Use Vlinder::Atomics
[Arachnida.git] / lib / Spin / Details / Response.h
blobd78c0bbcc9825f7cc0ae5dad4bdd0a2ea1c0df3c
1 #ifndef _spin_details_response_h
2 #define _spin_details_response_h
4 #include <string>
5 #include <vector>
6 #include "prologue.h"
7 #include "Header.h"
9 namespace Spin
11 namespace Details
13 /** An HTTP response.
14 * This little structure encapsulates everything there is to know about an
15 * HTTP response and allows you to easily add stuff to it. It overloads the
16 * function call operator allowing you to easily add headers to the response,
17 * like so:
18 * \dontinclude Response.cpp
19 * \skip tryResponseWithHeaders
20 * \skip ::Response
21 * \until response
22 * \until response
23 * The same mechanism also allows you to add a body, by calling the object as
24 * a function with only a single argument:
25 * \skip tryResponseWithBody
26 * \skip ::Response
27 * \until response
28 * \until response
29 * It even allows to to add anything serializable to the response, including
30 * another response (or even the response itself):
31 * \skip tryResponseWithResponse
32 * \skip ::Response
33 * \until response
34 * \until response
35 * and, as you can see in this last example, the function call operator returns
36 * a reference to the response object itself, which means you can chain function
37 * calls together.
39 * Formatted a bit differently, the Mesothelae test server uses this feature
40 * (as of version 1.1.00) as follows:
41 * \dontinclude bin/Mesothelae/main.cpp
42 * \skip protocol_and_version_
43 * \until index.html
45 struct SPIN_API Response
47 enum StatusCode
49 continue__ = 100, ///< Section 10.1.1: Continue
50 switching_protocols__ = 101, ///< Section 10.1.2: Switching Protocols
51 ok__ = 200, ///< Section 10.2.1: OK
52 created__ = 201, ///< Section 10.2.2: Created
53 accepted__ = 202, ///< Section 10.2.3: Accepted
54 non_authoritive_information__ = 203, ///< Section 10.2.4: Non-Authoritative Information
55 no_content__ = 204, ///< Section 10.2.5: No Content
56 reset_content__ = 205, ///< Section 10.2.6: Reset Content
57 partial_content__ = 206, ///< Section 10.2.7: Partial Content
58 multiple_choices__ = 300, ///< Section 10.3.1: Multiple Choices
59 moved_permanently__ = 301, ///< Section 10.3.2: Moved Permanently
60 found__ = 302, ///< Section 10.3.3: Found
61 see_other__ = 303, ///< Section 10.3.4: See Other
62 not_modified__ = 304, ///< Section 10.3.5: Not Modified
63 use_proxy__ = 305, ///< Section 10.3.6: Use Proxy
64 temporary_redirect__ = 307, ///< Section 10.3.8: Temporary Redirect
65 bad_request__ = 400, ///< Section 10.4.1: Bad Request
66 unauthorized__ = 401, ///< Section 10.4.2: Unauthorized
67 payment_required__ = 402, ///< Section 10.4.3: Payment Required
68 forbidden__ = 403, ///< Section 10.4.4: Forbidden
69 not_found__ = 404, ///< Section 10.4.5: Not Found
70 method_not_allowed__ = 405, ///< Section 10.4.6: Method Not Allowed
71 not_acceptable__ = 406, ///< Section 10.4.7: Not Acceptable
72 proxy_authentication_required__ = 407, ///< Section 10.4.8: Proxy Authentication Required
73 request_time_out__ = 408, ///< Section 10.4.9: Request Time-out
74 conflict__ = 409, ///< Section 10.4.10: Conflict
75 gone__ = 410, ///< Section 10.4.11: Gone
76 length_required__ = 411, ///< Section 10.4.12: Length Required
77 precondition_failed__ = 412, ///< Section 10.4.13: Precondition Failed
78 request_entity_too_large__ = 413, ///< Section 10.4.14: Request Entity Too Large
79 request_uri_too_large__ = 414, ///< Section 10.4.15: Request-URI Too Large
80 unsupported_media_type__ = 415, ///< Section 10.4.16: Unsupported Media Type
81 requested_change_not_satisfiable__ = 416, ///< Section 10.4.17: Requested range not satisfiable
82 expectation_failed__ = 417, ///< Section 10.4.18: Expectation Failed
83 internal_server_error__ = 500, ///< Section 10.5.1: Internal Server Error
84 not_implemented__ = 501, ///< Section 10.5.2: Not Implemented
85 bad_gateway__ = 502, ///< Section 10.5.3: Bad Gateway
86 service_unavailable__ = 503, ///< Section 10.5.4: Service Unavailable
87 gateway_time_out__ = 504, ///< Section 10.5.5: Gateway Time-out
88 http_version_not_supported__ = 505, ///< Section 10.5.6: HTTP Version not supported
89 _upper_bound__ = 506
92 /** Construct an empty response with the given protocol-and-version
93 * (normally the one used for the request, should be HTTP/1.0 or
94 * HTTP/1.1) and the given status code. */
95 Response(const std::string & protocol_and_version, StatusCode status_code);
96 /** Construct an empty response with the given protocol-and-version
97 * (normally the one used for the request, should be HTTP/1.0 or
98 * HTTP/1.1), the given status code and reason string.
99 * You'll normally only need this constructor if the status code is
100 * not standard. In that case, know that 100-base status codes are
101 * for when the server/client connection should change state or there
102 * is something either party should do (such as: continue the query);
103 * 200-base status codes are for when all is OK, 300-base codes are
104 * for when it's OK but not quite what the client may have expected;
105 * 400-base codes are for client-side errors and 500-base codes are
106 * for server-side errors. */
107 Response(const std::string & protocol_and_version, int status_code, const std::string & reason_string);
109 /** Add a header to the response. */
110 void addHeader(const std::string & name, const std::string & value) { header_fields_.push_back(Header(name, value)); }
111 Response & operator()(const std::string & name, const std::string & value) { addHeader(name, value); return *this; }
113 /** Set the body of the response */
114 void setBody(const std::vector< char > & body) { body_ = body; }
115 Response & operator()(const std::vector< char > & body) { setBody(body); return *this; }
116 Response & operator()(const std::string & body) { setBody(std::vector< char >(body.begin(), body.end())); return *this; }
117 Response & operator()(const char * body) { return (*this)(std::string(body)); }
118 template < typename T >
119 Response & operator()(const T & body) { return (*this)(serialize(body)); }
121 std::string protocol_and_version_; ///< the protocol and version of the original request (see Sections 6, 3.1 and 10.5.6)
122 int status_code_; ///< the status code for the response
123 std::string reason_string_; ///< the human-readable equivalent of the status code
124 HeaderFields header_fields_; ///< all header fields found while parsing the request
125 std::vector< char > body_; ///< the body of the request
127 private :
128 static const char * reason_strings__[_upper_bound__];
131 SPIN_API std::vector< char > serialize(const Response & response);
135 #endif