]> git.mxchange.org Git - simgear.git/blob - simgear/io/HTTPRequest.hxx
HTTPRequest/pkg::Install: do not replace callbacks.
[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/function_list.hxx>
7 #include <simgear/structure/map.hxx>
8 #include <simgear/structure/SGReferenced.hxx>
9 #include <simgear/structure/SGSharedPtr.hxx>
10 #include <simgear/math/sg_types.hxx>
11
12 #include <boost/bind.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      * Add a 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      * Add a 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      * Add a handler to be called when the request either successfully completes
80      * 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     std::string responseMime() const;
122
123     virtual int responseCode() const
124         { return _responseStatus; }
125         
126     virtual std::string responseReason() const
127         { return _responseReason; }
128         
129     void setResponseLength(unsigned int l);
130     virtual unsigned int responseLength() const;
131   
132     /**
133      * Check if request contains body data.
134      */
135     virtual bool hasBodyData() const;
136
137     /**
138      * Retrieve the request body content type.
139      */
140     virtual std::string bodyType() const;
141
142     /**
143      * Retrieve the size of the request body.
144      */
145     virtual size_t bodyLength() const;
146     
147     /**
148      * Retrieve the body data bytes. Will be passed the maximum body bytes
149      * to return in the buffer, and must return the actual number
150      * of bytes written. 
151      */
152     virtual size_t getBodyData(char* s, size_t offset, size_t max_count) const;
153   
154     /**
155      * running total of body bytes received so far. Can be used
156      * to generate a completion percentage, if the response length is
157      * known. 
158      */
159     unsigned int responseBytesReceived() const
160         { return _receivedBodyBytes; }
161         
162     enum HTTPVersion {
163         HTTP_VERSION_UNKNOWN = 0,
164         HTTP_0_x, // 0.9 or similar
165         HTTP_1_0,
166         HTTP_1_1
167     };
168     
169     HTTPVersion responseVersion() const
170         { return _responseVersion; }
171     
172     ReadyState readyState() const { return _ready_state; }
173
174     /**
175      * Request aborting this request.
176      */
177     void abort();
178
179     /**
180      * Request aborting this request and specify the reported reaseon for it.
181      */
182     void abort(const std::string& reason);
183
184     bool closeAfterComplete() const;
185     bool isComplete() const;
186
187 protected:
188     Request(const std::string& url, const std::string method = "GET");
189
190     virtual void requestStart();
191     virtual void responseStart(const std::string& r);
192     virtual void responseHeader(const std::string& key, const std::string& value);
193     virtual void responseHeadersComplete();
194     virtual void responseComplete();
195     virtual void gotBodyData(const char* s, int n);
196
197     virtual void onDone();
198     virtual void onFail();
199     virtual void onAlways();
200
201     void setFailure(int code, const std::string& reason);
202
203 private:
204     friend class Client;
205     friend class Connection;
206     friend class ContentDecoder;
207     
208     Request(const Request&); // = delete;
209     Request& operator=(const Request&); // = delete;
210
211     void processBodyBytes(const char* s, int n);
212     void setReadyState(ReadyState state);
213
214     std::string   _method;
215     std::string   _url;
216     StringMap     _request_headers;
217     std::string   _request_data;
218     std::string   _request_media_type;
219
220     HTTPVersion   _responseVersion;
221     int           _responseStatus;
222     std::string   _responseReason;
223     StringMap     _responseHeaders;
224     unsigned int  _responseLength;
225     unsigned int  _receivedBodyBytes;
226
227     function_list<Callback> _cb_done,
228                             _cb_fail,
229                             _cb_always;
230
231     ReadyState    _ready_state;
232     bool          _willClose;
233 };
234
235 typedef SGSharedPtr<Request> Request_ptr;
236
237 } // of namespace HTTP
238 } // of namespace simgear
239
240 #endif // of SG_HTTP_REQUEST_HXX