pion-net  4.0.9
net/src/HTTPTypes.cpp
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