]> git.mxchange.org Git - simgear.git/blob - simgear/io/HTTPRequest.hxx
Improve (mostly Canvas event related) documentation.
[simgear.git] / simgear / io / HTTPRequest.hxx
1 ///@file
2 //
3 // Copyright (C) 2011  James Turner <zakalawe@mac.com>
4 // Copyright (C) 2013  Thomas Geymayer <tomgey@gmail.com>
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Library General Public
8 // License as published by the Free Software Foundation; either
9 // version 2 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Library General Public License for more details.
15 //
16 // You should have received a copy of the GNU Library General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA
19
20 #ifndef SG_HTTP_REQUEST_HXX
21 #define SG_HTTP_REQUEST_HXX
22
23 #include <map>
24
25 #include <simgear/structure/function_list.hxx>
26 #include <simgear/structure/map.hxx>
27 #include <simgear/structure/SGReferenced.hxx>
28 #include <simgear/structure/SGSharedPtr.hxx>
29 #include <simgear/math/sg_types.hxx>
30
31 #include <boost/bind.hpp>
32
33 class SGPropertyNode;
34
35 namespace simgear
36 {
37 namespace HTTP
38 {
39
40 /**
41  * Base class for HTTP request (and answer).
42  */
43 class Request:
44   public SGReferenced
45 {
46 public:
47     typedef boost::function<void(Request*)> Callback;
48
49     enum ReadyState
50     {
51       UNSENT = 0,
52       OPENED,
53       HEADERS_RECEIVED,
54       LOADING,
55       DONE,
56       FAILED
57     };
58
59     virtual ~Request();
60
61     /**
62      *
63      */
64     StringMap& requestHeaders()             { return _request_headers; }
65     const StringMap& requestHeaders() const { return _request_headers; }
66     std::string& requestHeader(const std::string& key)
67                                             { return _request_headers[key]; }
68     const std::string requestHeader(const std::string& key) const
69                                             { return _request_headers.get(key); }
70
71     /**
72      * Add a handler to be called when the request successfully completes.
73      *
74      * @note If the request is already complete, the handler is called
75      *       immediately.
76      */
77     Request* done(const Callback& cb);
78
79     template<class C>
80     Request* done(C* instance, void (C::*mem_func)(Request*))
81     {
82       return done(boost::bind(mem_func, instance, _1));
83     }
84
85     /**
86      * Add a handler to be called when the request completes or aborts with an
87      * error.
88      *
89      * @note If the request has already failed, the handler is called
90      *       immediately.
91      */
92     Request* fail(const Callback& cb);
93
94     template<class C>
95     Request* fail(C* instance, void (C::*mem_func)(Request*))
96     {
97       return fail(boost::bind(mem_func, instance, _1));
98     }
99
100     /**
101      * Add a handler to be called when the request either successfully completes
102      * or fails.
103      *
104      * @note If the request is already complete or has already failed, the
105      *       handler is called immediately.
106      */
107     Request* always(const Callback& cb);
108
109     template<class C>
110     Request* always(C* instance, void (C::*mem_func)(Request*))
111     {
112       return always(boost::bind(mem_func, instance, _1));
113     }
114
115     /**
116      * Set the data for the body of the request. The request is automatically
117      * send using the POST method.
118      *
119      * @param data  Body data
120      * @param type  Media Type (aka MIME) of the body data
121      */
122     void setBodyData( const std::string& data,
123                       const std::string& type = "text/plain" );
124     void setBodyData( const SGPropertyNode* data );
125
126     virtual void setUrl(const std::string& url);
127     
128     virtual std::string method() const
129         { return _method; }
130     virtual std::string url() const
131         { return _url; }
132     
133     virtual std::string scheme() const;
134     virtual std::string path() const;
135     virtual std::string host() const;
136     virtual std::string hostAndPort() const;
137     virtual unsigned short port() const;
138     virtual std::string query() const;
139     
140     StringMap const& responseHeaders() const
141         { return _responseHeaders; }
142
143     std::string responseMime() const;
144
145     virtual int responseCode() const
146         { return _responseStatus; }
147         
148     virtual std::string responseReason() const
149         { return _responseReason; }
150         
151     void setResponseLength(unsigned int l);
152     virtual unsigned int responseLength() const;
153   
154     /**
155      * Check if request contains body data.
156      */
157     virtual bool hasBodyData() const;
158
159     /**
160      * Retrieve the request body content type.
161      */
162     virtual std::string bodyType() const;
163
164     /**
165      * Retrieve the size of the request body.
166      */
167     virtual size_t bodyLength() const;
168     
169     /**
170      * Retrieve the body data bytes. Will be passed the maximum body bytes
171      * to return in the buffer, and must return the actual number
172      * of bytes written. 
173      */
174     virtual size_t getBodyData(char* s, size_t offset, size_t max_count) const;
175   
176     /**
177      * running total of body bytes received so far. Can be used
178      * to generate a completion percentage, if the response length is
179      * known. 
180      */
181     unsigned int responseBytesReceived() const
182         { return _receivedBodyBytes; }
183         
184     enum HTTPVersion {
185         HTTP_VERSION_UNKNOWN = 0,
186         HTTP_0_x, // 0.9 or similar
187         HTTP_1_0,
188         HTTP_1_1
189     };
190     
191     HTTPVersion responseVersion() const
192         { return _responseVersion; }
193     
194     ReadyState readyState() const { return _ready_state; }
195
196     /**
197      * Request aborting this request.
198      */
199     void abort();
200
201     /**
202      * Request aborting this request and specify the reported reaseon for it.
203      */
204     void abort(const std::string& reason);
205
206     bool closeAfterComplete() const;
207     bool isComplete() const;
208
209 protected:
210     Request(const std::string& url, const std::string method = "GET");
211
212     virtual void requestStart();
213     virtual void responseStart(const std::string& r);
214     virtual void responseHeader(const std::string& key, const std::string& value);
215     virtual void responseHeadersComplete();
216     virtual void responseComplete();
217     virtual void gotBodyData(const char* s, int n);
218
219     virtual void onDone();
220     virtual void onFail();
221     virtual void onAlways();
222
223     void setFailure(int code, const std::string& reason);
224
225 private:
226     friend class Client;
227     friend class Connection;
228     friend class ContentDecoder;
229     
230     Request(const Request&); // = delete;
231     Request& operator=(const Request&); // = delete;
232
233     void processBodyBytes(const char* s, int n);
234     void setReadyState(ReadyState state);
235
236     std::string   _method;
237     std::string   _url;
238     StringMap     _request_headers;
239     std::string   _request_data;
240     std::string   _request_media_type;
241
242     HTTPVersion   _responseVersion;
243     int           _responseStatus;
244     std::string   _responseReason;
245     StringMap     _responseHeaders;
246     unsigned int  _responseLength;
247     unsigned int  _receivedBodyBytes;
248
249     function_list<Callback> _cb_done,
250                             _cb_fail,
251                             _cb_always;
252
253     ReadyState    _ready_state;
254     bool          _willClose;
255 };
256
257 typedef SGSharedPtr<Request> Request_ptr;
258
259 } // of namespace HTTP
260 } // of namespace simgear
261
262 #endif // of SG_HTTP_REQUEST_HXX