X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fio%2FHTTPClient.cxx;h=8a48bff6386deb9e97c75cad39f44f19ae5ccca2;hb=adb7db9229db1d869b254ac18f1471bed464c508;hp=2eff7439ba3e1adaada1edb1c40c2012a89822a5;hpb=d1af42e9adc79e6c0c9bcac416fae5a77a7b506b;p=simgear.git diff --git a/simgear/io/HTTPClient.cxx b/simgear/io/HTTPClient.cxx index 2eff7439..8a48bff6 100644 --- a/simgear/io/HTTPClient.cxx +++ b/simgear/io/HTTPClient.cxx @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -46,7 +47,7 @@ const int ZLIB_INFLATE_WINDOW_BITS = -MAX_WBITS; const int GZIP_HEADER_ID1 = 31; const int GZIP_HEADER_ID2 = 139; const int GZIP_HEADER_METHOD_DEFLATE = 8; -const int GZIP_HEADER_SIZE = 10; +const unsigned int GZIP_HEADER_SIZE = 10; const int GZIP_HEADER_FEXTRA = 1 << 2; const int GZIP_HEADER_FNAME = 1 << 3; const int GZIP_HEADER_COMMENT = 1 << 4; @@ -85,9 +86,26 @@ public: // socket-level errors virtual void handleError(int error) - { + { + if (error == ENOENT) { + // name lookup failure + // we won't have an active request yet, so the logic below won't + // fire to actually call setFailure. Let's fail all of the requests + BOOST_FOREACH(Request_ptr req, sentRequests) { + req->setFailure(error, "hostname lookup failure"); + } + + BOOST_FOREACH(Request_ptr req, queuedRequests) { + req->setFailure(error, "hostname lookup failure"); + } + + // name lookup failure, abandon all requests on this connection + sentRequests.clear(); + queuedRequests.clear(); + } + NetChat::handleError(error); - if (activeRequest) { + if (activeRequest) { SG_LOG(SG_IO, SG_INFO, "HTTP socket error"); activeRequest->setFailure(error, "socket error"); activeRequest = NULL; @@ -280,25 +298,51 @@ public: zlib.next_out = zlibOutputBuffer; zlib.avail_out = ZLIB_DECOMPRESS_BUFFER_SIZE; - if (contentGZip) { + if (contentGZip && !handleGZipHeader()) { + return; + } + + int writtenSize = 0; + do { + int result = inflate(&zlib, Z_NO_FLUSH); + if (result == Z_OK || result == Z_STREAM_END) { + // nothing to do + } else { + SG_LOG(SG_IO, SG_WARN, "got Zlib error:" << result); + return; + } + + writtenSize = ZLIB_DECOMPRESS_BUFFER_SIZE - zlib.avail_out; + if (result == Z_STREAM_END) { + break; + } + } while ((writtenSize == 0) && (zlib.avail_in > 0)); + + if (writtenSize > 0) { + activeRequest->processBodyBytes((const char*) zlibOutputBuffer, writtenSize); + } + } + + bool handleGZipHeader() + { // we clear this down to contentDeflate once the GZip header has been seen - if (reqSize < GZIP_HEADER_SIZE) { - return; // need more header bytes + if (zlib.avail_in < GZIP_HEADER_SIZE) { + return false; // need more header bytes } if ((zlibInflateBuffer[0] != GZIP_HEADER_ID1) || (zlibInflateBuffer[1] != GZIP_HEADER_ID2) || (zlibInflateBuffer[2] != GZIP_HEADER_METHOD_DEFLATE)) { - return; // invalid GZip header + return false; // invalid GZip header } char flags = zlibInflateBuffer[3]; int gzipHeaderSize = GZIP_HEADER_SIZE; if (flags & GZIP_HEADER_FEXTRA) { gzipHeaderSize += 2; - if (reqSize < gzipHeaderSize) { - return; // need more header bytes + if (zlib.avail_in < gzipHeaderSize) { + return false; // need more header bytes } unsigned short extraHeaderBytes = *(reinterpret_cast(zlibInflateBuffer + GZIP_HEADER_FEXTRA)); @@ -307,14 +351,14 @@ public: } gzipHeaderSize += extraHeaderBytes; - if (reqSize < gzipHeaderSize) { - return; // need more header bytes + if (zlib.avail_in < gzipHeaderSize) { + return false; // need more header bytes } } if (flags & GZIP_HEADER_FNAME) { gzipHeaderSize++; - while (gzipHeaderSize <= reqSize) { + while (gzipHeaderSize <= zlib.avail_in) { if (zlibInflateBuffer[gzipHeaderSize-1] == 0) { break; // found terminating NULL character } @@ -323,7 +367,7 @@ public: if (flags & GZIP_HEADER_COMMENT) { gzipHeaderSize++; - while (gzipHeaderSize <= reqSize) { + while (gzipHeaderSize <= zlib.avail_in) { if (zlibInflateBuffer[gzipHeaderSize-1] == 0) { break; // found terminating NULL character } @@ -334,33 +378,16 @@ public: gzipHeaderSize += 2; } - if (reqSize < gzipHeaderSize) { - return; // need more header bytes + if (zlib.avail_in < gzipHeaderSize) { + return false; // need more header bytes } zlib.next_in += gzipHeaderSize; - zlib.avail_in = reqSize - gzipHeaderSize; + zlib.avail_in -= gzipHeaderSize; // now we've processed the GZip header, can decode as deflate contentGZip = false; contentDeflate = true; - } - - int writtenSize = 0; - do { - int result = inflate(&zlib, Z_NO_FLUSH); - if (result == Z_OK || result == Z_STREAM_END) { - - } else { - SG_LOG(SG_IO, SG_WARN, "got Zlib error:" << result); - return; - } - - writtenSize = ZLIB_DECOMPRESS_BUFFER_SIZE - zlib.avail_out; - } while ((writtenSize == 0) && (zlib.avail_in > 0)); - - if (writtenSize > 0) { - activeRequest->processBodyBytes((const char*) zlibOutputBuffer, writtenSize); - } + return true; } virtual void foundTerminator(void) @@ -387,6 +414,7 @@ public: case STATE_GETTING_CHUNKED_BYTES: setTerminator("\r\n"); state = STATE_GETTING_CHUNKED; + buffer.clear(); break; @@ -535,7 +563,7 @@ private: // blank line after chunk data return; } - + int chunkSize = 0; int semiPos = buffer.find(';'); if (semiPos >= 0) {