]> git.mxchange.org Git - simgear.git/blobdiff - simgear/io/HTTPRequest.cxx
Fix windows build
[simgear.git] / simgear / io / HTTPRequest.cxx
index 50d059e6e2ffcfbebc55a932342a204107f1dad6..4b7a11bf607fb31c5f776ac0119a22372a6aff18 100644 (file)
@@ -7,12 +7,6 @@
 using std::string;
 using std::map;
 
-#include <iostream>
-
-using std::cout;
-using std::cerr;
-using std::endl;
-
 namespace simgear
 {
 
@@ -23,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)
 {
     
 }
@@ -51,14 +50,25 @@ string Request::header(const std::string& name) const
 
 void Request::responseStart(const string& r)
 {
-    const int maxSplit = 2; // HTTP/1.1 nnn status code
+    const int maxSplit = 2; // HTTP/1.1 nnn reason-string
     string_list parts = strutils::split(r, NULL, maxSplit);
+    if (parts.size() != 3) {
+        SG_LOG(SG_IO, SG_WARN, "HTTP::Request: malformed response start:" << r);
+        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;
 }
 
@@ -67,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)
 {
 
@@ -147,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)
+{
+    _responseLength = l;
+}
+
+unsigned int Request::responseLength() const
 {
-    HeaderDict::const_iterator it = _responseHeaders.find("content-length");
-    if (it == _responseHeaders.end()) {
-        return 0;
+// 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