From b9a57999d4ed3a08262296ccb9a1a97e6ac7ffbb Mon Sep 17 00:00:00 2001 From: eidheim Date: Sat, 5 Jul 2014 17:55:03 +0200 Subject: [PATCH] Some updates and improved examples and comments --- README.md | 2 +- httpserver.cpp | 26 +++++++++++--------------- main.cpp | 27 +++++++++++++++++++-------- 3 files changed, 31 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index a4878e4..72ad8a8 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ A very simple, fast, multithreaded and platform independent HTTP server implemen * Thread pool * Platform independent * HTTP persistent connection (for HTTP/1.1) -* Simple way to add REST resources using regex for method and path, and anonymous functions +* Simple way to add REST resources using regex for path and anonymous functions ###Usage diff --git a/httpserver.cpp b/httpserver.cpp index 2150fa9..58791c0 100644 --- a/httpserver.cpp +++ b/httpserver.cpp @@ -117,22 +117,18 @@ void HTTPServer::respond(shared_ptr socket, shared_ptr regex e(res.first); smatch sm_res; if(regex_match(request->path, sm_res, e)) { - for(auto& res_path: res.second) { - e=res_path.first; - smatch sm_path; - if(regex_match(request->method, sm_path, e)) { - shared_ptr write_buffer(new boost::asio::streambuf); - ostream response(write_buffer.get()); - res_path.second(response, *request, sm_res); + if(res.second.count(request->method)>0) { + shared_ptr write_buffer(new boost::asio::streambuf); + ostream response(write_buffer.get()); + res.second[request->method](response, *request, sm_res); - //Capture write_buffer in lambda so it is not destroyed before async_write is finished - async_write(*socket, *write_buffer, [this, socket, request, write_buffer](const boost::system::error_code& ec, size_t bytes_transferred) { - //HTTP persistent connection (HTTP 1.1): - if(!ec && stof(request->http_version)>1.05) - process_request_and_respond(socket); - }); - return; - } + //Capture write_buffer in lambda so it is not destroyed before async_write is finished + async_write(*socket, *write_buffer, [this, socket, request, write_buffer](const boost::system::error_code& ec, size_t bytes_transferred) { + //HTTP persistent connection (HTTP 1.1): + if(!ec && stof(request->http_version)>1.05) + process_request_and_respond(socket); + }); + return; } } } diff --git a/main.cpp b/main.cpp index 7e052ab..ebac724 100644 --- a/main.cpp +++ b/main.cpp @@ -10,11 +10,11 @@ using namespace boost::property_tree; int main() { //HTTP-server at port 8080 using 4 threads - HTTPServer httpserver(8080, 1); + HTTPServer httpserver(8080, 4); - //Add resources using regular expressions for path and method + //Add resources using regular expression for path, a method-string and an anonymous function //POST-example for the path /string, responds the posted string - httpserver.resources["^/string/?$"]["^POST$"]=[](ostream& response, const Request& request, const smatch& path_match) { + httpserver.resources["^/string/?$"]["POST"]=[](ostream& response, const Request& request, const smatch& path_match) { //Retrieve string from istream (*request.content) stringstream ss; *request.content >> ss.rdbuf(); @@ -24,14 +24,14 @@ int main() { }; //POST-example for the path /json, responds firstName+" "+lastName from the posted json - //Responds with an appropriate error message if the posted json is not correct, or if firstName or lastName is missing + //Responds with an appropriate error message if the posted json is not valid, or if firstName or lastName is missing //Example posted json: //{ // "firstName": "John", // "lastName": "Smith", // "age": 25 //} - httpserver.resources["^/json/?$"]["^POST$"]=[](ostream& response, const Request& request, const smatch& path_match) { + httpserver.resources["^/json/?$"]["POST"]=[](ostream& response, const Request& request, const smatch& path_match) { ptree pt; try { read_json(*request.content, pt); @@ -46,13 +46,24 @@ int main() { }; //GET-example for the path / - httpserver.resources["^/$"]["^GET$"]=[](ostream& response, const Request& request, const smatch& path_match) { - response << "HTTP/1.1 200 OK\r\nContent-Length: 13\r\n\r\nRoot resource"; + //Responds with request-information + httpserver.resources["^/$"]["GET"]=[](ostream& response, const Request& request, const smatch& path_match) { + stringstream content_stream; + content_stream << "

Request:

"; + content_stream << request.method << " " << request.path << " HTTP/" << request.http_version << "
"; + for(auto& header: request.header) { + content_stream << header.first << ": " << header.second << "
"; + } + + //find length of content_stream (length received using content_stream.tellp()) + content_stream.seekp(0, ios::end); + + response << "HTTP/1.1 200 OK\r\nContent-Length: " << content_stream.tellp() << "\r\n\r\n" << content_stream.rdbuf(); }; //GET-example for the path /match/[number], responds with the matched string in path (number) //For instance a request GET /match/123 will receive: 123 - httpserver.resources["^/match/([0-9]*)/?$"]["^GET$"]=[](ostream& response, const Request& request, const smatch& path_match) { + httpserver.resources["^/match/([0-9]+)/?$"]["GET"]=[](ostream& response, const Request& request, const smatch& path_match) { string number=path_match[1]; response << "HTTP/1.1 200 OK\r\nContent-Length: " << number.length() << "\r\n\r\n" << number; };