From: Amos Jeffries Date: Sat, 28 Dec 2013 01:03:29 +0000 (-0800) Subject: Make HttpParser parse method directly into HttpRequestMethod object X-Git-Tag: merge-candidate-3-v1~506^2~79 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=274bd5ad905e73241293a6d662226a4686b74995;p=thirdparty%2Fsquid.git Make HttpParser parse method directly into HttpRequestMethod object There appears to be no need for the HTTP method object to be outside the parser. We can simplify the processing code by parsing directly into the object from the I/O buffer. TODO: * fix parsing of whitespace prefix in accordance with HTTPbis specs. * make parser incremental to end of method --- diff --git a/src/client_side.cc b/src/client_side.cc index c82f1fb9b5..a0052656a3 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -206,7 +206,7 @@ static IOACB httpsAccept; #endif static CTCB clientLifetimeTimeout; static ClientSocketContext *parseHttpRequestAbort(ConnStateData * conn, const char *uri); -static ClientSocketContext *parseHttpRequest(ConnStateData *, const Http::Http1ParserPointer &, HttpRequestMethod *); +static ClientSocketContext *parseHttpRequest(ConnStateData *, const Http::Http1ParserPointer &); #if USE_IDENT static IDCB clientIdentDone; #endif @@ -2212,7 +2212,7 @@ prepareTransparentURL(ConnStateData * conn, ClientHttpRequest *http, char *url, * a ClientSocketContext structure on success or failure. */ static ClientSocketContext * -parseHttpRequest(ConnStateData *csd, const Http::Http1ParserPointer &hp, HttpRequestMethod * method_p) +parseHttpRequest(ConnStateData *csd, const Http::Http1ParserPointer &hp) { char *req_hdr = NULL; char *end; @@ -2221,9 +2221,6 @@ parseHttpRequest(ConnStateData *csd, const Http::Http1ParserPointer &hp, HttpReq ClientSocketContext *result; StoreIOBuffer tempBuffer; - /* pre-set these values to make aborting simpler */ - *method_p = Http::METHOD_NONE; - /* NP: don't be tempted to move this down or remove again. * It's the only DDoS protection old-String has against long URL */ if ( hp->bufsiz <= 0) { @@ -2280,11 +2277,8 @@ parseHttpRequest(ConnStateData *csd, const Http::Http1ParserPointer &hp, HttpReq return parseHttpRequestAbort(csd, "error:request-too-large"); } - /* Set method_p */ - *method_p = HttpRequestMethod(&hp->buf[hp->req.m_start], &hp->buf[hp->req.m_end]+1); - /* deny CONNECT via accelerated ports */ - if (*method_p == Http::METHOD_CONNECT && csd->port && csd->port->flags.accelSurrogate) { + if (*(hp->method()) == Http::METHOD_CONNECT && csd->port && csd->port->flags.accelSurrogate) { debugs(33, DBG_IMPORTANT, "WARNING: CONNECT method received on " << csd->port->transport.protocol << " Accelerator port " << csd->port->s.port()); /* XXX need a way to say "this many character length string" */ debugs(33, DBG_IMPORTANT, "WARNING: for request: " << hp->buf); @@ -2292,7 +2286,7 @@ parseHttpRequest(ConnStateData *csd, const Http::Http1ParserPointer &hp, HttpReq return parseHttpRequestAbort(csd, "error:method-not-allowed"); } - if (*method_p == Http::METHOD_NONE) { + if (*(hp->method()) == Http::METHOD_NONE) { /* XXX need a way to say "this many character length string" */ debugs(33, DBG_IMPORTANT, "clientParseRequestMethod: Unsupported method in request '" << hp->buf << "'"); hp->request_parse_status = Http::scMethodNotAllowed; @@ -2638,7 +2632,7 @@ bool ConnStateData::serveDelayedError(ClientSocketContext *context) #endif // USE_SSL static void -clientProcessRequest(ConnStateData *conn, const Http::Http1ParserPointer &hp, ClientSocketContext *context, const HttpRequestMethod& method) +clientProcessRequest(ConnStateData *conn, const Http::Http1ParserPointer &hp, ClientSocketContext *context) { ClientHttpRequest *http = context->http; HttpRequest::Pointer request; @@ -2648,6 +2642,7 @@ clientProcessRequest(ConnStateData *conn, const Http::Http1ParserPointer &hp, Cl bool unsupportedTe = false; bool expectBody = false; const AnyP::ProtocolVersion &http_ver = hp->messageProtocol(); + const HttpRequestMethodPointer method = hp->method(); /* We have an initial client stream in place should it be needed */ /* setup our private context */ @@ -2663,14 +2658,14 @@ clientProcessRequest(ConnStateData *conn, const Http::Http1ParserPointer &hp, Cl assert (repContext); switch (hp->request_parse_status) { case Http::scHeaderTooLarge: - repContext->setReplyToError(ERR_TOO_BIG, Http::scBadRequest, method, http->uri, conn->clientConnection->remote, NULL, conn->in.buf, NULL); + repContext->setReplyToError(ERR_TOO_BIG, Http::scBadRequest, *method, http->uri, conn->clientConnection->remote, NULL, conn->in.buf, NULL); break; case Http::scMethodNotAllowed: - repContext->setReplyToError(ERR_UNSUP_REQ, Http::scMethodNotAllowed, method, http->uri, + repContext->setReplyToError(ERR_UNSUP_REQ, Http::scMethodNotAllowed, *method, http->uri, conn->clientConnection->remote, NULL, conn->in.buf, NULL); break; default: - repContext->setReplyToError(ERR_INVALID_REQ, hp->request_parse_status, method, http->uri, + repContext->setReplyToError(ERR_INVALID_REQ, hp->request_parse_status, *method, http->uri, conn->clientConnection->remote, NULL, conn->in.buf, NULL); } assert(context->http->out.offset == 0); @@ -2678,7 +2673,7 @@ clientProcessRequest(ConnStateData *conn, const Http::Http1ParserPointer &hp, Cl goto finish; } - if ((request = HttpRequest::CreateFromUrlAndMethod(http->uri, method)) == NULL) { + if ((request = HttpRequest::CreateFromUrlAndMethod(http->uri, *method)) == NULL) { clientStreamNode *node = context->getClientReplyContext(); debugs(33, 5, "Invalid URL: " << http->uri); conn->quitAfterError(request.getRaw()); @@ -2686,7 +2681,7 @@ clientProcessRequest(ConnStateData *conn, const Http::Http1ParserPointer &hp, Cl setLogUri(http, http->uri, true); clientReplyContext *repContext = dynamic_cast(node->data.getRaw()); assert (repContext); - repContext->setReplyToError(ERR_INVALID_URL, Http::scBadRequest, method, http->uri, conn->clientConnection->remote, NULL, NULL, NULL); + repContext->setReplyToError(ERR_INVALID_URL, Http::scBadRequest, *method, http->uri, conn->clientConnection->remote, NULL, NULL, NULL); assert(context->http->out.offset == 0); context->pullData(); goto finish; @@ -2704,7 +2699,7 @@ clientProcessRequest(ConnStateData *conn, const Http::Http1ParserPointer &hp, Cl setLogUri(http, http->uri, true); clientReplyContext *repContext = dynamic_cast(node->data.getRaw()); assert (repContext); - repContext->setReplyToError(ERR_UNSUP_HTTPVERSION, Http::scHttpVersionNotSupported, method, http->uri, + repContext->setReplyToError(ERR_UNSUP_HTTPVERSION, Http::scHttpVersionNotSupported, *method, http->uri, conn->clientConnection->remote, NULL, hp->rawHeaderBuf(), NULL); assert(context->http->out.offset == 0); context->pullData(); @@ -2722,7 +2717,7 @@ clientProcessRequest(ConnStateData *conn, const Http::Http1ParserPointer &hp, Cl setLogUri(http, http->uri, true); clientReplyContext *repContext = dynamic_cast(node->data.getRaw()); assert (repContext); - repContext->setReplyToError(ERR_INVALID_REQ, Http::scBadRequest, method, http->uri, conn->clientConnection->remote, NULL, NULL, NULL); + repContext->setReplyToError(ERR_INVALID_REQ, Http::scBadRequest, *method, http->uri, conn->clientConnection->remote, NULL, NULL, NULL); assert(context->http->out.offset == 0); context->pullData(); goto finish; @@ -2805,7 +2800,7 @@ clientProcessRequest(ConnStateData *conn, const Http::Http1ParserPointer &hp, Cl unsupportedTe = te.size() && te != "identity"; } // else implied identity coding - mustReplyToOptions = (method == Http::METHOD_OPTIONS) && + mustReplyToOptions = (*method == Http::METHOD_OPTIONS) && (request->header.getInt64(HDR_MAX_FORWARDS) == 0); if (!urlCheckRequest(request.getRaw()) || mustReplyToOptions || unsupportedTe) { clientStreamNode *node = context->getClientReplyContext(); @@ -2963,7 +2958,6 @@ ConnStateData::concurrentRequestQueueFilled() const bool ConnStateData::clientParseRequests() { - HttpRequestMethod method; bool parsed_req = false; debugs(33, 5, HERE << clientConnection << ": attempting to parse"); @@ -2997,7 +2991,7 @@ ConnStateData::clientParseRequests() parser_->bufsiz = in.notYetUsed; /* Process request */ - ClientSocketContext *context = parseHttpRequest(this, parser_, &method); + ClientSocketContext *context = parseHttpRequest(this, parser_); PROF_stop(parseHttpRequest); /* partial or incomplete request */ @@ -3015,7 +3009,7 @@ ConnStateData::clientParseRequests() CommTimeoutCbPtrFun(clientLifetimeTimeout, context->http)); commSetConnTimeout(clientConnection, Config.Timeout.lifetime, timeoutCall); - clientProcessRequest(this, parser_, context, method); + clientProcessRequest(this, parser_, context); parsed_req = true; // XXX: do we really need to parse everything right NOW ? diff --git a/src/http/Http1Parser.cc b/src/http/Http1Parser.cc index f153413172..8b535c0212 100644 --- a/src/http/Http1Parser.cc +++ b/src/http/Http1Parser.cc @@ -1,6 +1,7 @@ #include "squid.h" #include "Debug.h" #include "http/Http1Parser.h" +#include "http/RequestMethod.h" #include "profiler/Profiler.h" #include "SquidConfig.h" @@ -18,6 +19,7 @@ Http::Http1Parser::clear() req.u_start = req.u_end = -1; req.v_start = req.v_end = -1; msgProtocol_ = AnyP::ProtocolVersion(); + method_ = NULL; } void @@ -137,6 +139,9 @@ Http::Http1Parser::parseRequestFirstLine() return -1; } + /* Set method_ */ + method_ = new HttpRequestMethod(&buf[req.m_start], &buf[req.m_end]+1); + // First non-whitespace after first SP = beginning of URL+Version if (second_word > line_end || second_word < req.start) { request_parse_status = Http::scBadRequest; // missing URI diff --git a/src/http/Http1Parser.h b/src/http/Http1Parser.h index 45dc22233b..0be9b09b33 100644 --- a/src/http/Http1Parser.h +++ b/src/http/Http1Parser.h @@ -2,6 +2,7 @@ #define _SQUID_SRC_HTTP_HTTP1PARSER_H #include "base/RefCount.h" +#include "http/forward.h" #include "http/ProtocolVersion.h" #include "http/StatusCode.h" @@ -104,6 +105,9 @@ public: /// the protocol label for this message const AnyP::ProtocolVersion & messageProtocol() const {return msgProtocol_;} + /// the HTTP method if this is a request method + const HttpRequestMethodPointer & method() const {return method_;} + // Offsets for pieces of the MiME Header segment int hdr_start, hdr_end; @@ -123,6 +127,9 @@ private: /// what protocol label has been found in the first line AnyP::ProtocolVersion msgProtocol_; + + /// what request method has been found on the first line + HttpRequestMethodPointer method_; }; } // namespace Http diff --git a/src/http/RequestMethod.h b/src/http/RequestMethod.h index 1bb5f00042..40bb82433c 100644 --- a/src/http/RequestMethod.h +++ b/src/http/RequestMethod.h @@ -13,7 +13,7 @@ * It has a runtime extension facility to allow it to * efficiently support new methods */ -class HttpRequestMethod +class HttpRequestMethod : public RefCountable { public: HttpRequestMethod() : theMethod(Http::METHOD_NONE), theImage() {} diff --git a/src/tests/testHttp1Parser.cc b/src/tests/testHttp1Parser.cc index 8079e21fdc..50281f4cae 100644 --- a/src/tests/testHttp1Parser.cc +++ b/src/tests/testHttp1Parser.cc @@ -8,6 +8,7 @@ #include "testHttp1Parser.h" #include "http/Http1Parser.h" +#include "http/RequestMethod.h" #include "Mem.h" #include "MemBuf.h" #include "SquidConfig.h" @@ -52,6 +53,7 @@ testHttp1Parser::testParseRequestLineProtocols() CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(2, output.req.m_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("GET", &output.buf[output.req.m_start], (output.req.m_end-output.req.m_start+1))); + CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(Http::METHOD_GET), *output.method_); CPPUNIT_ASSERT_EQUAL(4, output.req.u_start); CPPUNIT_ASSERT_EQUAL(4, output.req.u_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("/", &output.buf[output.req.u_start], (output.req.u_end-output.req.u_start+1))); @@ -71,16 +73,17 @@ testHttp1Parser::testParseRequestLineProtocols() CPPUNIT_ASSERT_EQUAL(Http::scOkay, output.request_parse_status); CPPUNIT_ASSERT_EQUAL(0, output.req.start); CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req.end); - CPPUNIT_ASSERT_EQUAL(0,memcmp("GET /\r\n", &output.buf[output.req.start],(output.req.end-output.req.start+1))); + CPPUNIT_ASSERT_EQUAL(0,memcmp("POST /\r\n", &output.buf[output.req.start],(output.req.end-output.req.start+1))); CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); - CPPUNIT_ASSERT_EQUAL(2, output.req.m_end); - CPPUNIT_ASSERT_EQUAL(0, memcmp("GET", &output.buf[output.req.m_start], (output.req.m_end-output.req.m_start+1))); - CPPUNIT_ASSERT_EQUAL(4, output.req.u_start); - CPPUNIT_ASSERT_EQUAL(4, output.req.u_end); + CPPUNIT_ASSERT_EQUAL(3, output.req.m_end); + CPPUNIT_ASSERT_EQUAL(0, memcmp("POST", &output.buf[output.req.m_start], (output.req.m_end-output.req.m_start+1))); + CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(Http::METHOD_POST), *output.method_); + CPPUNIT_ASSERT_EQUAL(5, output.req.u_start); + CPPUNIT_ASSERT_EQUAL(5, output.req.u_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("/", &output.buf[output.req.u_start], (output.req.u_end-output.req.u_start+1))); CPPUNIT_ASSERT_EQUAL(-1, output.req.v_start); CPPUNIT_ASSERT_EQUAL(-1, output.req.v_end); - CPPUNIT_ASSERT_EQUAL(AnyP::ProtocolVersion(AnyP::PROTO_HTTP,0,9), output.msgProtocol_); + CPPUNIT_ASSERT_EQUAL(AnyP::ProtocolVersion(), output.msgProtocol_); input.reset(); } #endif @@ -98,6 +101,7 @@ testHttp1Parser::testParseRequestLineProtocols() CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(2, output.req.m_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("GET", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1))); + CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(Http::METHOD_GET), *output.method_); CPPUNIT_ASSERT_EQUAL(4, output.req.u_start); CPPUNIT_ASSERT_EQUAL(4, output.req.u_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("/", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1))); @@ -121,6 +125,7 @@ testHttp1Parser::testParseRequestLineProtocols() CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(2, output.req.m_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("GET", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1))); + CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(Http::METHOD_GET), *output.method_); CPPUNIT_ASSERT_EQUAL(4, output.req.u_start); CPPUNIT_ASSERT_EQUAL(4, output.req.u_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("/", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1))); @@ -144,6 +149,7 @@ testHttp1Parser::testParseRequestLineProtocols() CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(2, output.req.m_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("GET", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1))); + CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(Http::METHOD_GET), *output.method_); CPPUNIT_ASSERT_EQUAL(4, output.req.u_start); CPPUNIT_ASSERT_EQUAL(4, output.req.u_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("/", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1))); @@ -169,6 +175,7 @@ testHttp1Parser::testParseRequestLineProtocols() CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(2, output.req.m_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("GET", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1))); + CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(Http::METHOD_GET), *output.method_); CPPUNIT_ASSERT_EQUAL(4, output.req.u_start); CPPUNIT_ASSERT_EQUAL(4, output.req.u_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("/", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1))); @@ -206,6 +213,7 @@ testHttp1Parser::testParseRequestLineProtocols() CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(2, output.req.m_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("GET", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1))); + CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(Http::METHOD_GET), *output.method_); CPPUNIT_ASSERT_EQUAL(4, output.req.u_start); CPPUNIT_ASSERT_EQUAL(6, output.req.v_start); CPPUNIT_ASSERT_EQUAL(12, output.req.v_end); @@ -227,6 +235,7 @@ testHttp1Parser::testParseRequestLineProtocols() CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(2, output.req.m_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("GET", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1))); + CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(Http::METHOD_GET), *output.method_); CPPUNIT_ASSERT_EQUAL(4, output.req.u_start); CPPUNIT_ASSERT_EQUAL(4, output.req.u_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("/", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1))); @@ -251,6 +260,7 @@ testHttp1Parser::testParseRequestLineProtocols() CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(2, output.req.m_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("GET", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1))); + CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(Http::METHOD_GET), *output.method_); CPPUNIT_ASSERT_EQUAL(4, output.req.u_start); CPPUNIT_ASSERT_EQUAL(4, output.req.u_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("/", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1))); @@ -275,6 +285,7 @@ testHttp1Parser::testParseRequestLineProtocols() CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(2, output.req.m_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("GET", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1))); + CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(Http::METHOD_GET), *output.method_); CPPUNIT_ASSERT_EQUAL(4, output.req.u_start); CPPUNIT_ASSERT_EQUAL(4, output.req.u_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("/", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1))); @@ -299,6 +310,7 @@ testHttp1Parser::testParseRequestLineProtocols() CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(2, output.req.m_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("GET", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1))); + CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(Http::METHOD_GET), *output.method_); CPPUNIT_ASSERT_EQUAL(4, output.req.u_start); CPPUNIT_ASSERT_EQUAL(4, output.req.u_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("/", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1))); @@ -323,6 +335,7 @@ testHttp1Parser::testParseRequestLineProtocols() CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(2, output.req.m_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("GET", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1))); + CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(Http::METHOD_GET), *output.method_); CPPUNIT_ASSERT_EQUAL(4, output.req.u_start); CPPUNIT_ASSERT_EQUAL(4, output.req.u_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("/", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1))); @@ -347,6 +360,7 @@ testHttp1Parser::testParseRequestLineProtocols() CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(2, output.req.m_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("GET", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1))); + CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(Http::METHOD_GET), *output.method_); CPPUNIT_ASSERT_EQUAL(4, output.req.u_start); CPPUNIT_ASSERT_EQUAL(4, output.req.u_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("/", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1))); @@ -382,6 +396,7 @@ testHttp1Parser::testParseRequestLineStrange() CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(2, output.req.m_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("GET", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1))); + CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(Http::METHOD_GET), *output.method_); CPPUNIT_ASSERT_EQUAL(5, output.req.u_start); CPPUNIT_ASSERT_EQUAL(5, output.req.u_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("/", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1))); @@ -406,6 +421,7 @@ testHttp1Parser::testParseRequestLineStrange() CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(2, output.req.m_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("GET", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1))); + CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(Http::METHOD_GET), *output.method_); CPPUNIT_ASSERT_EQUAL(4, output.req.u_start); CPPUNIT_ASSERT_EQUAL(9, output.req.u_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("/fo o/", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1))); @@ -430,6 +446,7 @@ testHttp1Parser::testParseRequestLineStrange() CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(2, output.req.m_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("GET", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1))); + CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(Http::METHOD_GET), *output.method_); CPPUNIT_ASSERT_EQUAL(4, output.req.u_start); CPPUNIT_ASSERT_EQUAL(4, output.req.u_end); // strangeness generated by following RFC CPPUNIT_ASSERT_EQUAL(0, memcmp("/", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1))); @@ -465,6 +482,7 @@ testHttp1Parser::testParseRequestLineTerminators() CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(2, output.req.m_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("GET", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1))); + CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(Http::METHOD_GET), *output.method_); CPPUNIT_ASSERT_EQUAL(4, output.req.u_start); CPPUNIT_ASSERT_EQUAL(4, output.req.u_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("/", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1))); @@ -489,6 +507,7 @@ testHttp1Parser::testParseRequestLineTerminators() CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(2, output.req.m_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("GET", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1))); + CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(Http::METHOD_GET), *output.method_); CPPUNIT_ASSERT_EQUAL(4, output.req.u_start); CPPUNIT_ASSERT_EQUAL(4, output.req.u_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("/", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1))); @@ -515,6 +534,7 @@ testHttp1Parser::testParseRequestLineTerminators() CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(2, output.req.m_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("GET", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1))); + CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(Http::METHOD_GET), *output.method_); CPPUNIT_ASSERT_EQUAL(4, output.req.u_start); CPPUNIT_ASSERT_EQUAL(4, output.req.u_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("/", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1))); @@ -563,6 +583,7 @@ testHttp1Parser::testParseRequestLineTerminators() CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(2, output.req.m_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("GET", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1))); + CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(Http::METHOD_GET), *output.method_); CPPUNIT_ASSERT_EQUAL(4, output.req.u_start); CPPUNIT_ASSERT_EQUAL(13, output.req.u_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("/ HTTP/1.1", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1))); @@ -584,6 +605,7 @@ testHttp1Parser::testParseRequestLineTerminators() CPPUNIT_ASSERT_EQUAL(-1, output.req.end); CPPUNIT_ASSERT_EQUAL(-1, output.req.m_start); CPPUNIT_ASSERT_EQUAL(-1, output.req.m_end); + CPPUNIT_ASSERT(!output.method_); CPPUNIT_ASSERT_EQUAL(-1, output.req.u_start); CPPUNIT_ASSERT_EQUAL(-1, output.req.u_end); CPPUNIT_ASSERT_EQUAL(-1, output.req.v_start); @@ -601,6 +623,7 @@ testHttp1Parser::testParseRequestLineTerminators() CPPUNIT_ASSERT_EQUAL(-1, output.req.end); CPPUNIT_ASSERT_EQUAL(-1, output.req.m_start); CPPUNIT_ASSERT_EQUAL(-1, output.req.m_end); + CPPUNIT_ASSERT(!output.method_); CPPUNIT_ASSERT_EQUAL(-1, output.req.u_start); CPPUNIT_ASSERT_EQUAL(-1, output.req.u_end); CPPUNIT_ASSERT_EQUAL(-1, output.req.v_start); @@ -618,6 +641,7 @@ testHttp1Parser::testParseRequestLineTerminators() CPPUNIT_ASSERT_EQUAL(-1, output.req.end); CPPUNIT_ASSERT_EQUAL(-1, output.req.m_start); CPPUNIT_ASSERT_EQUAL(-1, output.req.m_end); + CPPUNIT_ASSERT(!output.method_); CPPUNIT_ASSERT_EQUAL(-1, output.req.u_start); CPPUNIT_ASSERT_EQUAL(-1, output.req.u_end); CPPUNIT_ASSERT_EQUAL(-1, output.req.v_start); @@ -635,6 +659,7 @@ testHttp1Parser::testParseRequestLineTerminators() CPPUNIT_ASSERT_EQUAL(-1, output.req.end); CPPUNIT_ASSERT_EQUAL(-1, output.req.m_start); CPPUNIT_ASSERT_EQUAL(-1, output.req.m_end); + CPPUNIT_ASSERT(!output.method_); CPPUNIT_ASSERT_EQUAL(-1, output.req.u_start); CPPUNIT_ASSERT_EQUAL(-1, output.req.u_end); CPPUNIT_ASSERT_EQUAL(-1, output.req.v_start); @@ -668,6 +693,7 @@ testHttp1Parser::testParseRequestLineMethods() CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(0, output.req.m_end); CPPUNIT_ASSERT_EQUAL(0, memcmp(".", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1))); + CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(".", NULL), *output.method_); CPPUNIT_ASSERT_EQUAL(2, output.req.u_start); CPPUNIT_ASSERT_EQUAL(2, output.req.u_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("/", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1))); @@ -692,6 +718,7 @@ testHttp1Parser::testParseRequestLineMethods() CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(6, output.req.m_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("OPTIONS", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1))); + CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(Http::METHOD_OPTIONS), *output.method_); CPPUNIT_ASSERT_EQUAL(8, output.req.u_start); CPPUNIT_ASSERT_EQUAL(8, output.req.u_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("*", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1))); @@ -716,6 +743,7 @@ testHttp1Parser::testParseRequestLineMethods() CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(9, output.req.m_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("HELLOWORLD", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1))); + CPPUNIT_ASSERT_EQUAL(HttpRequestMethod("HELLOWORLD",NULL), *output.method_); CPPUNIT_ASSERT_EQUAL(11, output.req.u_start); CPPUNIT_ASSERT_EQUAL(11, output.req.u_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("/", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1))); @@ -739,6 +767,7 @@ testHttp1Parser::testParseRequestLineMethods() CPPUNIT_ASSERT_EQUAL(0, memcmp("A\n", &output.buf[output.req.start],(output.req.end-output.req.start+1))); CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(-1, output.req.m_end); + CPPUNIT_ASSERT(!output.method_); CPPUNIT_ASSERT_EQUAL(-1, output.req.u_start); CPPUNIT_ASSERT_EQUAL(-1, output.req.u_end); CPPUNIT_ASSERT_EQUAL(-1, output.req.v_start); @@ -759,6 +788,7 @@ testHttp1Parser::testParseRequestLineMethods() CPPUNIT_ASSERT_EQUAL(0, memcmp("GET\n", &output.buf[output.req.start],(output.req.end-output.req.start+1))); CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(-1, output.req.m_end); + CPPUNIT_ASSERT(!output.method_); CPPUNIT_ASSERT_EQUAL(-1, output.req.u_start); CPPUNIT_ASSERT_EQUAL(-1, output.req.u_end); CPPUNIT_ASSERT_EQUAL(-1, output.req.v_start); @@ -782,6 +812,7 @@ testHttp1Parser::testParseRequestLineMethods() CPPUNIT_ASSERT_EQUAL(1, output.req.m_start); CPPUNIT_ASSERT_EQUAL(3, output.req.m_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("GET", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1))); + CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(Http::METHOD_GET), *output.method_); CPPUNIT_ASSERT_EQUAL(5, output.req.u_start); CPPUNIT_ASSERT_EQUAL(5, output.req.u_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("/", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1))); @@ -806,12 +837,14 @@ testHttp1Parser::testParseRequestLineMethods() CPPUNIT_ASSERT_EQUAL(0, memcmp(" GET / HTTP/1.1\n", &output.buf[output.req.start],(output.req.end-output.req.start+1))); CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(-1, output.req.m_end); + CPPUNIT_ASSERT(!output.method_); CPPUNIT_ASSERT_EQUAL(-1, output.req.u_start); CPPUNIT_ASSERT_EQUAL(-1, output.req.u_end); CPPUNIT_ASSERT_EQUAL(-1, output.req.v_start); CPPUNIT_ASSERT_EQUAL(-1, output.req.v_end); CPPUNIT_ASSERT_EQUAL(AnyP::ProtocolVersion(AnyP::PROTO_NONE,0,0), output.msgProtocol_); input.reset(); + Config.onoff.relaxed_header_parser = 1; } // tab padded method (NP: tab is not SP so treated as any other binary) @@ -828,6 +861,7 @@ testHttp1Parser::testParseRequestLineMethods() CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(3, output.req.m_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("\tGET", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1))); + CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(&output.buf[output.req.m_start],&output.buf[output.req.m_end+1]), *output.method_); CPPUNIT_ASSERT_EQUAL(5, output.req.u_start); CPPUNIT_ASSERT_EQUAL(5, output.req.u_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("/", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1))); @@ -864,6 +898,7 @@ testHttp1Parser::testParseRequestLineInvalid() CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(0, output.req.m_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("/", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1))); + CPPUNIT_ASSERT_EQUAL(HttpRequestMethod("/",NULL), *output.method_); CPPUNIT_ASSERT_EQUAL(2, output.req.u_start); CPPUNIT_ASSERT_EQUAL(9, output.req.u_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("HTTP/1.0", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1))); @@ -889,6 +924,7 @@ testHttp1Parser::testParseRequestLineInvalid() CPPUNIT_ASSERT_EQUAL(1, output.req.m_start); CPPUNIT_ASSERT_EQUAL(1, output.req.m_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("/", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1))); + CPPUNIT_ASSERT_EQUAL(HttpRequestMethod("/",NULL), *output.method_); CPPUNIT_ASSERT_EQUAL(3, output.req.u_start); CPPUNIT_ASSERT_EQUAL(10, output.req.u_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("HTTP/1.0", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1))); @@ -913,6 +949,7 @@ testHttp1Parser::testParseRequestLineInvalid() CPPUNIT_ASSERT_EQUAL(0, memcmp(" / HTTP/1.0\n", &output.buf[output.req.start],(output.req.end-output.req.start+1))); CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(-1, output.req.m_end); + CPPUNIT_ASSERT(!output.method_); CPPUNIT_ASSERT_EQUAL(-1, output.req.u_start); CPPUNIT_ASSERT_EQUAL(-1, output.req.u_end); CPPUNIT_ASSERT_EQUAL(-1, output.req.v_start); @@ -935,6 +972,7 @@ testHttp1Parser::testParseRequestLineInvalid() CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(3, output.req.m_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("GET\x0B", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1))); +// CPPUNIT_ASSERT_EQUAL(HttpRequestMethod("GET\0x0B",NULL), *output.method_); CPPUNIT_ASSERT_EQUAL(5, output.req.u_start); CPPUNIT_ASSERT_EQUAL(5, output.req.u_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("/", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1))); @@ -958,6 +996,7 @@ testHttp1Parser::testParseRequestLineInvalid() CPPUNIT_ASSERT_EQUAL(-1, output.req.end); CPPUNIT_ASSERT_EQUAL(-1, output.req.m_start); CPPUNIT_ASSERT_EQUAL(-1, output.req.m_end); + CPPUNIT_ASSERT(!output.method_); CPPUNIT_ASSERT_EQUAL(-1, output.req.u_start); CPPUNIT_ASSERT_EQUAL(-1, output.req.u_end); CPPUNIT_ASSERT_EQUAL(-1, output.req.v_start); @@ -980,6 +1019,7 @@ testHttp1Parser::testParseRequestLineInvalid() CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(3, output.req.m_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("GET\0", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1))); +// CPPUNIT_ASSERT_EQUAL(HttpRequestMethod("GET\0",NULL), *output.method_); CPPUNIT_ASSERT_EQUAL(5, output.req.u_start); CPPUNIT_ASSERT_EQUAL(5, output.req.u_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("/", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1))); @@ -1004,6 +1044,7 @@ testHttp1Parser::testParseRequestLineInvalid() CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(2, output.req.m_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("GET", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1))); + CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(Http::METHOD_GET), *output.method_); CPPUNIT_ASSERT_EQUAL(5, output.req.u_start); CPPUNIT_ASSERT_EQUAL(12, output.req.u_end); CPPUNIT_ASSERT_EQUAL(-1, output.req.v_start); @@ -1027,6 +1068,7 @@ testHttp1Parser::testParseRequestLineInvalid() CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(2, output.req.m_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("GET", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1))); + CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(Http::METHOD_GET), *output.method_); CPPUNIT_ASSERT_EQUAL(4, output.req.u_start); CPPUNIT_ASSERT_EQUAL(11, output.req.u_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("HTTP/1.1", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1))); @@ -1049,6 +1091,7 @@ testHttp1Parser::testParseRequestLineInvalid() CPPUNIT_ASSERT_EQUAL(0, memcmp("\xB\xC\xE\xF\n", &output.buf[output.req.start],(output.req.end-output.req.start+1))); CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(-1, output.req.m_end); + CPPUNIT_ASSERT(!output.method_); CPPUNIT_ASSERT_EQUAL(-1, output.req.u_start); CPPUNIT_ASSERT_EQUAL(-1, output.req.u_end); CPPUNIT_ASSERT_EQUAL(-1, output.req.v_start); @@ -1073,6 +1116,7 @@ testHttp1Parser::testParseRequestLineInvalid() CPPUNIT_ASSERT_EQUAL(0, output.req.m_start); CPPUNIT_ASSERT_EQUAL(0, output.req.m_end); CPPUNIT_ASSERT_EQUAL(0, memcmp("\t", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1))); + CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(&output.buf[output.req.m_start],&output.buf[output.req.m_end+1]), *output.method_); CPPUNIT_ASSERT_EQUAL(-1, output.req.u_start); CPPUNIT_ASSERT_EQUAL(-1, output.req.u_end); CPPUNIT_ASSERT_EQUAL(-1, output.req.v_start); @@ -1095,6 +1139,7 @@ testHttp1Parser::testParseRequestLineInvalid() CPPUNIT_ASSERT_EQUAL(-1, output.req.end); CPPUNIT_ASSERT_EQUAL(-1, output.req.m_start); CPPUNIT_ASSERT_EQUAL(-1, output.req.m_end); + CPPUNIT_ASSERT(!output.method_); CPPUNIT_ASSERT_EQUAL(-1, output.req.u_start); CPPUNIT_ASSERT_EQUAL(-1, output.req.u_end); CPPUNIT_ASSERT_EQUAL(-1, output.req.v_start);