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 #include <boost/lexical_cast.hpp> 00011 #include <boost/thread/mutex.hpp> 00012 #include <pion/http/types.hpp> 00013 #include <pion/algorithm.hpp> 00014 #include <cstdio> 00015 #include <ctime> 00016 00017 00018 namespace pion { // begin namespace pion 00019 namespace http { // begin namespace http 00020 00021 00022 // generic strings used by HTTP 00023 const std::string types::STRING_EMPTY; 00024 const std::string types::STRING_CRLF("\x0D\x0A"); 00025 const std::string types::STRING_HTTP_VERSION("HTTP/"); 00026 const std::string types::HEADER_NAME_VALUE_DELIMITER(": "); 00027 const std::string types::COOKIE_NAME_VALUE_DELIMITER("="); 00028 00029 // common HTTP header names 00030 const std::string types::HEADER_HOST("Host"); 00031 const std::string types::HEADER_COOKIE("Cookie"); 00032 const std::string types::HEADER_SET_COOKIE("Set-Cookie"); 00033 const std::string types::HEADER_CONNECTION("Connection"); 00034 const std::string types::HEADER_CONTENT_TYPE("Content-Type"); 00035 const std::string types::HEADER_CONTENT_LENGTH("Content-Length"); 00036 const std::string types::HEADER_CONTENT_LOCATION("Content-Location"); 00037 const std::string types::HEADER_CONTENT_ENCODING("Content-Encoding"); 00038 const std::string types::HEADER_CONTENT_DISPOSITION("Content-Disposition"); 00039 const std::string types::HEADER_LAST_MODIFIED("Last-Modified"); 00040 const std::string types::HEADER_IF_MODIFIED_SINCE("If-Modified-Since"); 00041 const std::string types::HEADER_TRANSFER_ENCODING("Transfer-Encoding"); 00042 const std::string types::HEADER_LOCATION("Location"); 00043 const std::string types::HEADER_AUTHORIZATION("Authorization"); 00044 const std::string types::HEADER_REFERER("Referer"); 00045 const std::string types::HEADER_USER_AGENT("User-Agent"); 00046 const std::string types::HEADER_X_FORWARDED_FOR("X-Forwarded-For"); 00047 const std::string types::HEADER_CLIENT_IP("Client-IP"); 00048 00049 // common HTTP content types 00050 const std::string types::CONTENT_TYPE_HTML("text/html"); 00051 const std::string types::CONTENT_TYPE_TEXT("text/plain"); 00052 const std::string types::CONTENT_TYPE_XML("text/xml"); 00053 const std::string types::CONTENT_TYPE_URLENCODED("application/x-www-form-urlencoded"); 00054 const std::string types::CONTENT_TYPE_MULTIPART_FORM_DATA("multipart/form-data"); 00055 00056 // common HTTP request methods 00057 const std::string types::REQUEST_METHOD_HEAD("HEAD"); 00058 const std::string types::REQUEST_METHOD_GET("GET"); 00059 const std::string types::REQUEST_METHOD_PUT("PUT"); 00060 const std::string types::REQUEST_METHOD_POST("POST"); 00061 const std::string types::REQUEST_METHOD_DELETE("DELETE"); 00062 00063 // common HTTP response messages 00064 const std::string types::RESPONSE_MESSAGE_OK("OK"); 00065 const std::string types::RESPONSE_MESSAGE_CREATED("Created"); 00066 const std::string types::RESPONSE_MESSAGE_ACCEPTED("Accepted"); 00067 const std::string types::RESPONSE_MESSAGE_NO_CONTENT("No Content"); 00068 const std::string types::RESPONSE_MESSAGE_FOUND("Found"); 00069 const std::string types::RESPONSE_MESSAGE_UNAUTHORIZED("Unauthorized"); 00070 const std::string types::RESPONSE_MESSAGE_FORBIDDEN("Forbidden"); 00071 const std::string types::RESPONSE_MESSAGE_NOT_FOUND("Not Found"); 00072 const std::string types::RESPONSE_MESSAGE_METHOD_NOT_ALLOWED("Method Not Allowed"); 00073 const std::string types::RESPONSE_MESSAGE_NOT_MODIFIED("Not Modified"); 00074 const std::string types::RESPONSE_MESSAGE_BAD_REQUEST("Bad Request"); 00075 const std::string types::RESPONSE_MESSAGE_SERVER_ERROR("Server Error"); 00076 const std::string types::RESPONSE_MESSAGE_NOT_IMPLEMENTED("Not Implemented"); 00077 const std::string types::RESPONSE_MESSAGE_CONTINUE("Continue"); 00078 00079 // common HTTP response codes 00080 const unsigned int types::RESPONSE_CODE_OK = 200; 00081 const unsigned int types::RESPONSE_CODE_CREATED = 201; 00082 const unsigned int types::RESPONSE_CODE_ACCEPTED = 202; 00083 const unsigned int types::RESPONSE_CODE_NO_CONTENT = 204; 00084 const unsigned int types::RESPONSE_CODE_FOUND = 302; 00085 const unsigned int types::RESPONSE_CODE_UNAUTHORIZED = 401; 00086 const unsigned int types::RESPONSE_CODE_FORBIDDEN = 403; 00087 const unsigned int types::RESPONSE_CODE_NOT_FOUND = 404; 00088 const unsigned int types::RESPONSE_CODE_METHOD_NOT_ALLOWED = 405; 00089 const unsigned int types::RESPONSE_CODE_NOT_MODIFIED = 304; 00090 const unsigned int types::RESPONSE_CODE_BAD_REQUEST = 400; 00091 const unsigned int types::RESPONSE_CODE_SERVER_ERROR = 500; 00092 const unsigned int types::RESPONSE_CODE_NOT_IMPLEMENTED = 501; 00093 const unsigned int types::RESPONSE_CODE_CONTINUE = 100; 00094 00095 00096 // static member functions 00097 00098 std::string types::get_date_string(const time_t t) 00099 { 00100 // use mutex since time functions are normally not thread-safe 00101 static boost::mutex time_mutex; 00102 static const char *TIME_FORMAT = "%a, %d %b %Y %H:%M:%S GMT"; 00103 static const unsigned int TIME_BUF_SIZE = 100; 00104 char time_buf[TIME_BUF_SIZE+1]; 00105 00106 boost::mutex::scoped_lock time_lock(time_mutex); 00107 if (strftime(time_buf, TIME_BUF_SIZE, TIME_FORMAT, gmtime(&t)) == 0) 00108 time_buf[0] = '\0'; // failed; resulting buffer is indeterminate 00109 time_lock.unlock(); 00110 00111 return std::string(time_buf); 00112 } 00113 00114 std::string types::make_query_string(const ihash_multimap& query_params) 00115 { 00116 std::string query_string; 00117 for (ihash_multimap::const_iterator i = query_params.begin(); i != query_params.end(); ++i) { 00118 if (i != query_params.begin()) 00119 query_string += '&'; 00120 query_string += algorithm::url_encode(i->first); 00121 query_string += '='; 00122 query_string += algorithm::url_encode(i->second); 00123 } 00124 return query_string; 00125 } 00126 00127 std::string types::make_set_cookie_header(const std::string& name, 00128 const std::string& value, 00129 const std::string& path, 00130 const bool has_max_age, 00131 const unsigned long max_age) 00132 { 00133 // note: according to RFC6265, attributes should not be quoted 00134 std::string set_cookie_header(name); 00135 set_cookie_header += "=\""; 00136 set_cookie_header += value; 00137 set_cookie_header += "\"; Version=1"; 00138 if (! path.empty()) { 00139 set_cookie_header += "; Path="; 00140 set_cookie_header += path; 00141 } 00142 if (has_max_age) { 00143 set_cookie_header += "; Max-Age="; 00144 set_cookie_header += boost::lexical_cast<std::string>(max_age); 00145 } 00146 return set_cookie_header; 00147 } 00148 00149 00150 } // end namespace http 00151 } // end namespace pion