]> git.mxchange.org Git - simgear.git/blob - simgear/io/HTTPRequest.cxx
84a19c99682e427394bbe0f3f7e96ec3b660a7fe
[simgear.git] / simgear / io / HTTPRequest.cxx
1 #include "HTTPRequest.hxx"
2
3 #include <simgear/misc/strutils.hxx>
4 #include <simgear/compiler.h>
5 #include <simgear/debug/logstream.hxx>
6
7 using std::string;
8 using std::map;
9
10 namespace simgear
11 {
12
13 namespace HTTP
14 {
15
16 extern const int DEFAULT_HTTP_PORT;
17
18 Request::Request(const string& url, const string method) :
19     _method(method),
20     _url(url),
21     _responseStatus(0),
22     _responseLength(0),
23     _receivedBodyBytes(0)
24 {
25     
26 }
27
28 Request::~Request()
29 {
30     
31 }
32
33 void Request::setUrl(const string& url)
34 {
35     _url = url;
36 }
37
38 string_list Request::requestHeaders() const
39 {
40     string_list r;
41     return r;
42 }
43
44 string Request::header(const std::string& name) const
45 {
46     return string();
47 }
48
49 void Request::responseStart(const string& r)
50 {
51     const int maxSplit = 2; // HTTP/1.1 nnn reason-string
52     string_list parts = strutils::split(r, NULL, maxSplit);
53     if (parts.size() != 3) {
54         SG_LOG(SG_IO, SG_WARN, "HTTP::Request: malformed response start:" << r);
55         _responseStatus = 400;
56         _responseReason = "bad HTTP response header";
57         return;
58     }
59     
60     _responseStatus = strutils::to_int(parts[1]);
61     _responseReason = parts[2];
62 }
63
64 void Request::responseHeader(const string& key, const string& value)
65 {
66     _responseHeaders[key] = value;
67 }
68
69 void Request::responseHeadersComplete()
70 {
71     // no op
72 }
73
74 void Request::processBodyBytes(const char* s, int n)
75 {
76     _receivedBodyBytes += n;
77     gotBodyData(s, n);
78 }
79
80 void Request::gotBodyData(const char* s, int n)
81 {
82
83 }
84
85 void Request::responseComplete()
86 {
87     
88 }
89     
90 string Request::scheme() const
91 {
92     int firstColon = url().find(":");
93     if (firstColon > 0) {
94         return url().substr(0, firstColon);
95     }
96     
97     return ""; // couldn't parse scheme
98 }
99     
100 string Request::path() const
101 {
102     string u(url());
103     int schemeEnd = u.find("://");
104     if (schemeEnd < 0) {
105         return ""; // couldn't parse scheme
106     }
107     
108     int hostEnd = u.find('/', schemeEnd + 3);
109     if (hostEnd < 0) { 
110         return ""; // couldn't parse host
111     }
112     
113     int query = u.find('?', hostEnd + 1);
114     if (query < 0) {
115         // all remainder of URL is path
116         return u.substr(hostEnd);
117     }
118     
119     return u.substr(hostEnd, query - hostEnd);
120 }
121
122 string Request::host() const
123 {
124     string hp(hostAndPort());
125     int colonPos = hp.find(':');
126     if (colonPos >= 0) {
127         return hp.substr(0, colonPos); // trim off the colon and port
128     } else {
129         return hp; // no port specifier
130     }
131 }
132
133 unsigned short Request::port() const
134 {
135     string hp(hostAndPort());
136     int colonPos = hp.find(':');
137     if (colonPos >= 0) {
138         return (unsigned short) strutils::to_int(hp.substr(colonPos + 1));
139     } else {
140         return DEFAULT_HTTP_PORT;
141     }
142 }
143
144 string Request::hostAndPort() const
145 {
146     string u(url());
147     int schemeEnd = u.find("://");
148     if (schemeEnd < 0) {
149         return ""; // couldn't parse scheme
150     }
151     
152     int hostEnd = u.find('/', schemeEnd + 3);
153     if (hostEnd < 0) { // all remainder of URL is host
154         return u.substr(schemeEnd + 3);
155     }
156     
157     return u.substr(schemeEnd + 3, hostEnd - (schemeEnd + 3));
158 }
159
160 void Request::setResponseLength(unsigned int l)
161 {
162     _responseLength = l;
163 }
164
165 unsigned int Request::responseLength() const
166 {
167 // if the server didn't supply a content length, use the number
168 // of bytes we actually received (so far)
169     if ((_responseLength == 0) && (_receivedBodyBytes > 0)) {
170         return _receivedBodyBytes;
171     }
172     
173     return _responseLength;
174 }
175
176 void Request::setFailure(int code, const std::string& reason)
177 {
178     _responseStatus = code;
179     _responseReason = reason;
180     failed();
181 }
182
183 void Request::failed()
184 {
185     // no-op in base class
186 }
187
188 } // of namespace HTTP
189
190 } // of namespace simgear