staticlib_pion  2.0.2
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Friends Macros
http_response.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2015, alex at staticlibs.net
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 // ---------------------------------------------------------------------
18 // pion: a Boost C++ framework for building lightweight HTTP interfaces
19 // ---------------------------------------------------------------------
20 // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion)
21 //
22 // Distributed under the Boost Software License, Version 1.0.
23 // See http://www.boost.org/LICENSE_1_0.txt
24 //
25 
26 #ifndef STATICLIB_PION_HTTP_RESPONSE_HPP
27 #define STATICLIB_PION_HTTP_RESPONSE_HPP
28 
29 #include <memory>
30 
31 #include "staticlib/config.hpp"
32 
36 
37 namespace staticlib {
38 namespace pion {
39 
43 class http_response : public http_message {
44 
48  unsigned int status_code;
49 
53  std::string status_message;
54 
58  std::string request_method;
59 
60 public:
61 
67  http_response(const http_request& http_request_ptr) :
68  status_code(RESPONSE_CODE_OK),
69  status_message(RESPONSE_MESSAGE_OK) {
70  update_request_info(http_request_ptr);
71  }
72 
79  http_message(http_response),
80  status_code(http_response.status_code),
81  status_message(http_response.status_message),
82  request_method(http_response.request_method) { }
83 
87  virtual ~http_response() STATICLIB_NOEXCEPT { }
88 
92  virtual void clear() {
94  status_code = RESPONSE_CODE_OK;
95  status_message = RESPONSE_MESSAGE_OK;
96  request_method.clear();
97  }
98 
104  virtual bool is_content_length_implied() const {
105  return (request_method == REQUEST_METHOD_HEAD // HEAD responses have no content
106  || (status_code >= 100 && status_code <= 199) // 1xx responses have no content
107  || status_code == 204 || status_code == 205 // no content & reset content responses
108  || status_code == 304 // not modified responses have no content
109  );
110  }
111 
119  request_method = http_request.get_method();
120  if (http_request.get_version_major() == 1 && http_request.get_version_minor() >= 1) {
121  set_chunks_supported(true);
122  } else if (http_request.get_version_major() == 0) {
123  // the request is likely HTTP 0.9 "simple-request", so expect the response to contain no header and no version info
124  set_status_code(0U);
125  set_status_message("");
128  }
129  }
130 
136  void set_status_code(unsigned int n) {
137  status_code = n;
139  }
140 
146  void set_status_message(const std::string& msg) {
147  status_message = msg;
149  }
150 
156  unsigned int get_status_code() const {
157  return status_code;
158  }
159 
165  const std::string& get_status_message() const {
166  return status_message;
167  }
168 
174  bool is_body_allowed() const {
175  return REQUEST_METHOD_HEAD != request_method;
176  }
177 
185  void set_cookie(const std::string& name, const std::string& value) {
186  std::string set_cookie_header(make_set_cookie_header(name, value, "/"));
187  add_header(HEADER_SET_COOKIE, set_cookie_header);
188  }
189 
198  void set_cookie(const std::string& name, const std::string& value, const std::string& path) {
199  std::string set_cookie_header(make_set_cookie_header(name, value, path));
200  add_header(HEADER_SET_COOKIE, set_cookie_header);
201  }
202 
211  void set_cookie(const std::string& name, const std::string& value, const std::string& path,
212  const unsigned long max_age) {
213  std::string set_cookie_header(make_set_cookie_header(name, value, path, true, max_age));
214  add_header(HEADER_SET_COOKIE, set_cookie_header);
215  }
216 
224  void set_cookie(const std::string& name, const std::string& value, const unsigned long max_age) {
225  std::string set_cookie_header(make_set_cookie_header(name, value, "/", true, max_age));
226  add_header(HEADER_SET_COOKIE, set_cookie_header);
227  }
228 
234  void delete_cookie(const std::string& name) {
235  std::string set_cookie_header(make_set_cookie_header(name, "", "/", true, 0));
236  add_header(HEADER_SET_COOKIE, set_cookie_header);
237  }
238 
245  void delete_cookie(const std::string& name, const std::string& path) {
246  std::string set_cookie_header(make_set_cookie_header(name, "", path, true, 0));
247  add_header(HEADER_SET_COOKIE, set_cookie_header);
248  }
249 
255  void set_last_modified(const unsigned long t);
256 
257 protected:
258 
262  virtual void update_first_line() const {
263  // start out with the HTTP version
265  m_first_line += ' ';
266  // append the response status code
267  m_first_line += sl::support::to_string(status_code);
268  m_first_line += ' ';
269  // append the response status message
270  m_first_line += status_message;
271  }
272 
276  virtual void append_cookie_headers() {
277  for (std::unordered_multimap<std::string, std::string, algorithm::ihash, algorithm::iequal_to>
278  ::const_iterator i = get_cookies().begin(); i != get_cookies().end(); ++i) {
279  set_cookie(i->first, i->second);
280  }
281  }
282 
283 };
284 
285 } // namespace
286 }
287 
288 #endif // STATICLIB_PION_HTTP_RESPONSE_HPP