From: Amos Jeffries Date: Thu, 13 Nov 2014 15:29:04 +0000 (-0800) Subject: Merge from trunk rev.13702 X-Git-Tag: merge-candidate-3-v1~240^2~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=204d529bd7a197e0e846daaeb07d88b9f6236054;p=thirdparty%2Fsquid.git Merge from trunk rev.13702 --- 204d529bd7a197e0e846daaeb07d88b9f6236054 diff --cc src/servers/HttpServer.cc index cf2d437666,a0d70aa3b1..75ffe722e6 --- a/src/servers/HttpServer.cc +++ b/src/servers/HttpServer.cc @@@ -127,6 -137,111 +137,111 @@@ Http::Server::parseOneRequest( return context; } + void clientProcessRequestFinished(ConnStateData *conn, const HttpRequest::Pointer &request); + + bool + Http::Server::buildHttpRequest(ClientSocketContext *context) + { + HttpRequest::Pointer request; + ClientHttpRequest *http = context->http; + if (context->flags.parsed_ok == 0) { + clientStreamNode *node = context->getClientReplyContext(); + debugs(33, 2, "Invalid Request"); + quitAfterError(NULL); + // setLogUri should called before repContext->setReplyToError + setLogUri(http, http->uri, true); + clientReplyContext *repContext = dynamic_cast(node->data.getRaw()); + assert(repContext); + + // determine which error page templates to use for specific parsing errors + err_type errPage = ERR_INVALID_REQ; - switch (parser_->request_parse_status) { ++ switch (parser_->parseStatusCode) { + case Http::scRequestHeaderFieldsTooLarge: + // fall through to next case + case Http::scUriTooLong: + errPage = ERR_TOO_BIG; + break; + case Http::scMethodNotAllowed: + errPage = ERR_UNSUP_REQ; + break; + case Http::scHttpVersionNotSupported: + errPage = ERR_UNSUP_HTTPVERSION; + break; + default: + // use default ERR_INVALID_REQ set above. + break; + } - repContext->setReplyToError(errPage, parser_->request_parse_status, parser_->method(), http->uri, ++ repContext->setReplyToError(errPage, parser_->parseStatusCode, parser_->method(), http->uri, + clientConnection->remote, NULL, in.buf.c_str(), NULL); + assert(context->http->out.offset == 0); + context->pullData(); + return false; + } + + if ((request = HttpRequest::CreateFromUrlAndMethod(http->uri, parser_->method())) == NULL) { + clientStreamNode *node = context->getClientReplyContext(); + debugs(33, 5, "Invalid URL: " << http->uri); + quitAfterError(request.getRaw()); + // setLogUri should called before repContext->setReplyToError + setLogUri(http, http->uri, true); + clientReplyContext *repContext = dynamic_cast(node->data.getRaw()); + assert(repContext); + repContext->setReplyToError(ERR_INVALID_URL, Http::scBadRequest, parser_->method(), http->uri, clientConnection->remote, NULL, NULL, NULL); + assert(context->http->out.offset == 0); + context->pullData(); + return false; + } + + /* RFC 2616 section 10.5.6 : handle unsupported HTTP major versions cleanly. */ + /* We currently only support 0.9, 1.0, 1.1 properly */ + /* TODO: move HTTP-specific processing into servers/HttpServer and such */ + if ( (parser_->messageProtocol().major == 0 && parser_->messageProtocol().minor != 9) || + (parser_->messageProtocol().major > 1) ) { + + clientStreamNode *node = context->getClientReplyContext(); + debugs(33, 5, "Unsupported HTTP version discovered. :\n" << parser_->messageProtocol()); + quitAfterError(request.getRaw()); + // setLogUri should called before repContext->setReplyToError + setLogUri(http, http->uri, true); + clientReplyContext *repContext = dynamic_cast(node->data.getRaw()); + assert (repContext); + repContext->setReplyToError(ERR_UNSUP_HTTPVERSION, Http::scHttpVersionNotSupported, parser_->method(), http->uri, + clientConnection->remote, NULL, NULL, NULL); + assert(context->http->out.offset == 0); + context->pullData(); + clientProcessRequestFinished(this, request); + return false; + } + + /* compile headers */ + if (parser_->messageProtocol().major >= 1 && !request->parseHeader(*parser_.getRaw())) { + clientStreamNode *node = context->getClientReplyContext(); + debugs(33, 5, "Failed to parse request headers:\n" << parser_->mimeHeader()); + quitAfterError(request.getRaw()); + // setLogUri should called before repContext->setReplyToError + setLogUri(http, http->uri, true); + clientReplyContext *repContext = dynamic_cast(node->data.getRaw()); + assert(repContext); + repContext->setReplyToError(ERR_INVALID_REQ, Http::scBadRequest, parser_->method(), http->uri, clientConnection->remote, NULL, NULL, NULL); + assert(context->http->out.offset == 0); + context->pullData(); + clientProcessRequestFinished(this, request); + return false; + } + + http->request = request.getRaw(); + HTTPMSGLOCK(http->request); + + return true; + } + + void + Http::Server::proceedAfterBodyContinuation(ClientSocketContext::Pointer context) + { + debugs(33, 5, "Body Continuation written"); + clientProcessRequest(this, parser_, context.getRaw()); + } + void Http::Server::processParsedRequest(ClientSocketContext *context) {