]> git.mxchange.org Git - simgear.git/blob - simgear/io/HTTPRequest.hxx
HTTPFileRequest: only save file if status == 200
[simgear.git] / simgear / io / HTTPRequest.hxx
1 #ifndef SG_HTTP_REQUEST_HXX
2 #define SG_HTTP_REQUEST_HXX
3
4 #include <map>
5
6 #include <simgear/structure/map.hxx>
7 #include <simgear/structure/SGReferenced.hxx>
8 #include <simgear/structure/SGSharedPtr.hxx>
9 #include <simgear/math/sg_types.hxx>
10
11 #include <boost/function.hpp>
12
13 class SGPropertyNode;
14
15 namespace simgear
16 {
17 namespace HTTP
18 {
19
20 class Request:
21   public SGReferenced
22 {
23 public:
24     typedef boost::function<void(Request*)> Callback;
25
26     enum ReadyState
27     {
28       UNSENT = 0,
29       OPENED,
30       HEADERS_RECEIVED,
31       LOADING,
32       DONE,
33       FAILED
34     };
35
36     virtual ~Request();
37
38     /**
39      *
40      */
41     StringMap& requestHeaders()             { return _request_headers; }
42     const StringMap& requestHeaders() const { return _request_headers; }
43     std::string& requestHeader(const std::string& key)
44                                             { return _request_headers[key]; }
45     const std::string requestHeader(const std::string& key) const
46                                             { return _request_headers.get(key); }
47
48     /**
49      * Set the handler to be called when the request successfully completes.
50      *
51      * @note If the request is already complete, the handler is called
52      *       immediately.
53      */
54     Request* done(const Callback& cb);
55
56     /**
57      * Set the handler to be called when the request completes or aborts with an
58      * error.
59      *
60      * @note If the request has already failed, the handler is called
61      *       immediately.
62      */
63     Request* fail(const Callback& cb);
64
65     /**
66      * Set the handler to be called when the request either successfully
67      * completes or fails.
68      *
69      * @note If the request is already complete or has already failed, the
70      *       handler is called immediately.
71      */
72     Request* always(const Callback& cb);
73
74     /**
75      * Set the data for the body of the request. The request is automatically
76      * send using the POST method.
77      *
78      * @param data  Body data
79      * @param type  Media Type (aka MIME) of the body data
80      */
81     void setBodyData( const std::string& data,
82                       const std::string& type = "text/plain" );
83     void setBodyData( const SGPropertyNode* data );
84
85     virtual void setUrl(const std::string& url);
86     
87     virtual std::string method() const
88         { return _method; }
89     virtual std::string url() const
90         { return _url; }
91     
92     virtual std::string scheme() const;
93     virtual std::string path() const;
94     virtual std::string host() const;
95     virtual std::string hostAndPort() const;
96     virtual unsigned short port() const;
97     virtual std::string query() const;
98     
99     StringMap const& responseHeaders() const
100         { return _responseHeaders; }
101
102     virtual int responseCode() const
103         { return _responseStatus; }
104         
105     virtual std::string responseReason() const
106         { return _responseReason; }
107         
108     void setResponseLength(unsigned int l);
109     virtual unsigned int responseLength() const;
110   
111     /**
112      * Check if request contains body data.
113      */
114     virtual bool hasBodyData() const;
115
116     /**
117      * Retrieve the request body content type.
118      */
119     virtual std::string bodyType() const;
120
121     /**
122      * Retrieve the size of the request body.
123      */
124     virtual size_t bodyLength() const;
125     
126     /**
127      * Retrieve the body data bytes. Will be passed the maximum body bytes
128      * to return in the buffer, and must return the actual number
129      * of bytes written. 
130      */
131     virtual size_t getBodyData(char* s, size_t offset, size_t max_count) const;
132   
133     /**
134      * running total of body bytes received so far. Can be used
135      * to generate a completion percentage, if the response length is
136      * known. 
137      */
138     unsigned int responseBytesReceived() const
139         { return _receivedBodyBytes; }
140         
141     enum HTTPVersion {
142         HTTP_VERSION_UNKNOWN = 0,
143         HTTP_0_x, // 0.9 or similar
144         HTTP_1_0,
145         HTTP_1_1
146     };
147     
148     HTTPVersion responseVersion() const
149         { return _responseVersion; }
150     
151     ReadyState readyState() const { return _ready_state; }
152
153     /**
154      * Request aborting this request.
155      */
156     void abort();
157
158     /**
159      * Request aborting this request and specify the reported reaseon for it.
160      */
161     void abort(const std::string& reason);
162
163     bool closeAfterComplete() const;
164     bool isComplete() const;
165
166 protected:
167     Request(const std::string& url, const std::string method = "GET");
168
169     virtual void requestStart();
170     virtual void responseStart(const std::string& r);
171     virtual void responseHeader(const std::string& key, const std::string& value);
172     virtual void responseHeadersComplete();
173     virtual void responseComplete();
174     virtual void gotBodyData(const char* s, int n);
175
176     virtual void onDone();
177     virtual void onFail();
178     virtual void onAlways();
179
180     void setFailure(int code, const std::string& reason);
181
182 private:
183     friend class Client;
184     friend class Connection;
185     friend class ContentDecoder;
186     
187     Request(const Request&); // = delete;
188     Request& operator=(const Request&); // = delete;
189
190     void processBodyBytes(const char* s, int n);
191     void setReadyState(ReadyState state);
192
193     std::string   _method;
194     std::string   _url;
195     StringMap     _request_headers;
196     std::string   _request_data;
197     std::string   _request_media_type;
198
199     HTTPVersion   _responseVersion;
200     int           _responseStatus;
201     std::string   _responseReason;
202     StringMap     _responseHeaders;
203     unsigned int  _responseLength;
204     unsigned int  _receivedBodyBytes;
205
206     Callback      _cb_done,
207                   _cb_fail,
208                   _cb_always;
209
210     ReadyState    _ready_state;
211     bool          _willClose;
212 };
213
214 typedef SGSharedPtr<Request> Request_ptr;
215
216 } // of namespace HTTP
217 } // of namespace simgear
218
219 #endif // of SG_HTTP_REQUEST_HXX