in Release/src/http/common/http_compression.cpp [1003:1095]
std::unique_ptr<decompress_provider> get_decompressor_from_header(
const utility::string_t& encoding,
header_types type,
const std::vector<std::shared_ptr<decompress_factory>>& factories)
{
const std::vector<std::shared_ptr<decompress_factory>>& f =
factories.empty() ? web::http::compression::builtin::g_decompress_factories : factories;
std::unique_ptr<decompress_provider> decompressor;
utility::string_t token;
size_t start;
size_t length;
size_t comma;
size_t n;
_ASSERTE(type == header_types::transfer_encoding || type == header_types::content_encoding);
n = 0;
while (n != utility::string_t::npos)
{
// Tokenize by commas first
comma = encoding.find(_XPLATSTR(','), n);
start = n;
if (comma == utility::string_t::npos)
{
length = encoding.size() - n;
n = utility::string_t::npos;
}
else
{
length = comma - n;
n = comma + 1;
}
// Then remove leading and trailing whitespace
remove_surrounding_http_whitespace(encoding, start, length);
if (!length)
{
throw http_exception(status_codes::BadRequest, "Empty field in header");
}
// Immediately try to instantiate a decompressor
token = encoding.substr(start, length);
auto d = web::http::compression::builtin::_make_decompressor(f, token);
if (d)
{
if (decompressor)
{
status_code code = status_codes::NotImplemented;
if (type == header_types::content_encoding)
{
code = status_codes::UnsupportedMediaType;
}
throw http_exception(code, "Multiple compression algorithms not supported for a single request");
}
// We found our decompressor; store it off while we process the rest of the header
decompressor = std::move(d);
}
else
{
if (n != utility::string_t::npos)
{
if (type == header_types::transfer_encoding &&
utility::details::str_iequal(_XPLATSTR("chunked"), token))
{
throw http_exception(status_codes::BadRequest,
"Chunked must come last in the Transfer-Encoding header");
}
}
if (!decompressor && !f.empty() && (n != utility::string_t::npos || type == header_types::content_encoding))
{
// The first encoding type did not match; throw an informative
// exception with an encoding-type-appropriate HTTP error code
status_code code = status_codes::NotImplemented;
if (type == header_types::content_encoding)
{
code = status_codes::UnsupportedMediaType;
}
throw http_exception(code, "Unsupported encoding type");
}
}
}
if (type == header_types::transfer_encoding && !utility::details::str_iequal(_XPLATSTR("chunked"), token))
{
throw http_exception(status_codes::BadRequest, "Transfer-Encoding header missing chunked");
}
// Either the response is compressed and we have a decompressor that can handle it, or
// built-in compression is not enabled and we don't have an alternate set of decompressors
return decompressor;
}