1 #ifndef _spin_details_response_h
2 #define _spin_details_response_h
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,
18 * \dontinclude Response.cpp
19 * \skip tryResponseWithHeaders
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
29 * It even allows to to add anything serializable to the response, including
30 * another response (or even the response itself):
31 * \skip tryResponseWithResponse
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
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_
45 struct SPIN_API Response
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
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
128 static const char * reason_strings__
[_upper_bound__
];
131 SPIN_API
std::vector
< char > serialize(const Response
& response
);