diff --git a/code/Message.cpp b/code/Message.cpp index 3eed4b0..74367df 100644 --- a/code/Message.cpp +++ b/code/Message.cpp @@ -14,6 +14,8 @@ #include #include +#include + namespace { struct Clear { @@ -146,24 +148,39 @@ namespace http { std::size_t Message::feed ( const char * data, ::size_t size ) { - const std::size_t pass = - ::http_parser_execute(&myParser, &mySettings, data, size); - if (pass != size) + std::size_t used = ::http_parser_execute + (&myParser, &mySettings, data, size); + + const ::http_errno error = + static_cast< ::http_errno >(myParser.http_errno); + + // The 'on_message_complete' and 'on_headers_complete' callbacks fail + // on purpose to force the parser to stop between pipelined requests. + // This allows the clients to reliably detect the end of headers and + // the end of the message. Make sure the parser is always unpaused + // for the next call to 'feed'. + if (error == HPE_PAUSED) { + ::http_parser_pause(&myParser, 0); + } + + if (used < size) { - const ::http_errno error = - static_cast< ::http_errno >(myParser.http_errno); - - // The 'on_message_complete' callback fails on purpose. - // It forces the parser to stop between pipelined - // requests so clients can test the '.complete()' flag. - if (error == HPE_PAUSED) { - ::http_parser_pause(&myParser, 0); - return (pass); + if (error == HPE_PAUSED) + { + // Make sure the byte that triggered the pause + // after the headers is properly processed. + if (!myComplete) + { + used += ::http_parser_execute + (&myParser, &mySettings, data+used, 1); + } + } + else { + throw (Error(error)); } - - throw (Error(error)); } - return (pass); + + return (used); } bool Message::complete () const diff --git a/test/data/request-002.txt b/test/data/request-002.txt new file mode 100644 index 0000000..ab0a190 --- /dev/null +++ b/test/data/request-002.txt @@ -0,0 +1,5 @@ +POST /index.html HTTP/1.1 +Host: www.example.com +Content-Length: 13 + +Hello, world! \ No newline at end of file diff --git a/test/http-extract-request-header.cpp b/test/http-extract-request-header.cpp index 13a844a..4231efd 100644 --- a/test/http-extract-request-header.cpp +++ b/test/http-extract-request-header.cpp @@ -17,14 +17,35 @@ namespace { // Parse HTTP request. http::Request request; char data[1024]; + std::size_t head = 0; + std::size_t body = 0; do { stream.read(data, sizeof(data)); std::size_t size = stream.gcount(); std::size_t used = 0; - std::size_t pass = 0; - while ((used < size) && !request.complete()) { - used += request.feed(data+used, size-used); + while ((used < size) && !request.headers_complete()) + { + const std::size_t pass = request.feed(data+used, size-used); + used += pass, head += pass; + if (request.headers_complete()) + { + std::cerr + << "Head size: " << head << "." + << std::endl; + } } + while ((used < size) && !request.complete()) + { + const std::size_t pass = request.feed(data+used, size-used); + used += pass, body += pass; + if (request.complete()) + { + std::cerr + << "Body size: " << body << "." + << std::endl; + } + } + head += used; } while ((stream.gcount() > 0) && !request.complete());