summaryrefslogtreecommitdiff
path: root/include/SFML/Network/Http.hpp
blob: 3e02531fb84ce5adc454ce634b9c323ab34c4ff8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
//    you must not claim that you wrote the original software.
//    If you use this software in a product, an acknowledgment
//    in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
//    and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////

#ifndef SFML_HTTP_HPP
#define SFML_HTTP_HPP

////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/System/NonCopyable.hpp>
#include <SFML/Network/IPAddress.hpp>
#include <SFML/Network/SocketTCP.hpp>
#include <map>
#include <string>


namespace sf
{
////////////////////////////////////////////////////////////
/// This class provides methods for manipulating the HTTP
/// protocol (described in RFC 1945).
/// It can connect to a website, get its files, send requests, etc.
////////////////////////////////////////////////////////////
class SFML_API Http : NonCopyable
{
public :

    ////////////////////////////////////////////////////////////
    /// This class wraps an HTTP request, which is basically :
    /// - a header with a method, a target URI, and a set of field/value pairs
    /// - an optional body (for POST requests)
    ////////////////////////////////////////////////////////////
    class SFML_API Request
    {
    public :

        ////////////////////////////////////////////////////////////
        /// Enumerate the available HTTP methods for a request
        ////////////////////////////////////////////////////////////
        enum Method
        {
            Get,  ///< Request in get mode, standard method to retrieve a page
            Post, ///< Request in post mode, usually to send data to a page
            Head  ///< Request a page's header only
        };

        ////////////////////////////////////////////////////////////
        /// Default constructor
        ///
        /// \param RequestMethod : Method to use for the request (Get by default)
        /// \param URI :           Target URI ("/" by default -- index page)
        /// \param Body :          Content of the request's body (empty by default)
        ///
        ////////////////////////////////////////////////////////////
        Request(Method RequestMethod = Get, const std::string& URI = "/", const std::string& Body = "");

        ////////////////////////////////////////////////////////////
        /// Set the value of a field; the field is added if it doesn't exist
        ///
        /// \param Field : Name of the field to set (case-insensitive)
        /// \param Value : Value of the field
        ///
        ////////////////////////////////////////////////////////////
        void SetField(const std::string& Field, const std::string& Value);

        ////////////////////////////////////////////////////////////
        /// Set the request method.
        /// This parameter is Http::Request::Get by default
        ///
        /// \param RequestMethod : Method to use for the request
        ///
        ////////////////////////////////////////////////////////////
        void SetMethod(Method RequestMethod);

        ////////////////////////////////////////////////////////////
        /// Set the target URI of the request.
        /// This parameter is "/" by default
        ///
        /// \param URI : URI to request, local to the host
        ///
        ////////////////////////////////////////////////////////////
        void SetURI(const std::string& URI);

        ////////////////////////////////////////////////////////////
        /// Set the HTTP version of the request.
        /// This parameter is 1.0 by default
        ///
        /// \param Major : Major version number
        /// \param Minor : Minor version number
        ///
        ////////////////////////////////////////////////////////////
        void SetHttpVersion(unsigned int Major, unsigned int Minor);

        ////////////////////////////////////////////////////////////
        /// Set the body of the request. This parameter is optional and
        /// makes sense only for POST requests.
        /// This parameter is empty by default
        ///
        /// \param Body : Content of the request body
        ///
        ////////////////////////////////////////////////////////////
        void SetBody(const std::string& Body);

    private :

        friend class Http;

        ////////////////////////////////////////////////////////////
        /// Get the string representation of the request header
        ///
        /// \return String containing the request
        ///
        ////////////////////////////////////////////////////////////
        std::string ToString() const;

        ////////////////////////////////////////////////////////////
        /// Check if the given field has been defined
        ///
        /// \param Field : Name of the field to check (case-insensitive)
        ///
        /// \return True if the field exists
        ///
        ////////////////////////////////////////////////////////////
        bool HasField(const std::string& Field) const;

        ////////////////////////////////////////////////////////////
        // Types
        ////////////////////////////////////////////////////////////
        typedef std::map<std::string, std::string> FieldTable;

        ////////////////////////////////////////////////////////////
        // Member data
        ////////////////////////////////////////////////////////////
        FieldTable   myFields;       ///< Fields of the header
        Method       myMethod;       ///< Method to use for the request
        std::string  myURI;          ///< Target URI of the request
        unsigned int myMajorVersion; ///< Major HTTP version
        unsigned int myMinorVersion; ///< Minor HTTP version
        std::string  myBody;         ///< Body of the request
    };

    ////////////////////////////////////////////////////////////
    /// This class wraps an HTTP response, which is basically :
    /// - a header with a status code and a set of field/value pairs
    /// - a body (the content of the requested resource)
    ////////////////////////////////////////////////////////////
    class SFML_API Response
    {
    public :

        ////////////////////////////////////////////////////////////
        /// Enumerate all the valid status codes returned in
        /// a HTTP response
        ////////////////////////////////////////////////////////////
        enum Status
        {
            // 2xx: success
            Ok        = 200, ///< Most common code returned when operation was successful
            Created   = 201, ///< The resource has successfully been created
            Accepted  = 202, ///< The request has been accepted, but will be processed later by the server
            NoContent = 204, ///< Sent when the server didn't send any data in return

