Created
April 10, 2020 08:49
-
-
Save eao197/87a553ad91c2b4d92485124bb6c6fc01 to your computer and use it in GitHub Desktop.
An example of handling POST body with x-www-form-urlencoded content type in RESTinio 0.6.5
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <restinio/all.hpp> | |
#include <restinio/helpers/http_field_parsers/content-type.hpp> | |
#include <fmt/format.h> | |
using router_t = restinio::router::express_router_t<>; | |
auto handle_post_body( | |
const restinio::request_handle_t & req ) | |
{ | |
fmt::basic_memory_buffer< char, 1u > response_body; | |
fmt::format_to( response_body, "POST request to '{}'\n", | |
req->header().request_target() ); | |
// Request header fields. | |
fmt::format_to( response_body, "HTTP-fields ({}):\n", | |
req->header().fields_count() ); | |
for( const auto & f : req->header() ) | |
{ | |
fmt::format_to( response_body, "{}: {}\n", | |
f.name(), f.value() ); | |
} | |
// Content-Type header file should be present. | |
const auto content_type = req->header().opt_value_of( | |
restinio::http_field::content_type ); | |
if( content_type ) | |
{ | |
// Parse Content-Type header to get a media-type from it. | |
const auto content_type_value = restinio::http_field_parsers:: | |
content_type_value_t::try_parse( *content_type ); | |
if( content_type_value ) | |
{ | |
// We can handle only "application/x-www-form-urlencoded" content. | |
if( "application" == content_type_value->media_type.type && | |
"x-www-form-urlencoded" == content_type_value->media_type.subtype ) | |
{ | |
// Split the body into key=value pairs. | |
const auto parsed_body = restinio::parse_query< | |
restinio::parse_query_traits::x_www_form_urlencoded | |
>( req->body() ); | |
fmt::format_to( response_body, "\nDATA FROM BODY:\n" ); | |
for( const auto p : parsed_body ) | |
{ | |
fmt::format_to( response_body, "'{}' => '{}'\n", | |
p.first, p.second ); | |
} | |
} | |
else | |
fmt::format_to( response_body, "\nUNSUPPORTED Content-Type:\n" | |
"\ntype={}, subtype={}\n", | |
content_type_value->media_type.type, | |
content_type_value->media_type.subtype ); | |
} | |
else | |
fmt::format_to( response_body, "\nERROR PARSING Content-Type:\n{}\n", | |
restinio::easy_parser::make_error_description( | |
content_type_value.error(), | |
*content_type ) ); | |
} | |
else | |
fmt::format_to( response_body, "\nUNABLE TO HANDLE BODY!\n" | |
"content-type header is not found\n" ); | |
return req->create_response() | |
.append_header( restinio::http_field::server, "RESTinio server" ) | |
.append_header_date_field() | |
.append_header( restinio::http_field::content_type, "text/plain; charset=utf-8" ) | |
.set_body( std::move(response_body) ) | |
.done(); | |
} | |
auto make_router() | |
{ | |
auto router = std::make_unique< router_t >(); | |
router->http_get( | |
"/", | |
[ & ]( const restinio::request_handle_t& req, auto ){ | |
const auto action_url = std::string{ "http://localhost:8080/" }; | |
auto resp = req->create_response(); | |
resp.append_header( "Server", "RESTinio" ); | |
resp.append_header_date_field(); | |
resp.append_header( | |
restinio::http_field::content_type, | |
"text/html; charset=utf-8" ); | |
resp.set_body( | |
R"---( | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="UTF-8"> | |
<title>File Upload!</title> | |
</head> | |
<body> | |
<p>Please select file to be uploaded to server.</p> | |
<form method="post" action=")---" + action_url + R"---("> | |
<p><input type="text" name="one" id="one-id" value=""></p> | |
<p><input type="text" name="second" id="second-id"></p> | |
<p><input type="text" name="third" id="third-id"></p> | |
<p><button type="submit">Submit</button></p> | |
</form> | |
</body> | |
</html> | |
)---" ); | |
return resp.done(); | |
} ); | |
router->http_post( "/", | |
[&]( const auto & req, const auto & ) | |
{ | |
return handle_post_body( req ); | |
} ); | |
return router; | |
} | |
int main() | |
{ | |
try | |
{ | |
using traits_t = | |
restinio::traits_t< | |
restinio::asio_timer_manager_t, | |
restinio::shared_ostream_logger_t, | |
router_t >; | |
restinio::run( | |
restinio::on_thread_pool< traits_t >( | |
std::thread::hardware_concurrency() ) | |
.port( 8080 ) | |
.address( "localhost" ) | |
.request_handler( make_router() ) ); | |
} | |
catch( const std::exception & ex ) | |
{ | |
std::cerr << "Error: " << ex.what() << std::endl; | |
return 1; | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment