![]() |
Home | Libraries | People | FAQ | More |
Collaboration diagram for http::server::request_handler:
Definition at line 14 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 13 of file request_handler.cpp.
00014 : doc_root_(doc_root) 00015 { 00016 }
Handle a request and produce a reply.
Definition at line 18 of file request_handler.cpp.
Referenced by http::server::connection::handle_read().
00019 { 00020 // Decode url to path. 00021 std::string request_path; 00022 if (!url_decode(req.uri, request_path)) 00023 { 00024 rep = reply::stock_reply(reply::bad_request); 00025 return; 00026 } 00027 00028 // Request path must be absolute and not contain "..". 00029 if (request_path.empty() || request_path[0] != '/' 00030 || request_path.find("..") != std::string::npos) 00031 { 00032 rep = reply::stock_reply(reply::bad_request); 00033 return; 00034 } 00035 00036 // If path ends in slash (i.e. is a directory) then add "index.html". 00037 if (request_path[request_path.size() - 1] == '/') 00038 { 00039 request_path += "index.html"; 00040 } 00041 00042 // Determine the file extension. 00043 std::size_t last_slash_pos = request_path.find_last_of("/"); 00044 std::size_t last_dot_pos = request_path.find_last_of("."); 00045 std::string extension; 00046 if (last_dot_pos != std::string::npos && last_dot_pos > last_slash_pos) 00047 { 00048 extension = request_path.substr(last_dot_pos + 1); 00049 } 00050 00051 // Open the file to send back. 00052 std::string full_path = doc_root_ + "/" + request_path; 00053 std::ifstream is(full_path.c_str(), std::ios::in | std::ios::binary); 00054 if (!is) 00055 { 00056 rep = reply::stock_reply(reply::not_found); 00057 return; 00058 } 00059 00060 // Fill out the reply to be sent to the client. 00061 rep.status = reply::ok; 00062 char buf[512]; 00063 while (is.read(buf, sizeof(buf)).gcount() > 0) 00064 rep.content.append(buf, is.gcount()); 00065 rep.headers.resize(2); 00066 rep.headers[0].name = "Content-Length"; 00067 rep.headers[0].value = boost::lexical_cast<std::string>(rep.content.size()); 00068 rep.headers[1].name = "Content-Type"; 00069 rep.headers[1].value = mime_types::extension_to_type(extension); 00070 }
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 72 of file request_handler.cpp.
Referenced by handle_request().
00073 { 00074 out.clear(); 00075 out.reserve(in.size()); 00076 for (std::size_t i = 0; i < in.size(); ++i) 00077 { 00078 if (in[i] == '%') 00079 { 00080 if (i + 3 < in.size()) 00081 { 00082 int value; 00083 std::istringstream is(in.substr(i + 1, 2)); 00084 if (is >> std::hex >> value) 00085 { 00086 out += static_cast<char>(value); 00087 } 00088 else 00089 { 00090 return false; 00091 } 00092 } 00093 else 00094 { 00095 return false; 00096 } 00097 } 00098 else 00099 { 00100 out += in[i]; 00101 } 00102 } 00103 return true; 00104 }
std::string http::server::request_handler::doc_root_ [private] |
The directory containing the files to be served.
Definition at line 26 of file request_handler.hpp.
Referenced by handle_request().
Copyright © 2003 - 2006 Christopher M. Kohlhoff |