Examples |
Collaboration diagram for http::server::request_handler:
Definition at line 24 of file request_handler.hpp.
Public Member Functions | |
request_handler (const std::string &doc_root) | |
Construct with a directory containing files to be served. | |
void | handle_request (const request &req, reply &rep) |
Handle a request and produce a reply. | |
Static Private Member Functions | |
static bool | url_decode (const std::string &in, std::string &out) |
Perform URL-decoding on a string. Returns false if the encoding was invalid. | |
Private Attributes | |
std::string | doc_root_ |
The directory containing the files to be served. |
http::server::request_handler::request_handler | ( | const std::string & | doc_root | ) | [explicit] |
Construct with a directory containing files to be served.
Definition at line 23 of file request_handler.cpp.
00024 : doc_root_(doc_root) 00025 { 00026 }
Handle a request and produce a reply.
Definition at line 28 of file request_handler.cpp.
Referenced by http::server::connection::handle_read().
00029 { 00030 // Decode url to path. 00031 std::string request_path; 00032 if (!url_decode(req.uri, request_path)) 00033 { 00034 rep = reply::stock_reply(reply::bad_request); 00035 return; 00036 } 00037 00038 // Request path must be absolute and not contain "..". 00039 if (request_path.empty() || request_path[0] != '/' 00040 || request_path.find("..") != std::string::npos) 00041 { 00042 rep = reply::stock_reply(reply::bad_request); 00043 return; 00044 } 00045 00046 // If path ends in slash (i.e. is a directory) then add "index.html". 00047 if (request_path[request_path.size() - 1] == '/') 00048 { 00049 request_path += "index.html"; 00050 } 00051 00052 // Determine the file extension. 00053 std::size_t last_slash_pos = request_path.find_last_of("/"); 00054 std::size_t last_dot_pos = request_path.find_last_of("."); 00055 std::string extension; 00056 if (last_dot_pos != std::string::npos && last_dot_pos > last_slash_pos) 00057 { 00058 extension = request_path.substr(last_dot_pos + 1); 00059 } 00060 00061 // Open the file to send back. 00062 std::string full_path = doc_root_ + "/" + request_path; 00063 std::ifstream is(full_path.c_str(), std::ios::in | std::ios::binary); 00064 if (!is) 00065 { 00066 rep = reply::stock_reply(reply::not_found); 00067 return; 00068 } 00069 00070 // Fill out the reply to be sent to the client. 00071 rep.status = reply::ok; 00072 char buf[512]; 00073 while (is.read(buf, sizeof(buf)).gcount() > 0) 00074 rep.content.append(buf, is.gcount()); 00075 rep.headers.resize(2); 00076 rep.headers[0].name = "Content-Length"; 00077 rep.headers[0].value = boost::lexical_cast<std::string>(rep.content.size()); 00078 rep.headers[1].name = "Content-Type"; 00079 rep.headers[1].value = mime_types::extension_to_type(extension); 00080 }
bool http::server::request_handler::url_decode | ( | const std::string & | in, | |
std::string & | out | |||
) | [static, private] |
Perform URL-decoding on a string. Returns false if the encoding was invalid.
Definition at line 82 of file request_handler.cpp.
Referenced by handle_request().
00083 { 00084 out.clear(); 00085 out.reserve(in.size()); 00086 for (std::size_t i = 0; i < in.size(); ++i) 00087 { 00088 if (in[i] == '%') 00089 { 00090 if (i + 3 <= in.size()) 00091 { 00092 int value; 00093 std::istringstream is(in.substr(i + 1, 2)); 00094 if (is >> std::hex >> value) 00095 { 00096 out += static_cast<char>(value); 00097 i += 2; 00098 } 00099 else 00100 { 00101 return false; 00102 } 00103 } 00104 else 00105 { 00106 return false; 00107 } 00108 } 00109 else 00110 { 00111 out += in[i]; 00112 } 00113 } 00114 return true; 00115 }
std::string http::server::request_handler::doc_root_ [private] |
The directory containing the files to be served.
Definition at line 36 of file request_handler.hpp.
Referenced by handle_request().