13 #include <restinio/impl/include_fmtlib.hpp> 15 #include <restinio/impl/string_caseless_compare.hpp> 17 #include <restinio/exception.hpp> 18 #include <restinio/string_view.hpp> 19 #include <restinio/message_builders.hpp> 20 #include <restinio/request_handler.hpp> 138 if( level_value < -1 || level_value > 9 )
142 "invalid compression level: {}, must be " 143 "an integer value in the range of -1 to 9",
156 return std::move(
this->level( level_value ) );
188 if( ( window_bits_value < 8 || window_bits_value >
MAX_WBITS ) &&
193 "invalid window_bits: {}, must be " 194 "an integer value in the range of 8 to {} or " 195 "0 for decompress operation",
200 if( 8 == window_bits_value )
201 window_bits_value = 9;
212 return std::move(
this->window_bits( window_bits_value ) );
238 "invalid compression mem_level: {}, must be " 239 "an integer value in the range of 1 to {}",
253 return std::move(
this->mem_level( mem_level_value ) );
276 Z_RLE != strategy_value )
280 "invalid compression strategy: {}, must be " 282 "Z_DEFAULT_STRATEGY({}), ",
284 "Z_HUFFMAN_ONLY({}), ",
302 return std::move(
this->strategy( strategy_value ) );
321 throw exception_t{
"too small reserve buffer size" };
324 m_reserve_buffer_size = size;
333 return std::move(
this->reserve_buffer_size( size ) );
492 auto current_window_bits = m_params.window_bits();
494 if( params_t::format_t::gzip == m_params.format() )
496 current_window_bits += 16;
499 if( params_t::operation_t::compress == m_params.operation() )
508 m_params.mem_level(),
509 m_params.strategy() );
516 current_window_bits );
519 if(
Z_OK != init_result )
523 "Failed to initialize zlib stream: {}, {}",
545 if( params_t::operation_t::compress == m_params.operation() )
571 m_out_buffer.append( input.data(), input.size() );
572 m_write_pos = m_out_buffer.size();
576 if( std::numeric_limits<
decltype( m_zlib_stream.avail_in ) >::max() < input.size() )
580 "input data is too large: {} (max possible: {}), " 581 "try to break large data into pieces",
583 std::numeric_limits<
decltype( m_zlib_stream.avail_in ) >::max() ) };
586 if( 0 < input.size() )
588 m_zlib_stream.next_in =
589 reinterpret_cast< Bytef* >(
const_cast<
char* >( input.data() ) );
591 m_zlib_stream.avail_in =
static_cast< uInt >( input.size() );
593 if( params_t::operation_t::compress == m_params.operation() )
620 if( params_t::operation_t::compress == m_params.operation() )
642 if( params_t::operation_t::compress == m_params.operation() )
681 const auto data_size = m_write_pos;
682 std::swap( result, m_out_buffer );
684 result.resize( data_size );
697 return params_t::format_t::identity == m_params.format();
704 const char * err_msg =
"<no zlib error description>";
716 throw exception_t{
"zlib operation is already completed" };
724 m_out_buffer.size() + m_params.reserve_buffer_size() );
731 m_zlib_stream.next_out =
732 reinterpret_cast< Bytef* >(
733 const_cast<
char* >( m_out_buffer.data() + m_write_pos ) );
735 const auto provided_out_buffer_size =
736 m_out_buffer.size() - m_write_pos;
737 m_zlib_stream.avail_out =
738 static_cast<uInt>( provided_out_buffer_size );
740 return provided_out_buffer_size;
753 const auto provided_out_buffer_size = prepare_out_buffer();
757 if( !(
Z_OK == operation_result ||
761 const char * err_msg =
"<no error desc>";
767 "unexpected result of deflate() (zlib): {}, {}",
772 m_write_pos += provided_out_buffer_size - m_zlib_stream.avail_out;
802 const auto provided_out_buffer_size = prepare_out_buffer();
805 if( !(
Z_OK == operation_result ||
811 "unexpected result of inflate() (zlib): {}, {}",
816 m_write_pos += provided_out_buffer_size - m_zlib_stream.avail_out;
884 return z.giveaway_output();
890 return transform( input, make_deflate_compress_params( compression_level ) );
896 return transform( input, make_deflate_decompress_params() );
902 return transform( input, make_gzip_compress_params( compression_level ) );
908 return transform( input, make_gzip_decompress_params() );
916 template <
typename Response_Output_Strategy >
930 throw exception_t{
"operation is not copress" };
937 if(
nullptr == ztransformator )
939 throw exception_t{
"invalid body appender" };
946 std::string result{
"identity" };
950 result.assign(
"deflate" );
954 result.assign(
"gzip" );
967 template <
typename Response_Output_Strategy,
typename Descendant >
1003 template <
typename X_Controlled_Output,
typename Descendant >
1010 using base_type_t::base_type_t;
1119 impl::ensure_valid_transforator( m_ztransformator.get() );
1120 m_ztransformator->flush();
1122 .append_body( m_ztransformator->giveaway_output() )
1315 template <
typename Extra_Data,
typename Handler >
1318 const generic_request_t<Extra_Data> & req,
1319 Handler && handler )
1321 using restinio::impl::is_equal_caseless;
1323 const auto content_encoding =
1324 req.header().get_field_or( restinio::http_field::content_encoding,
"identity" );
1326 if( is_equal_caseless( content_encoding,
"deflate" ) )
1328 return handler( deflate_decompress( req.body() ) );
1330 else if( is_equal_caseless( content_encoding,
"gzip" ) )
1332 return handler( gzip_decompress( req.body() ) );
1334 else if( !is_equal_caseless( content_encoding,
"identity" ) )
1337 fmt::format(
"content-encoding '{}' not supported", content_encoding ) };
1340 return handler( req.body() );
#define deflateInit2(strm, level, method, windowBits, memLevel, strategy)
void complete()
Complete zlib transformation operation.
void complete()
Complete zlib transformation operation.
std::unique_ptr< zlib_t > m_ztransformator
virtual ~body_appender_base_t()
body_appender_base_t & operator=(const body_appender_base_t &)=delete
#define inflateInit2(strm, windowBits)
body_appender_base_t(body_appender_base_t &&ba) noexcept
body_appender_base_t & operator=(body_appender_base_t &&)=delete
body_appender_base_t(const body_appender_base_t &)=delete
Base class for body appenders with restinio or user controlled output.
#define Z_DEFAULT_STRATEGY
Base class for body appenders.
std::enable_if< std::is_same< Parameter_Container, query_string_params_t >::value||std::is_same< Parameter_Container, router::route_params_t >::value, optional_t< Value_Type > >::type opt_value(const Parameter_Container ¶ms, string_view_t key)
Gets the value of a parameter specified by key wrapped in optional_t<Value_Type> if parameter exists ...
body_appender_base_t(const params_t ¶ms, resp_t &resp)
Descendant & append(string_view_t input)
Append a piece of data to response.