]> git.mxchange.org Git - simgear.git/blobdiff - simgear/io/HTTPRequest.cxx
Fix windows build
[simgear.git] / simgear / io / HTTPRequest.cxx
index 68d69d3cc270c2f41f5f55c3cdef83045d4e7aaa..4b7a11bf607fb31c5f776ac0119a22372a6aff18 100644 (file)
@@ -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