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