X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fio%2FHTTPRequest.cxx;h=4b7a11bf607fb31c5f776ac0119a22372a6aff18;hb=902948e3c637969b4ad29c9b6dd756c7ede28ec4;hp=68d69d3cc270c2f41f5f55c3cdef83045d4e7aaa;hpb=a2249becba1d574d567791ef8b03ef50b129eb90;p=simgear.git diff --git a/simgear/io/HTTPRequest.cxx b/simgear/io/HTTPRequest.cxx index 68d69d3c..4b7a11bf 100644 --- a/simgear/io/HTTPRequest.cxx +++ b/simgear/io/HTTPRequest.cxx @@ -17,7 +17,12 @@ extern const int DEFAULT_HTTP_PORT; Request::Request(const string& url, const string method) : _method(method), - _url(url) + _url(url), + _responseVersion(HTTP_VERSION_UNKNOWN), + _responseStatus(0), + _responseLength(0), + _receivedBodyBytes(0), + _willClose(false) { } @@ -49,17 +54,21 @@ void Request::responseStart(const string& r) string_list parts = strutils::split(r, NULL, maxSplit); if (parts.size() != 3) { SG_LOG(SG_IO, SG_WARN, "HTTP::Request: malformed response start:" << r); - _responseStatus = 400; - _responseReason = "bad HTTP response header"; + setFailure(400, "malformed HTTP response header"); return; } + _responseVersion = decodeVersion(parts[0]); _responseStatus = strutils::to_int(parts[1]); _responseReason = parts[2]; } void Request::responseHeader(const string& key, const string& value) { + if (key == "connection") { + _willClose = (value.find("close") >= 0); + } + _responseHeaders[key] = value; } @@ -68,6 +77,12 @@ void Request::responseHeadersComplete() // no op } +void Request::processBodyBytes(const char* s, int n) +{ + _receivedBodyBytes += n; + gotBodyData(s, n); +} + void Request::gotBodyData(const char* s, int n) { @@ -148,14 +163,46 @@ string Request::hostAndPort() const return u.substr(schemeEnd + 3, hostEnd - (schemeEnd + 3)); } -unsigned int Request::contentLength() const +void Request::setResponseLength(unsigned int l) { - HeaderDict::const_iterator it = _responseHeaders.find("content-length"); - if (it == _responseHeaders.end()) { - return 0; + _responseLength = l; +} + +unsigned int Request::responseLength() const +{ +// if the server didn't supply a content length, use the number +// of bytes we actually received (so far) + if ((_responseLength == 0) && (_receivedBodyBytes > 0)) { + return _receivedBodyBytes; } - return (unsigned int) strutils::to_int(it->second); + return _responseLength; +} + +void Request::setFailure(int code, const std::string& reason) +{ + _responseStatus = code; + _responseReason = reason; + failed(); +} + +void Request::failed() +{ + // no-op in base class +} + +Request::HTTPVersion Request::decodeVersion(const string& v) +{ + if (v == "HTTP/1.1") return HTTP_1_1; + if (v == "HTTP/1.0") return HTTP_1_0; + if (strutils::starts_with(v, "HTTP/0.")) return HTTP_0_x; + return HTTP_VERSION_UNKNOWN; +} + +bool Request::closeAfterComplete() const +{ +// for non HTTP/1.1 connections, assume server closes + return _willClose || (_responseVersion != HTTP_1_1); } } // of namespace HTTP