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