Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save eao197/87a553ad91c2b4d92485124bb6c6fc01 to your computer and use it in GitHub Desktop.
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
#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