From: Mark Slee Date: Tue, 27 Feb 2007 19:03:01 +0000 (+0000) Subject: Various bug fixes with the THttpClient X-Git-Tag: 0.2.0~1448 X-Git-Url: https://source.supwisdom.com/gerrit/gitweb?a=commitdiff_plain;h=4401814d3a4ea2ef02215073d74e9ec4b946afab;p=common%2Fthrift.git Various bug fixes with the THttpClient Summary: All kinds of buffer madness, what a pain. Reviewed By: http git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665024 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/lib/cpp/src/transport/THttpClient.cpp b/lib/cpp/src/transport/THttpClient.cpp index 3e611ffc..b3896946 100644 --- a/lib/cpp/src/transport/THttpClient.cpp +++ b/lib/cpp/src/transport/THttpClient.cpp @@ -48,6 +48,7 @@ void THttpClient::init() { if (httpBuf_ == NULL) { throw TTransportException("Out of memory."); } + httpBuf_[httpBufPos_] = '\0'; } THttpClient::~THttpClient() { @@ -79,7 +80,7 @@ uint32_t THttpClient::readMoreData() { return readChunked(); } else { char* read; - read = readContent((char*)httpBuf_, contentLength_); + read = readContent(httpBuf_, contentLength_); shift(read); return contentLength_; } @@ -87,10 +88,9 @@ uint32_t THttpClient::readMoreData() { uint32_t THttpClient::readChunked() { uint32_t length = 0; - char* nextLine = (char*)httpBuf_; + char* nextLine = httpBuf_; while (true) { - char* line = nextLine; - nextLine = readLine(nextLine); + char* line = readLine(nextLine, &nextLine); uint32_t chunkSize = parseChunkSize(line); if (chunkSize == 0) { break; @@ -100,13 +100,12 @@ uint32_t THttpClient::readChunked() { length += chunkSize; // Read trailing CRLF after content - nextLine = readLine(nextLine); + readLine(nextLine, &nextLine); } // Read footer lines until a blank one appears while (true) { - char* line = nextLine; - nextLine = readLine(nextLine); + char* line = readLine(nextLine, &nextLine); if (strlen(line) == 0) { break; } @@ -123,9 +122,8 @@ uint32_t THttpClient::parseChunkSize(char* line) { if (semi != NULL) { *semi = '\0'; } - int s; - int size; - s = sscanf(line, "%x", &size); + int size = 0; + sscanf(line, "%x", &size); return (uint32_t)size; } @@ -135,7 +133,12 @@ char* THttpClient::readContent(char* pos, uint32_t size) { while (need > 0) { uint32_t avail = httpBufPos_ - (pos - httpBuf_); if (avail == 0) { - refill(); + // We have given all the data, reset position to head of the buffer + pos = shift(pos); + pos = refill(); + + // Now have available however much we read + avail = httpBufPos_; } uint32_t give = avail; if (need < give) { @@ -147,8 +150,8 @@ char* THttpClient::readContent(char* pos, uint32_t size) { } return pos; } - -char* THttpClient::readLine(char* pos) { + +char* THttpClient::readLine(char* pos, char** next) { while (true) { char* eol = NULL; @@ -159,14 +162,14 @@ char* THttpClient::readLine(char* pos) { // No CRLF yet? if (eol == NULL) { - // Shift whatever we have now to front + // Shift whatever we have now to front and refill pos = shift(pos); - // Refill the buffer - refill(); + pos = refill(); } else { // Return pointer to next line *eol = '\0'; - return eol + CRLF_LEN; + *next = eol + CRLF_LEN; + return pos; } } @@ -185,11 +188,11 @@ char* THttpClient::shift(char* pos) { return httpBuf_; } -void THttpClient::refill() { +char* THttpClient::refill() { uint32_t avail = httpBufSize_ - httpBufPos_; if (avail <= (httpBufSize_ / 4)) { httpBufSize_ *= 2; - httpBuf_ = (char*)realloc(httpBuf_, httpBufSize_); + httpBuf_ = (char*)realloc(httpBuf_, httpBufSize_+1); if (httpBuf_ == NULL) { throw TTransportException("Out of memory."); } @@ -199,10 +202,12 @@ void THttpClient::refill() { uint32_t got = transport_->read((uint8_t*)(httpBuf_+httpBufPos_), httpBufSize_-httpBufPos_); httpBufPos_ += got; httpBuf_[httpBufPos_] = '\0'; - + if (got == 0) { - throw TTransportException("Could not finish reading HTTP headers"); + throw TTransportException("Could not refill buffer"); } + + return httpBuf_; } void THttpClient::readHeaders() { @@ -220,8 +225,7 @@ void THttpClient::readHeaders() { // Loop until headers are finished while (true) { - char* line = nextLine; - nextLine = readLine(nextLine); + char* line = readLine(nextLine, &nextLine); if (strlen(line) == 0) { if (finished) { diff --git a/lib/cpp/src/transport/THttpClient.h b/lib/cpp/src/transport/THttpClient.h index e7f88c9d..81fff391 100644 --- a/lib/cpp/src/transport/THttpClient.h +++ b/lib/cpp/src/transport/THttpClient.h @@ -67,7 +67,7 @@ class THttpClient : public TTransport { uint32_t httpBufSize_; uint32_t readMoreData(); - char* readLine(char* line); + char* readLine(char* line, char** next); void readHeaders(); void parseHeader(char* header); @@ -78,7 +78,7 @@ class THttpClient : public TTransport { char* readContent(char* pos, uint32_t size); - void refill(); + char* refill(); char* shift(char* pos); };