/***
* Copyright (C) Microsoft. All rights reserved.
* Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
*
* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
*
* HTTP Library: Compression and decompression interfaces
*
* For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk
*
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
****/
#pragma once
namespace web
{
namespace http
{
namespace compression
{
///
/// Hint as to whether a compress or decompress call is meant to be the last for a particular HTTP request or reply
///
enum operation_hint
{
is_last, // Used for the expected last compress() call, or for an expected single decompress() call
has_more // Used when further compress() calls will be made, or when multiple decompress() calls may be required
};
///
/// Result structure for asynchronous compression and decompression operations
///
struct operation_result
{
size_t input_bytes_processed; // From the input buffer
size_t output_bytes_produced; // To the output buffer
bool done; // For compress, set when 'last' is true and there was enough space to complete compression;
// for decompress, set if the end of the decompression stream has been reached
};
///
/// Compression interface for use with HTTP requests
///
class compress_provider
{
public:
virtual const utility::string_t& algorithm() const = 0;
virtual size_t compress(const uint8_t* input,
size_t input_size,
uint8_t* output,
size_t output_size,
operation_hint hint,
size_t& input_bytes_processed,
bool& done) = 0;
virtual pplx::task compress(
const uint8_t* input, size_t input_size, uint8_t* output, size_t output_size, operation_hint hint) = 0;
virtual void reset() = 0;
virtual ~compress_provider() = default;
};
///
/// Decompression interface for use with HTTP requests
///
class decompress_provider
{
public:
virtual const utility::string_t& algorithm() const = 0;
virtual size_t decompress(const uint8_t* input,
size_t input_size,
uint8_t* output,
size_t output_size,
operation_hint hint,
size_t& input_bytes_processed,
bool& done) = 0;
virtual pplx::task decompress(
const uint8_t* input, size_t input_size, uint8_t* output, size_t output_size, operation_hint hint) = 0;
virtual void reset() = 0;
virtual ~decompress_provider() = default;
};
///
/// Factory interface for compressors for use with received HTTP requests
///
class compress_factory
{
public:
virtual const utility::string_t& algorithm() const = 0;
virtual std::unique_ptr make_compressor() const = 0;
virtual ~compress_factory() = default;
};
///
/// Factory interface for decompressors for use with HTTP requests
///
class decompress_factory
{
public:
virtual const utility::string_t& algorithm() const = 0;
virtual uint16_t weight() const = 0;
virtual std::unique_ptr make_decompressor() const = 0;
virtual ~decompress_factory() = default;
};
///
/// Built-in compression support
///
namespace builtin
{
///
/// Test whether cpprestsdk was built with built-in compression support
/// True if cpprestsdk was built with built-in compression support, and false if not.
///
_ASYNCRTIMP bool supported();
///
// String constants for each built-in compression algorithm, for convenient use with the factory functions
///
namespace algorithm
{
#if defined(_MSC_VER) && _MSC_VER < 1900
const utility::char_t* const GZIP = _XPLATSTR("gzip");
const utility::char_t* const DEFLATE = _XPLATSTR("deflate");
const utility::char_t* const BROTLI = _XPLATSTR("br");
#else // ^^^ VS2013 and before ^^^ // vvv VS2015+, and everything else vvv
constexpr const utility::char_t* const GZIP = _XPLATSTR("gzip");
constexpr const utility::char_t* const DEFLATE = _XPLATSTR("deflate");
constexpr const utility::char_t* const BROTLI = _XPLATSTR("br");
#endif
///
/// Test whether cpprestsdk was built with built-in compression support and
/// the supplied string matches a supported built-in algorithm
/// The name of the algorithm to test for built-in support.
/// True if cpprestsdk was built with built-in compression support and
/// the supplied string matches a supported built-in algorithm, and false if not.
///
_ASYNCRTIMP bool supported(const utility::string_t& algorithm);
} // namespace algorithm
///
/// Factory function to instantiate a built-in compression provider with default parameters by compression algorithm
/// name.
///
/// The name of the algorithm for which to instantiate a provider.
///
/// A caller-owned pointer to a provider of the requested-type, or to nullptr if no such built-in type exists.
///
_ASYNCRTIMP std::unique_ptr make_compressor(const utility::string_t& algorithm);
///
/// Factory function to instantiate a built-in decompression provider with default parameters by compression algorithm
/// name.
///
/// The name of the algorithm for which to instantiate a provider.
///
/// A caller-owned pointer to a provider of the requested-type, or to nullptr if no such built-in type exists.
///
_ASYNCRTIMP std::unique_ptr make_decompressor(const utility::string_t& algorithm);
///
/// Factory function to obtain a pointer to a built-in compression provider factory by compression algorithm name.
///
/// The name of the algorithm for which to find a factory.
///
/// A caller-owned pointer to a provider of the requested-type, or to nullptr if no such built-in type exists.
///
_ASYNCRTIMP std::shared_ptr get_compress_factory(const utility::string_t& algorithm);
///
/// Factory function to obtain a pointer to a built-in decompression provider factory by compression algorithm name.
///
/// The name of the algorithm for which to find a factory.
///
/// A caller-owned pointer to a provider of the requested-type, or to nullptr if no such built-in type exists.
///
_ASYNCRTIMP std::shared_ptr get_decompress_factory(const utility::string_t& algorithm);
///
// Factory function to instantiate a built-in gzip compression provider with caller-selected parameters.
///
///
/// A caller-owned pointer to a gzip compression provider, or to nullptr if the library was built without built-in
/// compression support.
///
_ASYNCRTIMP std::unique_ptr make_gzip_compressor(int compressionLevel,
int method,
int strategy,
int memLevel);
///
// Factory function to instantiate a built-in deflate compression provider with caller-selected parameters.
///
///
/// A caller-owned pointer to a deflate compression provider, or to nullptr if the library was built without built-in
/// compression support..
///
_ASYNCRTIMP std::unique_ptr make_deflate_compressor(int compressionLevel,
int method,
int strategy,
int memLevel);
///
// Factory function to instantiate a built-in Brotli compression provider with caller-selected parameters.
///
///
/// A caller-owned pointer to a Brotli compression provider, or to nullptr if the library was built without built-in
/// compression support.
///
_ASYNCRTIMP std::unique_ptr make_brotli_compressor(
uint32_t window, uint32_t quality, uint32_t mode, uint32_t block, uint32_t nomodel, uint32_t hint);
} // namespace builtin
///
/// Factory function to instantiate a compression provider factory by compression algorithm name.
///
/// The name of the algorithm supported by the factory. Must match that returned by the
/// web::http::compression::compress_provider type instantiated by the factory's make_compressor function.
/// The supplied string is copied, and thus need not remain valid once the call returns.
/// A factory function to be used to instantiate a compressor matching the factory's
/// reported algorithm.
///
/// A pointer to a generic provider factory implementation configured with the supplied parameters.
///
///
/// This method may be used to conveniently instantiate a factory object for a caller-selected compress_provider.
/// That provider may be of the caller's own design, or it may be one of the built-in types. As such, this method may
/// be helpful when a caller wishes to build vectors containing a mix of custom and built-in providers.
///
_ASYNCRTIMP std::shared_ptr make_compress_factory(
const utility::string_t& algorithm, std::function()> make_compressor);
///
/// Factory function to instantiate a decompression provider factory by compression algorithm name.
///
/// The name of the algorithm supported by the factory. Must match that returned by the
/// web::http::compression::decompress_provider type instantiated by the factory's make_decompressor function.
/// The supplied string is copied, and thus need not remain valid once the call returns.
/// A numeric weight for the compression algorithm, times 1000, for use as a "quality value" when
/// requesting that the server send a compressed response. Valid values are between 0 and 1000, inclusive, where higher
/// values indicate more preferred algorithms, and 0 indicates that the algorithm is not allowed; values greater than
/// 1000 are treated as 1000.
/// A factory function to be used to instantiate a decompressor matching the factory's
/// reported algorithm.
///
/// A pointer to a generic provider factory implementation configured with the supplied parameters.
///
///
/// This method may be used to conveniently instantiate a factory object for a caller-selected
/// decompress_provider. That provider may be of the caller's own design, or it may be one of the built-in
/// types. As such, this method may be helpful when a caller wishes to change the weights of built-in provider types,
/// to use custom providers without explicitly implementing a decompress_factory, or to build vectors containing
/// a mix of custom and built-in providers.
///
_ASYNCRTIMP std::shared_ptr make_decompress_factory(
const utility::string_t& algorithm,
uint16_t weight,
std::function()> make_decompressor);
namespace details
{
///
/// Header type enum for use with compressor and decompressor header parsing and building functions
///
enum header_types
{
transfer_encoding,
content_encoding,
te,
accept_encoding
};
///
/// Factory function to instantiate an appropriate compression provider, if any.
///
/// A TE or Accept-Encoding header to interpret.
/// Specifies the type of header whose contents are in the encoding parameter; valid values are
/// header_type::te and header_type::accept_encoding.
/// A compressor object of the caller's preferred (possibly custom) type, which is used if
/// possible.
/// A collection of factory objects for use in construction of an appropriate compressor, if
/// any. If empty or not supplied, the set of supported built-in compressors is used.
///
/// A pointer to a compressor object that is acceptable per the supplied header, or to nullptr if no matching
/// algorithm is found.
///
_ASYNCRTIMP std::unique_ptr get_compressor_from_header(
const utility::string_t& encoding,
header_types type,
const std::vector>& factories = std::vector>());
///
/// Factory function to instantiate an appropriate decompression provider, if any.
///
/// A Transfer-Encoding or Content-Encoding header to interpret.
/// Specifies the type of header whose contents are in the encoding parameter; valid values are
/// header_type::transfer_encoding and header_type::content_encoding.
/// A collection of factory objects for use in construction of an appropriate decompressor,
/// if any. If empty or not supplied, the set of supported built-in compressors is used.
///
/// A pointer to a decompressor object that is acceptable per the supplied header, or to nullptr if no matching
/// algorithm is found.
///
_ASYNCRTIMP std::unique_ptr get_decompressor_from_header(
const utility::string_t& encoding,
header_types type,
const std::vector>& factories =
std::vector>());
///
/// Helper function to compose a TE or Accept-Encoding header with supported, and possibly ranked, compression
/// algorithms.
///
/// Specifies the type of header to be built; valid values are header_type::te and
/// header_type::accept_encoding.
/// A collection of factory objects for use in header construction. If empty or not
/// supplied, the set of supported built-in compressors is used.
///
/// A well-formed header, without the header name, specifying the acceptable ranked compression types.
///
_ASYNCRTIMP utility::string_t build_supported_header(header_types type,
const std::vector>& factories =
std::vector>());
} // namespace details
} // namespace compression
} // namespace http
} // namespace web