From 864c80601de17e0701c54c727f5d0584f7195229 Mon Sep 17 00:00:00 2001 From: Aki Tuomi Date: Mon, 30 Jun 2014 23:56:26 +0300 Subject: [PATCH] YaHTTP upstream update Fixes: - Chunked responses and requests are parsed properly even when the headers and body come in separately. --- pdns/ext/yahttp/yahttp/reqresp.cpp | 19 +++++++----- pdns/ext/yahttp/yahttp/reqresp.hpp | 15 ++++++---- pdns/ext/yahttp/yahttp/url.hpp | 48 +++++++++++++++--------------- 3 files changed, 44 insertions(+), 38 deletions(-) diff --git a/pdns/ext/yahttp/yahttp/reqresp.cpp b/pdns/ext/yahttp/yahttp/reqresp.cpp index d9d15ef096..9b94a2720a 100644 --- a/pdns/ext/yahttp/yahttp/reqresp.cpp +++ b/pdns/ext/yahttp/yahttp/reqresp.cpp @@ -96,25 +96,28 @@ namespace YaHTTP { if (buffer.size() == 0) return ready(); while(buffer.size() > 0) { - char buf[1024] = {0}; - if (chunked) { if (chunk_size == 0) { + char buf[100]; // read chunk length if ((pos = buffer.find('\n')) == std::string::npos) return false; - if (pos > 1023) + if (pos > 99) throw ParseError("Impossible chunk_size"); buffer.copy(buf, pos); buf[pos]=0; // just in case... buffer.erase(buffer.begin(), buffer.begin()+pos+1); // remove line from buffer sscanf(buf, "%x", &chunk_size); - if (!chunk_size) break; // last chunk + if (!chunk_size) { state = 3; break; } // last chunk } else { + int crlf=1; if (buffer.size() < static_cast(chunk_size+1)) return false; // expect newline - if (buffer.at(chunk_size) != '\n') return false; // there should be newline. - buffer.copy(buf, chunk_size); - buffer.erase(buffer.begin(), buffer.begin()+chunk_size+1); - bodybuf << buf; + if (buffer.at(chunk_size) == '\r') { + if (buffer.size() < static_cast(chunk_size+2) || buffer.at(chunk_size+1) != '\n') return false; // expect newline after carriage return + crlf=2; + } else if (buffer.at(chunk_size) != '\n') return false; + std::string tmp = buffer.substr(0, chunk_size); + buffer.erase(buffer.begin(), buffer.begin()+chunk_size+crlf); + bodybuf << tmp; chunk_size = 0; if (buffer.size() == 0) break; // just in case } diff --git a/pdns/ext/yahttp/yahttp/reqresp.hpp b/pdns/ext/yahttp/yahttp/reqresp.hpp index 3c31e63138..44be27a563 100644 --- a/pdns/ext/yahttp/yahttp/reqresp.hpp +++ b/pdns/ext/yahttp/yahttp/reqresp.hpp @@ -237,12 +237,15 @@ public: hasBody = false; }; // 1 && - (!hasBody || - (bodybuf.str().size() <= maxbody && - bodybuf.str().size() >= minbody) - ); - }; // 1 && + (!hasBody || + (bodybuf.str().size() <= maxbody && + bodybuf.str().size() >= minbody) + ) + ); + }; // YAHTTP_MAX_URL_LENGTH) return false; - size_t pos = 0; - if (*(url.begin()) != '/') { // full url? - if (parseSchema(url, pos) == false) return false; - if (pathless) { - parameters = url.substr(pos); - return true; - } - if (parseUserPass(url, pos) == false) return false; - if (parseHost(url, pos) == false) return false; + // setup + initialize(); + + if (url.size() > YAHTTP_MAX_URL_LENGTH) return false; + size_t pos = 0; + if (*(url.begin()) != '/') { // full url? + if (parseSchema(url, pos) == false) return false; + if (pathless) { + parameters = url.substr(pos); + return true; } - if (parsePath(url, pos) == false) return false; - if (parseParameters(url, pos) == false) return false; - return parseAnchor(url, pos); - }; /*! parse various formats of urls ranging from http://example.com/foo?bar=baz into data:base64:d089swt64wt... */ - - friend std::ostream & operator<<(std::ostream& os, const URL& url) { - os<