From 7dbbc6c892e209d9a89db5254e513166b70725b3 Mon Sep 17 00:00:00 2001 From: Thulinma Date: Mon, 31 Dec 2012 19:13:04 +0100 Subject: [PATCH] Implemented chunked transfer encoding support. --- lib/http_parser.cpp | 44 +++++++++++++++++++++++++++++++++++++++++++- lib/http_parser.h | 2 ++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/lib/http_parser.cpp b/lib/http_parser.cpp index 2f8ebb72..1dea052f 100644 --- a/lib/http_parser.cpp +++ b/lib/http_parser.cpp @@ -13,6 +13,8 @@ HTTP::Parser::Parser(){ void HTTP::Parser::Clean(){ seenHeaders = false; seenReq = false; + getChunks = false; + doingChunk = 0; method = "GET"; url = "/"; protocol = "HTTP/1.1"; @@ -200,6 +202,10 @@ bool HTTP::Parser::parse(std::string & HTTPbuffer){ body.reserve(length); } } + if (GetHeader("Transfer-Encoding") == "chunked"){ + getChunks = true; + doingChunk = 0; + } }else{ f = tmpA.find(':'); if (f == std::string::npos) continue; @@ -223,7 +229,43 @@ bool HTTP::Parser::parse(std::string & HTTPbuffer){ return false; } }else{ - return true; + if (getChunks){ + if (doingChunk){ + unsigned int toappend = HTTPbuffer.size(); + if (toappend > doingChunk){ + toappend = doingChunk; + } + body.append(HTTPbuffer, 0, toappend); + HTTPbuffer.erase(0, toappend); + doingChunk -= toappend; + }else{ + f = HTTPbuffer.find('\n'); + if (f == std::string::npos) return false; + tmpA = HTTPbuffer.substr(0, f); + while (tmpA.find('\r') != std::string::npos){ + tmpA.erase(tmpA.find('\r')); + } + unsigned int chunkLen = 0; + if ( !tmpA.empty()){ + for (int i = 0; i < tmpA.size(); ++i){ + chunkLen = (chunkLen << 4) | unhex(tmpA[i]); + } + if (chunkLen == 0){ + getChunks = false; + return true; + } + doingChunk = chunkLen; + } + if (f + 1 == HTTPbuffer.size()){ + HTTPbuffer.clear(); + }else{ + HTTPbuffer.erase(0, f + 1); + } + } + return false; + }else{ + return true; + } } } } diff --git a/lib/http_parser.h b/lib/http_parser.h index 77b12aed..300edf56 100644 --- a/lib/http_parser.h +++ b/lib/http_parser.h @@ -36,6 +36,8 @@ namespace HTTP { private: bool seenHeaders; bool seenReq; + bool getChunks; + unsigned int doingChunk; bool parse(std::string & HTTPbuffer); void parseVars(std::string data); std::string builder;