            // 3xx: redirection
            MultipleChoices  = 300, ///< The requested page can be accessed from several locations
            MovedPermanently = 301, ///< The requested page has permanently moved to a new location
            MovedTemporarily = 302, ///< The requested page has temporarily moved to a new location
            NotModified      = 304, ///< For conditionnal requests, means the requested page hasn't changed and doesn't need to be refreshed

            // 4xx: client error
            BadRequest   = 400, ///< The server couldn't understand the request (syntax error)
            Unauthorized = 401, ///< The requested page needs an authentification to be accessed
            Forbidden    = 403, ///< The requested page cannot be accessed at all, even with authentification
            NotFound     = 404, ///< The requested page doesn't exist

            // 5xx: server error
            InternalServerError = 500, ///< The server encountered an unexpected error
            NotImplemented      = 501, ///< The server doesn't implement a requested feature
            BadGateway          = 502, ///< The gateway server has received an error from the source server
            ServiceNotAvailable = 503, ///< The server is temporarily unavailable (overloaded, in maintenance, ...)

            // 10xx: SFML custom codes
            InvalidResponse  = 1000, ///< Response is not a valid HTTP one
            ConnectionFailed = 1001  ///< Connection with server failed
        };

        ////////////////////////////////////////////////////////////
        /// Default constructor
        ///
        ////////////////////////////////////////////////////////////
        Response();

        ////////////////////////////////////////////////////////////
        /// Get the value of a field
        ///
        /// \param Field : Name of the field to get (case-insensitive)
        ///
        /// \return Value of the field, or empty string if not found
        ///
        ////////////////////////////////////////////////////////////
        const std::string& GetField(const std::string& Field) const;

        ////////////////////////////////////////////////////////////
        /// Get the header's status code
        ///
        /// \return Header's status code
        ///
        ////////////////////////////////////////////////////////////
        Status GetStatus() const;

        ////////////////////////////////////////////////////////////
        /// Get the major HTTP version number of the response
        ///
        /// \return Major version number
        ///
        ////////////////////////////////////////////////////////////
        unsigned int GetMajorHttpVersion() const;

        ////////////////////////////////////////////////////////////
        /// Get the major HTTP version number of the response
        ///
        /// \return Major version number
        ///
        ////////////////////////////////////////////////////////////
        unsigned int GetMinorHttpVersion() const;

        ////////////////////////////////////////////////////////////
        /// Get the body of the response. The body can contain :
        /// - the requested page (for GET requests)
        /// - a response from the server (for POST requests)
        /// - nothing (for HEAD requests)
        /// - an error message (in case of an error)
        ///
        /// \return The response body
        ///
        ////////////////////////////////////////////////////////////
        const std::string& GetBody() const;

    private :

        friend class Http;

        ////////////////////////////////////////////////////////////
        /// Construct the header from a response string
        ///
        /// \param Data : Content of the response's header to parse
        ///
        ////////////////////////////////////////////////////////////
        void FromString(const std::string& Data);

        ////////////////////////////////////////////////////////////
        // Types
        ////////////////////////////////////////////////////////////
        typedef std::map<std::string, std::string> FieldTable;

        ////////////////////////////////////////////////////////////
        // Member data
        ////////////////////////////////////////////////////////////
        FieldTable   myFields;       ///< Fields of the header
        Status       myStatus;       ///< Status code
        unsigned int myMajorVersion; ///< Major HTTP version
        unsigned int myMinorVersion; ///< Minor HTTP version
        std::string  myBody;         ///< Body of the response
    };

    ////////////////////////////////////////////////////////////
    /// Default constructor
    ///
    ////////////////////////////////////////////////////////////
    Http();

    ////////////////////////////////////////////////////////////
    /// Construct the Http instance with the target host
    ///
    /// \param Host : Web server to connect to
    /// \param Port : Port to use for connection (0 by default -- use the standard port of the protocol used)
    ///
    ////////////////////////////////////////////////////////////
    Http(const std::string& Host, unsigned short Port = 0);

    ////////////////////////////////////////////////////////////
    /// Set the target host
    ///
    /// \param Host : Web server to connect to
    /// \param Port : Port to use for connection (0 by default -- use the standard port of the protocol used)
    ///
    ////////////////////////////////////////////////////////////
    void SetHost(const std::string& Host, unsigned short Port = 0);

    ////////////////////////////////////////////////////////////
    /// Send a HTTP request and return the server's response.
    /// You must be connected to a host before sending requests.
    /// Any missing mandatory header field will be added with an appropriate value.
    /// Warning : this function waits for the server's response and may
    /// not return instantly; use a thread if you don't want to block your
    /// application.
    ///
    /// \param Req : Request to send
    ///
    /// \return Server's response
    ///
    ////////////////////////////////////////////////////////////
    Response SendRequest(const Request& Req);

private :

    ////////////////////////////////////////////////////////////
    // Member data
    ////////////////////////////////////////////////////////////
    SocketTCP      myConnection; ///< Connection to the host
    IPAddress      myHost;       ///< Web host address
    std::string    myHostName;   ///< Web host name
    unsigned short myPort;       ///< Port used for connection with host
};

} // namespace sf


#endif // SFML_HTTP_HPP