private HttpResponse processRequest() {
		try {

			// Read client Input and parse it.
			BufferedReader inFromClient = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			RequestParser requestParser = new RequestParser(this);
			parsedHttpRequest = requestParser.getParsedRequest(inFromClient);

			// Check if connection was terminated by client.
			if (isTerminatedByClient) {
				isKeepAlive = false;
				return null;
			}

			// Get request parameters and request as string.
			httpRequestParams = requestParser.getParametersMap();
			request = requestParser.getRequest();
			httpResponseMaker = new HttpResponseMaker(this);
			
			// Print request to console
			System.out.println(request);

			// Validate if parse is OK.
			if (parsedHttpRequest == null) {
				return httpResponseMaker.makeErrorPageResponse(HttpResponse.RESPONSE_400_BAD_REQUEST,
						"Your browser sent a request that this server did not understand");
			}

			/*
			 * Check if head request (this check is here because even if response would be an error response, we will
			 * return only the headers)
			 */
			isHeadRequest = (parsedHttpRequest.get(RequestParser.METHOD).equals(HTTP_METHOD_HEAD));

			// Validate location
			if (!isValidLocation(parsedHttpRequest.get(RequestParser.LOCATION))) {
				return httpResponseMaker.makeErrorPageResponse(HttpResponse.RESPONSE_400_BAD_REQUEST,
						"Your browser sent a request that this server did not understand");
			}

			// Validate HTTP Protocol
			else if (!isValidProtocol(parsedHttpRequest.get(RequestParser.PROTOCOL))) {
				return httpResponseMaker.makeErrorPageResponse(HttpResponse.RESPONSE_505_BAD_HTTP_VERSION,
						"Your browser sent a request with an HTTP version this server does not support");
			}

			// Validations for HTTP 1.1
			else if (parsedHttpRequest.get(RequestParser.PROTOCOL).equals(PROTOCOL_HTTP11) && !isValidHTTP11()) {
				return httpResponseMaker.makeErrorPageResponse(HttpResponse.RESPONSE_400_BAD_REQUEST,
						"Your browser sent a request that this server did not understand");
			}

			else {
				isKeepAlive = checkKeepalive();
				isChunked = checkChunked();
				return processHttpResponse();
			}

		} catch (SocketTimeoutException e) {
			return httpResponseMaker.makeErrorPageResponse(HttpResponse.RESPONSE_408_REQUEST_TIMEOUT,
					"The server timed out while waiting for the browser's request");
		} catch (Exception e) {
			e.printStackTrace();
			return httpResponseMaker.makeErrorPageResponse(HttpResponse.RESPONSE_500_INTERNAL_ERROR, "Internal Error");

		}
	}