pion
5.0.6
|
00001 // --------------------------------------------------------------------- 00002 // pion: a Boost C++ framework for building lightweight HTTP interfaces 00003 // --------------------------------------------------------------------- 00004 // Copyright (C) 2007-2014 Splunk Inc. (https://github.com/splunk/pion) 00005 // 00006 // Distributed under the Boost Software License, Version 1.0. 00007 // See http://www.boost.org/LICENSE_1_0.txt 00008 // 00009 00010 #ifndef __PION_HTTP_RESPONSE_HEADER__ 00011 #define __PION_HTTP_RESPONSE_HEADER__ 00012 00013 #include <boost/shared_ptr.hpp> 00014 #include <boost/lexical_cast.hpp> 00015 #include <pion/config.hpp> 00016 #include <pion/http/message.hpp> 00017 #include <pion/http/request.hpp> 00018 00019 00020 namespace pion { // begin namespace pion 00021 namespace http { // begin namespace http 00022 00023 00027 class response 00028 : public http::message 00029 { 00030 public: 00031 00037 response(const http::request& http_request_ptr) 00038 : m_status_code(RESPONSE_CODE_OK), 00039 m_status_message(RESPONSE_MESSAGE_OK) 00040 { 00041 update_request_info(http_request_ptr); 00042 } 00043 00049 response(const std::string& request_method) 00050 : m_status_code(RESPONSE_CODE_OK), m_status_message(RESPONSE_MESSAGE_OK), 00051 m_request_method(request_method) 00052 {} 00053 00055 response(const response& http_response) 00056 : message(http_response), 00057 m_status_code(http_response.m_status_code), 00058 m_status_message(http_response.m_status_message), 00059 m_request_method(http_response.m_request_method) 00060 {} 00061 00064 response(void) 00065 : m_status_code(RESPONSE_CODE_OK), 00066 m_status_message(RESPONSE_MESSAGE_OK) 00067 {} 00068 00070 virtual ~response() {} 00071 00073 virtual void clear(void) { 00074 http::message::clear(); 00075 m_status_code = RESPONSE_CODE_OK; 00076 m_status_message = RESPONSE_MESSAGE_OK; 00077 m_request_method.clear(); 00078 } 00079 00081 virtual bool is_content_length_implied(void) const { 00082 return (m_request_method == REQUEST_METHOD_HEAD // HEAD responses have no content 00083 || (m_status_code >= 100 && m_status_code <= 199) // 1xx responses have no content 00084 || m_status_code == 204 || m_status_code == 205 // no content & reset content responses 00085 || m_status_code == 304 // not modified responses have no content 00086 ); 00087 } 00088 00095 inline void update_request_info(const http::request& http_request) { 00096 m_request_method = http_request.get_method(); 00097 if (http_request.get_version_major() == 1 && http_request.get_version_minor() >= 1) { 00098 set_chunks_supported(true); 00099 } else if (http_request.get_version_major() == 0) { 00100 // the request is likely HTTP 0.9 "simple-request", so expect the response to contain no header and no version info 00101 set_status_code(0U); 00102 set_status_message(""); 00103 set_version_major(0); 00104 set_version_minor(0); 00105 } 00106 } 00107 00109 inline void set_status_code(unsigned int n) { 00110 m_status_code = n; 00111 clear_first_line(); 00112 } 00113 00115 inline void set_status_message(const std::string& msg) { 00116 m_status_message = msg; 00117 clear_first_line(); 00118 } 00119 00121 inline unsigned int get_status_code(void) const { return m_status_code; } 00122 00124 inline const std::string& get_status_message(void) const { return m_status_message; } 00125 00126 00134 inline void set_cookie(const std::string& name, const std::string& value) { 00135 std::string set_cookie_header(make_set_cookie_header(name, value, "/")); 00136 add_header(HEADER_SET_COOKIE, set_cookie_header); 00137 } 00138 00147 inline void set_cookie(const std::string& name, const std::string& value, 00148 const std::string& path) 00149 { 00150 std::string set_cookie_header(make_set_cookie_header(name, value, path)); 00151 add_header(HEADER_SET_COOKIE, set_cookie_header); 00152 } 00153 00162 inline void set_cookie(const std::string& name, const std::string& value, 00163 const std::string& path, const unsigned long max_age) 00164 { 00165 std::string set_cookie_header(make_set_cookie_header(name, value, path, true, max_age)); 00166 add_header(HEADER_SET_COOKIE, set_cookie_header); 00167 } 00168 00176 inline void set_cookie(const std::string& name, const std::string& value, 00177 const unsigned long max_age) 00178 { 00179 std::string set_cookie_header(make_set_cookie_header(name, value, "/", true, max_age)); 00180 add_header(HEADER_SET_COOKIE, set_cookie_header); 00181 } 00182 00184 inline void delete_cookie(const std::string& name) { 00185 std::string set_cookie_header(make_set_cookie_header(name, "", "/", true, 0)); 00186 add_header(HEADER_SET_COOKIE, set_cookie_header); 00187 } 00188 00190 inline void delete_cookie(const std::string& name, const std::string& path) { 00191 std::string set_cookie_header(make_set_cookie_header(name, "", path, true, 0)); 00192 add_header(HEADER_SET_COOKIE, set_cookie_header); 00193 } 00194 00196 inline void set_last_modified(const unsigned long t) { 00197 change_header(HEADER_LAST_MODIFIED, get_date_string(t)); 00198 } 00199 00200 00201 protected: 00202 00204 virtual void update_first_line(void) const { 00205 // start out with the HTTP version 00206 m_first_line = get_version_string(); 00207 m_first_line += ' '; 00208 // append the response status code 00209 m_first_line += boost::lexical_cast<std::string>(m_status_code); 00210 m_first_line += ' '; 00211 // append the response status message 00212 m_first_line += m_status_message; 00213 } 00214 00216 virtual void append_cookie_headers(void) { 00217 for (ihash_multimap::const_iterator i = get_cookies().begin(); i != get_cookies().end(); ++i) { 00218 set_cookie(i->first, i->second); 00219 } 00220 } 00221 00222 00223 private: 00224 00226 unsigned int m_status_code; 00227 00229 std::string m_status_message; 00230 00232 std::string m_request_method; 00233 }; 00234 00235 00237 typedef boost::shared_ptr<response> response_ptr; 00238 00239 00240 } // end namespace http 00241 } // end namespace pion 00242 00243 #endif