Loading...
Searching...
No Matches
message_builders.hpp
Go to the documentation of this file.
/*
restinio
*/
#pragma once
#include <ctime>
#include <chrono>
#include <restinio/impl/include_fmtlib.hpp>
#include <restinio/common_types.hpp>
#include <restinio/http_headers.hpp>
#include <restinio/os.hpp>
#include <restinio/sendfile.hpp>
#include <restinio/impl/connection_base.hpp>
#include <restinio/impl/header_helpers.hpp>
namespace restinio
{
//
// make_date_field_value()
//
inline std::string
make_date_field_value( std::time_t t )
{
const auto tpoint = make_gmtime( t );
std::array< char, 64 > buf;
// TODO: is there a faster way to get time string?
strftime(
buf.data(),
buf.size(),
"%a, %d %b %Y %H:%M:%S GMT",
&tpoint );
return std::string{ buf.data() };
}
inline std::string
make_date_field_value( std::chrono::system_clock::time_point tp )
{
return make_date_field_value( std::chrono::system_clock::to_time_t( tp ) );
}
//
// base_response_builder_t
//
template < typename Response_Builder >
class base_response_builder_t
{
public:
base_response_builder_t( const base_response_builder_t & ) = delete;
base_response_builder_t & operator = ( const base_response_builder_t & ) = delete;
base_response_builder_t( base_response_builder_t && ) noexcept = default;
base_response_builder_t & operator =( base_response_builder_t && ) noexcept = default;
virtual ~base_response_builder_t() = default;
base_response_builder_t(
http_status_line_t status_line,
impl::connection_handle_t connection,
request_id_t request_id,
bool should_keep_alive )
: m_header{ std::move( status_line ) }
, m_connection{ std::move( connection ) }
, m_request_id{ request_id }
{
m_header.should_keep_alive( should_keep_alive );
}
http_response_header_t &
header() noexcept
{
return m_header;
}
const http_response_header_t &
header() const noexcept
{
return m_header;
}
Response_Builder &
append_header(
std::string field_name,
std::string field_value ) &
{
m_header.add_field(
std::move( field_name ),
std::move( field_value ) );
return upcast_reference();
}
Response_Builder &&
append_header(
std::string field_name,
std::string field_value ) &&
{
return std::move( this->append_header(
std::move( field_name ),
std::move( field_value ) ) );
}
Response_Builder &
append_header( http_header_field_t http_header_field ) &
{
m_header.add_field( std::move( http_header_field ) );
return upcast_reference();
}
Response_Builder &&
append_header( http_header_field_t http_header_field ) &&
{
return std::move( this->append_header(
std::move( http_header_field ) ) );
}
Response_Builder &
append_header(
http_field_t field_id,
std::string field_value ) &
{
m_header.add_field(
field_id,
std::move( field_value ) );
return upcast_reference();
}
Response_Builder &&
append_header(
http_field_t field_id,
std::string field_value ) &&
{
return std::move( this->append_header(
field_id,
std::move( field_value ) ) );
}
Response_Builder &
append_header_date_field(
std::chrono::system_clock::time_point tp =
std::chrono::system_clock::now() ) &
{
m_header.set_field( http_field_t::date, make_date_field_value( tp ) );
return upcast_reference();
}
Response_Builder &&
append_header_date_field(
std::chrono::system_clock::time_point tp =
std::chrono::system_clock::now() ) &&
{
return std::move( this->append_header_date_field( tp ) );
}
Response_Builder &
connection_close() & noexcept
{
m_header.should_keep_alive( false );
return upcast_reference();
}
Response_Builder &&
connection_close() && noexcept
{
return std::move( this->connection_close() );
}
Response_Builder &
connection_keep_alive() & noexcept
{
m_header.should_keep_alive();
return upcast_reference();
}
Response_Builder &&
connection_keep_alive() && noexcept
{
return std::move( this->connection_keep_alive() );
}
protected:
std::size_t
calculate_status_line_size() const noexcept
{
// "HTTP/1.1 *** <reason-phrase>"
return 8 + 1 + 3 + 1 + m_header.status_line().reason_phrase().size();
}
http_response_header_t m_header;
impl::connection_handle_t m_connection;
const request_id_t m_request_id;
void
throw_done_must_be_called_once() const
{
throw exception_t{ "done() cannot be called twice" };
}
private:
Response_Builder &
upcast_reference() noexcept
{
return static_cast< Response_Builder & >( *this );
}
};
//
// response_builder_t
//
template < typename Response_Output_Strategy >
class response_builder_t
{
response_builder_t() = delete;
};
struct restinio_controlled_output_t {};
template <>
class response_builder_t< restinio_controlled_output_t > final
: public base_response_builder_t< response_builder_t< restinio_controlled_output_t > >
{
public:
using base_type_t =
base_response_builder_t< response_builder_t< restinio_controlled_output_t > >;
using self_type_t =
response_builder_t< restinio_controlled_output_t >;
response_builder_t( response_builder_t && ) = default;
// Reuse construstors from base.
using base_type_t::base_type_t;
self_type_t &
set_body( writable_item_t body ) &
{
auto size = body.size();
return set_body_impl( body, size );
}
self_type_t &&
set_body( writable_item_t body ) &&
{
return std::move( this->set_body( std::move( body ) ) );
}
self_type_t &
append_body( writable_item_t body_part ) &
{
auto size = body_part.size();
return append_body_impl( body_part, size );
}
self_type_t &&
append_body( writable_item_t body_part ) &&
{
return std::move( this->append_body( std::move( body_part ) ) );
}
request_handling_status_t
done( write_status_cb_t wscb = write_status_cb_t{} )
{
if( m_connection )
{
const response_output_flags_t
response_output_flags{
response_parts_attr_t::final_parts,
response_connection_attr( m_header.should_keep_alive() ) };
m_header.content_length( m_body_size );
if_neccessary_reserve_first_element_for_header();
m_response_parts[ 0 ] =
writable_item_t{ impl::create_header_string( m_header ) };
write_group_t wg{ std::move( m_response_parts ) };
wg.status_line_size( calculate_status_line_size() );
if( wscb )
{
wg.after_write_notificator( std::move( wscb ) );
}
auto conn = std::move( m_connection );
conn->write_response_parts(
m_request_id,
response_output_flags,
std::move( wg ) );
}
else
{
throw_done_must_be_called_once();
}
return restinio::request_accepted();
}
private:
self_type_t &
set_body_impl( writable_item_t & body, std::size_t body_size )
{
if_neccessary_reserve_first_element_for_header();
// Leave only buf that is reserved for header,
// so forget all the previous data.
m_response_parts.resize( 1 );
if( 0 < body_size )
{
m_response_parts.emplace_back( std::move( body ) );
}
m_body_size = body_size;
return *this;
}
self_type_t &
append_body_impl( writable_item_t & body_part, std::size_t append_size )
{
if_neccessary_reserve_first_element_for_header();
if( 0 < append_size )
{
m_response_parts.emplace_back( std::move( body_part ) );
m_body_size += append_size;
}
return *this;
}
void
if_neccessary_reserve_first_element_for_header()
{
if( m_response_parts.empty() )
{
m_response_parts.reserve( 2 );
m_response_parts.emplace_back();
}
}
std::size_t m_body_size{ 0 };
writable_items_container_t m_response_parts;
};
struct user_controlled_output_t {};
template <>
class response_builder_t< user_controlled_output_t > final
: public base_response_builder_t< response_builder_t< user_controlled_output_t > >
{
public:
using base_type_t =
base_response_builder_t< response_builder_t< user_controlled_output_t > >;
using self_type_t =
response_builder_t< user_controlled_output_t >;
response_builder_t( response_builder_t && ) = default;
// Reuse construstors from base.
using base_type_t::base_type_t;
self_type_t &
set_content_length( std::size_t content_length ) &
{
m_header.content_length( content_length );
return *this;
}
self_type_t &&
set_content_length( std::size_t content_length ) &&
{
return std::move( this->set_content_length( content_length ) );
}
self_type_t &
set_body( writable_item_t body ) &
{
auto size = body.size();
return set_body_impl( body, size );
}
self_type_t &&
set_body( writable_item_t body ) &&
{
return std::move( this->set_body( std::move( body ) ) );
}
self_type_t &
append_body( writable_item_t body_part ) &
{
auto size = body_part.size();
if( 0 == size )
return *this;
return append_body_impl( body_part );
}
self_type_t &&
append_body( writable_item_t body_part ) &&
{
return std::move( this->append_body( std::move( body_part ) ) );
}
self_type_t &
flush( write_status_cb_t wscb = write_status_cb_t{} ) &
{
if( m_connection )
{
send_ready_data(
m_connection,
response_parts_attr_t::not_final_parts,
std::move( wscb ) );
}
return *this;
}
self_type_t &&
flush( write_status_cb_t wscb = write_status_cb_t{} ) &&
{
return std::move( this->flush( std::move( wscb ) ) );
}
request_handling_status_t
done( write_status_cb_t wscb = write_status_cb_t{} )
{
if( m_connection )
{
// Note: m_connection should become empty after return
// from that method.
impl::connection_handle_t old_conn_handle{
std::move(m_connection) };
send_ready_data(
old_conn_handle,
response_parts_attr_t::final_parts,
std::move( wscb ) );
}
else
{
throw_done_must_be_called_once();
}
return restinio::request_accepted();
}
private:
void
send_ready_data(
const impl::connection_handle_t & conn,
response_parts_attr_t response_parts_attr,
write_status_cb_t wscb )
{
std::size_t status_line_size{ 0 };
if( !m_header_was_sent )
{
m_should_keep_alive_when_header_was_sent =
m_header.should_keep_alive();
if_neccessary_reserve_first_element_for_header();
m_response_parts[ 0 ] =
writable_item_t{ impl::create_header_string( m_header ) };
m_header_was_sent = true;
status_line_size = calculate_status_line_size();
}
if( !m_response_parts.empty() ||
wscb ||
response_parts_attr_t::final_parts == response_parts_attr )
{
const response_output_flags_t
response_output_flags{
response_parts_attr,
response_connection_attr( m_should_keep_alive_when_header_was_sent ) };
write_group_t wg{ std::move( m_response_parts ) };
wg.status_line_size( status_line_size );
if( wscb )
{
wg.after_write_notificator( std::move( wscb ) );
}
conn->write_response_parts(
m_request_id,
response_output_flags,
std::move( wg ) );
}
}
self_type_t &
set_body_impl( writable_item_t & body, std::size_t body_size )
{
if_neccessary_reserve_first_element_for_header();
// Leave only buf that is reserved for header,
// so forget all the previous data.
if( !m_header_was_sent )
m_response_parts.resize( 1 );
else
m_response_parts.resize( 0 );
if( 0 < body_size )
{
// if body is not empty:
m_response_parts.emplace_back( std::move( body ) );
}
return *this;
}
self_type_t &
append_body_impl( writable_item_t & body_part )
{
if_neccessary_reserve_first_element_for_header();
m_response_parts.emplace_back( std::move( body_part ) );
return *this;
}
void
if_neccessary_reserve_first_element_for_header()
{
if( !m_header_was_sent && m_response_parts.empty() )
{
m_response_parts.reserve( 2 );
m_response_parts.emplace_back();
}
}
bool m_header_was_sent{ false };
bool m_should_keep_alive_when_header_was_sent{ true };
writable_items_container_t m_response_parts;
};
struct chunked_output_t {};
template <>
class response_builder_t< chunked_output_t > final
: public base_response_builder_t< response_builder_t< chunked_output_t > >
{
public:
using base_type_t =
base_response_builder_t< response_builder_t< chunked_output_t > >;
using self_type_t =
response_builder_t< chunked_output_t >;
response_builder_t(
http_status_line_t status_line,
impl::connection_handle_t connection,
request_id_t request_id,
bool should_keep_alive )
: base_type_t{
std::move( status_line ),
std::move( connection ),
request_id,
should_keep_alive }
{
m_chunks.reserve( 4 );
}
response_builder_t( response_builder_t && ) = default;
self_type_t &
append_chunk( writable_item_t chunk ) &
{
auto size = chunk.size();
if( 0 != size )
m_chunks.emplace_back( std::move( chunk ) );
return *this;
}
self_type_t &&
append_chunk( writable_item_t chunk ) &&
{
return std::move( this->append_chunk( std::move( chunk ) ) );
}
self_type_t &
flush( write_status_cb_t wscb = write_status_cb_t{} ) &
{
if( m_connection )
{
send_ready_data(
m_connection,
response_parts_attr_t::not_final_parts,
std::move( wscb ) );
}
return *this;
}
self_type_t &&
flush( write_status_cb_t wscb = write_status_cb_t{} ) &&
{
return std::move( this->flush( std::move( wscb ) ) );
}
request_handling_status_t
done( write_status_cb_t wscb = write_status_cb_t{} )
{
if( m_connection )
{
// Note: m_connection should become empty after return
// from that method.
impl::connection_handle_t old_conn_handle{
std::move(m_connection) };
send_ready_data(
old_conn_handle,
response_parts_attr_t::final_parts,
std::move( wscb ) );
}
else
{
throw_done_must_be_called_once();
}
return restinio::request_accepted();
}
private:
void
send_ready_data(
const impl::connection_handle_t & conn,
response_parts_attr_t response_parts_attr,
write_status_cb_t wscb )
{
std::size_t status_line_size{ 0 };
if( !m_header_was_sent )
{
status_line_size = calculate_status_line_size();
prepare_header_for_sending();
}
auto bufs = create_bufs( response_parts_attr_t::final_parts == response_parts_attr );
m_header_was_sent = true;
const response_output_flags_t
response_output_flags{
response_parts_attr,
response_connection_attr( m_should_keep_alive_when_header_was_sent ) };
// We have buffers or at least we have after-write notificator.
if( !bufs.empty() || wscb )
{
write_group_t wg{ std::move( bufs ) };
wg.status_line_size( status_line_size );
if( wscb )
{
wg.after_write_notificator( std::move( wscb ) );
}
conn->write_response_parts(
m_request_id,
response_output_flags,
std::move( wg ) );
}
}
void
prepare_header_for_sending()
{
m_should_keep_alive_when_header_was_sent =
m_header.should_keep_alive();
constexpr const char value[] = "chunked";
if( !m_header.has_field( restinio::http_field::transfer_encoding ) )
{
m_header.add_field(
restinio::http_field::transfer_encoding,
std::string{ value, impl::ct_string_len( value ) } );
}
else
{
auto & current_value =
m_header.get_field( restinio::http_field::transfer_encoding );
if( std::string::npos == current_value.find( value ) )
{
constexpr const char comma_value[] = ",chunked";
m_header.append_field(
restinio::http_field::transfer_encoding,
std::string{
comma_value,
impl::ct_string_len( comma_value ) } );
}
}
}
writable_items_container_t
create_bufs( bool add_zero_chunk )
{
writable_items_container_t bufs;
std::size_t reserve_size = 2 * m_chunks.size() + 1;
if( !m_header_was_sent )
{
++reserve_size;
}
if( add_zero_chunk )
{
++reserve_size;
}
bufs.reserve( reserve_size );
if( !m_header_was_sent )
{
bufs.emplace_back(
impl::create_header_string(
m_header,
impl::content_length_field_presence_t::skip_content_length ) );
}
// Since fmtlib-8.0.0 compile-time checks of format strings
// is enabled by default. If non-constexpr string has to be
// passed as format_string then fmt::runtime() function should
// be used. But there are some drawbacks:
// - fmt::runtime is added only in fmtlib-8.0.0, there is no
// such a function in previous versions of fmtlib;
// - using fmt::runtime we lack a possibility to check
// format_string in compile-time and can have some performance
// penalty in run-time.
//
// Because of that, the following code was rewritten to have different
// code fragments for the first item in m_chunks and all successive
// items.
auto chunk_it = m_chunks.begin();
const auto chunk_end = m_chunks.end();
if( chunk_it != chunk_end )
{
bufs.emplace_back(
fmt::format(
RESTINIO_FMT_FORMAT_STRING( "{:X}\r\n" ),
asio_ns::buffer_size( chunk_it->buf() ) ) );
bufs.emplace_back( std::move( *chunk_it ) );
for( ++chunk_it; chunk_it != chunk_end; ++chunk_it )
{
bufs.emplace_back(
fmt::format(
RESTINIO_FMT_FORMAT_STRING( "\r\n{:X}\r\n" ),
asio_ns::buffer_size( chunk_it->buf() ) ) );
bufs.emplace_back( std::move( *chunk_it ) );
}
}
const char * const ending_representation = "\r\n" "0\r\n\r\n";
const char * appendix_begin = ending_representation + 2;
const char * appendix_end = appendix_begin;
if( !m_chunks.empty() )
{
// Add "\r\n"part to appendix.
appendix_begin -= 2;
// bufs.emplace_back( const_buffer( rn_ending, 2 ) );
}
if( add_zero_chunk )
{
// Add "0\r\n\r\n"part to appendix.
appendix_end += 5;
}
if( appendix_begin != appendix_end )
{
bufs.emplace_back( const_buffer(
appendix_begin,
static_cast<std::size_t>(appendix_end - appendix_begin)
) );
}
m_chunks.clear();
return bufs;
}
bool m_header_was_sent{ false };
bool m_should_keep_alive_when_header_was_sent{ true };
writable_items_container_t m_chunks;
};
} /* namespace restinio */
restinio::base_response_builder_t
Definition: message_builders.hpp:60
restinio::base_response_builder_t::upcast_reference
Response_Builder & upcast_reference() noexcept
Definition: message_builders.hpp:230
restinio::base_response_builder_t::append_header
Response_Builder && append_header(http_field_t field_id, std::string field_value) &&
Add header field.
Definition: message_builders.hpp:150
restinio::base_response_builder_t::append_header
Response_Builder && append_header(http_header_field_t http_header_field) &&
Add header field.
Definition: message_builders.hpp:130
restinio::base_response_builder_t::m_connection
impl::connection_handle_t m_connection
Definition: message_builders.hpp:219
restinio::base_response_builder_t::append_header
Response_Builder && append_header(std::string field_name, std::string field_value) &&
Add header field.
Definition: message_builders.hpp:111
restinio::base_response_builder_t::append_header
Response_Builder & append_header(std::string field_name, std::string field_value) &
Add header field.
Definition: message_builders.hpp:99
restinio::base_response_builder_t::connection_close
Response_Builder & connection_close() &noexcept
Set connection close.
Definition: message_builders.hpp:181
restinio::base_response_builder_t::calculate_status_line_size
std::size_t calculate_status_line_size() const noexcept
Definition: message_builders.hpp:211
restinio::base_response_builder_t::base_response_builder_t
base_response_builder_t(base_response_builder_t &&) noexcept=default
restinio::base_response_builder_t::append_header
Response_Builder & append_header(http_header_field_t http_header_field) &
Add header field.
Definition: message_builders.hpp:122
restinio::base_response_builder_t::append_header
Response_Builder & append_header(http_field_t field_id, std::string field_value) &
Add header field.
Definition: message_builders.hpp:138
restinio::base_response_builder_t::connection_keep_alive
Response_Builder & connection_keep_alive() &noexcept
Set connection keep-alive.
Definition: message_builders.hpp:197
restinio::base_response_builder_t::header
const http_response_header_t & header() const noexcept
Definition: message_builders.hpp:91
restinio::base_response_builder_t::append_header_date_field
Response_Builder & append_header_date_field(std::chrono::system_clock::time_point tp=std::chrono::system_clock::now()) &
Add header Date field.
Definition: message_builders.hpp:162
restinio::base_response_builder_t::m_request_id
const request_id_t m_request_id
Definition: message_builders.hpp:220
restinio::base_response_builder_t::append_header_date_field
Response_Builder && append_header_date_field(std::chrono::system_clock::time_point tp=std::chrono::system_clock::now()) &&
Add header Date field.
Definition: message_builders.hpp:172
restinio::base_response_builder_t::operator=
base_response_builder_t & operator=(const base_response_builder_t &)=delete
restinio::base_response_builder_t::base_response_builder_t
base_response_builder_t(const base_response_builder_t &)=delete
restinio::base_response_builder_t::header
http_response_header_t & header() noexcept
Accessors for header.
Definition: message_builders.hpp:85
restinio::base_response_builder_t::connection_close
Response_Builder && connection_close() &&noexcept
Set connection close.
Definition: message_builders.hpp:189
restinio::base_response_builder_t::connection_keep_alive
Response_Builder && connection_keep_alive() &&noexcept
Definition: message_builders.hpp:204
restinio::base_response_builder_t::m_header
http_response_header_t m_header
Definition: message_builders.hpp:217
restinio::base_response_builder_t::throw_done_must_be_called_once
void throw_done_must_be_called_once() const
Definition: message_builders.hpp:223
restinio::exception_t
Exception class for all exceptions thrown by RESTinio.
Definition: exception.hpp:26
restinio::http_header_field_t
A single header field.
Definition: http_headers.hpp:583
restinio::http_header_fields_t::add_field
void add_field(http_field_t field_id, std::string field_value)
Add a field in the form of id-value pair.
Definition: http_headers.hpp:860
restinio::http_header_fields_t::set_field
void set_field(http_header_field_t http_header_field)
Set header field via http_header_field_t.
Definition: http_headers.hpp:773
restinio::http_status_line_t
HTTP response header status line.
Definition: http_headers.hpp:2125
restinio::http_status_line_t::reason_phrase
const std::string & reason_phrase() const noexcept
Definition: http_headers.hpp:2146
restinio::response_builder_t< chunked_output_t >
Chunked transfer encoding output builder.
Definition: message_builders.hpp:632
restinio::response_builder_t< chunked_output_t >::flush
self_type_t & flush(write_status_cb_t wscb=write_status_cb_t{}) &
Flush ready outgoing data.
Definition: message_builders.hpp:679
restinio::response_builder_t< chunked_output_t >::flush
self_type_t && flush(write_status_cb_t wscb=write_status_cb_t{}) &&
Flush ready outgoing data.
Definition: message_builders.hpp:694
restinio::response_builder_t< chunked_output_t >::m_chunks
writable_items_container_t m_chunks
Chunks accumulator.
Definition: message_builders.hpp:893
restinio::response_builder_t< chunked_output_t >::create_bufs
writable_items_container_t create_bufs(bool add_zero_chunk)
Definition: message_builders.hpp:792
restinio::response_builder_t< chunked_output_t >::send_ready_data
void send_ready_data(const impl::connection_handle_t &conn, response_parts_attr_t response_parts_attr, write_status_cb_t wscb)
Definition: message_builders.hpp:724
restinio::response_builder_t< chunked_output_t >::response_builder_t
response_builder_t(response_builder_t &&)=default
restinio::response_builder_t< chunked_output_t >::prepare_header_for_sending
void prepare_header_for_sending()
Definition: message_builders.hpp:763
restinio::response_builder_t< chunked_output_t >::append_chunk
self_type_t && append_chunk(writable_item_t chunk) &&
Append current chunk.
Definition: message_builders.hpp:669
restinio::response_builder_t< chunked_output_t >::append_chunk
self_type_t & append_chunk(writable_item_t chunk) &
Append current chunk.
Definition: message_builders.hpp:657
restinio::response_builder_t< chunked_output_t >::done
request_handling_status_t done(write_status_cb_t wscb=write_status_cb_t{})
Complete response.
Definition: message_builders.hpp:701
restinio::response_builder_t< chunked_output_t >::response_builder_t
response_builder_t(http_status_line_t status_line, impl::connection_handle_t connection, request_id_t request_id, bool should_keep_alive)
Definition: message_builders.hpp:639
restinio::response_builder_t< restinio_controlled_output_t >
Simple standard response builder.
Definition: message_builders.hpp:260
restinio::response_builder_t< restinio_controlled_output_t >::append_body_impl
self_type_t & append_body_impl(writable_item_t &body_part, std::size_t append_size)
Definition: message_builders.hpp:364
restinio::response_builder_t< restinio_controlled_output_t >::m_response_parts
writable_items_container_t m_response_parts
Definition: message_builders.hpp:388
restinio::response_builder_t< restinio_controlled_output_t >::append_body
self_type_t && append_body(writable_item_t body_part) &&
Append body.
Definition: message_builders.hpp:297
restinio::response_builder_t< restinio_controlled_output_t >::append_body
self_type_t & append_body(writable_item_t body_part) &
Append body.
Definition: message_builders.hpp:289
restinio::response_builder_t< restinio_controlled_output_t >::if_neccessary_reserve_first_element_for_header
void if_neccessary_reserve_first_element_for_header()
Definition: message_builders.hpp:378
restinio::response_builder_t< restinio_controlled_output_t >::response_builder_t
response_builder_t(response_builder_t &&)=default
restinio::response_builder_t< restinio_controlled_output_t >::done
request_handling_status_t done(write_status_cb_t wscb=write_status_cb_t{})
Complete response.
Definition: message_builders.hpp:304
restinio::response_builder_t< restinio_controlled_output_t >::set_body
self_type_t && set_body(writable_item_t body) &&
Set body.
Definition: message_builders.hpp:282
restinio::response_builder_t< restinio_controlled_output_t >::set_body_impl
self_type_t & set_body_impl(writable_item_t &body, std::size_t body_size)
Definition: message_builders.hpp:345
restinio::response_builder_t< restinio_controlled_output_t >::set_body
self_type_t & set_body(writable_item_t body) &
Set body.
Definition: message_builders.hpp:274
restinio::response_builder_t< user_controlled_output_t >
User controlled response output builder.
Definition: message_builders.hpp:404
restinio::response_builder_t< user_controlled_output_t >::flush
self_type_t & flush(write_status_cb_t wscb=write_status_cb_t{}) &
Flush ready outgoing data.
Definition: message_builders.hpp:470
restinio::response_builder_t< user_controlled_output_t >::m_response_parts
writable_items_container_t m_response_parts
Body accumulator.
Definition: message_builders.hpp:618
restinio::response_builder_t< user_controlled_output_t >::append_body_impl
self_type_t & append_body_impl(writable_item_t &body_part)
Definition: message_builders.hpp:582
restinio::response_builder_t< user_controlled_output_t >::set_body
self_type_t & set_body(writable_item_t body) &
Set body (part).
Definition: message_builders.hpp:433
restinio::response_builder_t< user_controlled_output_t >::response_builder_t
response_builder_t(response_builder_t &&)=default
restinio::response_builder_t< user_controlled_output_t >::send_ready_data
void send_ready_data(const impl::connection_handle_t &conn, response_parts_attr_t response_parts_attr, write_status_cb_t wscb)
Definition: message_builders.hpp:515
restinio::response_builder_t< user_controlled_output_t >::set_content_length
self_type_t & set_content_length(std::size_t content_length) &
Manualy set content length.
Definition: message_builders.hpp:418
restinio::response_builder_t< user_controlled_output_t >::set_content_length
self_type_t && set_content_length(std::size_t content_length) &&
Manualy set content length.
Definition: message_builders.hpp:426
restinio::response_builder_t< user_controlled_output_t >::set_body
self_type_t && set_body(writable_item_t body) &&
Set body (part).
Definition: message_builders.hpp:441
restinio::response_builder_t< user_controlled_output_t >::flush
self_type_t && flush(write_status_cb_t wscb=write_status_cb_t{}) &&
Flush ready outgoing data.
Definition: message_builders.hpp:485
restinio::response_builder_t< user_controlled_output_t >::done
request_handling_status_t done(write_status_cb_t wscb=write_status_cb_t{})
Complete response.
Definition: message_builders.hpp:492
restinio::response_builder_t< user_controlled_output_t >::set_body_impl
self_type_t & set_body_impl(writable_item_t &body, std::size_t body_size)
Definition: message_builders.hpp:561
restinio::response_builder_t< user_controlled_output_t >::if_neccessary_reserve_first_element_for_header
void if_neccessary_reserve_first_element_for_header()
Definition: message_builders.hpp:591
restinio::response_builder_t< user_controlled_output_t >::append_body
self_type_t && append_body(writable_item_t body_part) &&
Append body.
Definition: message_builders.hpp:460
restinio::response_builder_t< user_controlled_output_t >::append_body
self_type_t & append_body(writable_item_t body_part) &
Append body.
Definition: message_builders.hpp:448
restinio::response_builder_t
Forbid arbitrary response_builder_t instantiations.
Definition: message_builders.hpp:243
restinio::response_builder_t::response_builder_t
response_builder_t()=delete
restinio::writable_item_t
Class for storing the buffers used for streaming body (request/response).
Definition: buffers.hpp:526
restinio::write_group_t
Group of writable items transported to the context of underlying connection as one solid piece.
Definition: buffers.hpp:729
restinio::write_group_t::status_line_size
void status_line_size(std::size_t n)
Definition: buffers.hpp:800
common_types.hpp
connection_base.hpp
header_helpers.hpp
http_headers.hpp
include_fmtlib.hpp
A special wrapper around fmtlib include files.
RESTINIO_FMT_FORMAT_STRING
#define RESTINIO_FMT_FORMAT_STRING(s)
Definition: include_fmtlib.hpp:92
restinio::impl::create_header_string
std::string create_header_string(const http_response_header_t &h, content_length_field_presence_t content_length_field_presence=content_length_field_presence_t::add_content_length, std::size_t buffer_size=0)
Creates a string for http response header.
Definition: header_helpers.hpp:68
restinio::impl::connection_handle_t
std::shared_ptr< connection_base_t > connection_handle_t
Alias for http connection handle.
Definition: connection_base.hpp:47
restinio::impl::content_length_field_presence_t::skip_content_length
@ skip_content_length
restinio::impl::ct_string_len
constexpr std::size_t ct_string_len(const char(&)[N]) noexcept
Compile time c-string length.
Definition: header_helpers.hpp:28
restinio
Definition: asio_include.hpp:21
restinio::writable_items_container_t
std::vector< writable_item_t > writable_items_container_t
Definition: buffers.hpp:705
restinio::request_id_t
unsigned int request_id_t
Request id in scope of single connection.
Definition: common_types.hpp:70
restinio::response_connection_attr
response_connection_attr_t response_connection_attr(bool should_keep_alive)
Definition: common_types.hpp:113
restinio::request_handling_status_t
request_handling_status_t
Request handling status.
Definition: common_types.hpp:26
restinio::http_field_t
http_field_t
C++ enum that repeats nodejs c-style enum.
Definition: http_headers.hpp:233
restinio::write_status_cb_t
std::function< void(const asio_ns::error_code &ec) > write_status_cb_t
An alias for a callback to be invoked after the write operation of a particular group of "buffers".
Definition: buffers.hpp:717
restinio::make_date_field_value
std::string make_date_field_value(std::time_t t)
Format a timepoint to a string of a propper format.
Definition: message_builders.hpp:33
restinio::const_buffer
constexpr const_buffer_t const_buffer(const void *str, std::size_t size) noexcept
Definition: buffers.hpp:424
restinio::response_connection_attr_t::connection_close
@ connection_close
This response says to close connection.
restinio::request_accepted
RESTINIO_NODISCARD constexpr request_handling_status_t request_accepted() noexcept
Definition: common_types.hpp:46
restinio::response_parts_attr_t
response_parts_attr_t
Attribute for parts.
Definition: common_types.hpp:74
restinio::response_parts_attr_t::final_parts
@ final_parts
Final parts (response ands with these parts).
restinio::response_parts_attr_t::not_final_parts
@ not_final_parts
Intermediate parts (more parts of response to follow).
std
STL namespace.
os.hpp
make_gmtime
std::tm make_gmtime(std::time_t t)
Definition: os_posix.ipp:2
sendfile.hpp
restinio::chunked_output_t
Tag type for chunked output response builder.
Definition: message_builders.hpp:622
restinio::http_header_common_t::should_keep_alive
bool should_keep_alive() const noexcept
Definition: http_headers.hpp:1612
restinio::http_response_header_t
Resp header.
Definition: http_headers.hpp:2339
restinio::http_response_header_t::status_line
const http_status_line_t & status_line() const noexcept
Definition: http_headers.hpp:2365
restinio::response_output_flags_t
Response output flags for buffers commited to response-coordinator.
Definition: common_types.hpp:123
restinio::restinio_controlled_output_t
Tag type for RESTinio controlled output response builder.
Definition: message_builders.hpp:248
restinio::user_controlled_output_t
Tag type for user controlled output response builder.
Definition: message_builders.hpp:392
const
#define const
Definition: zconf.h:230