Merge branch 'parse_accept_encoding'

This commit is contained in:
Nick Mathewson
2017-04-27 11:31:31 -04:00
5 changed files with 122 additions and 13 deletions
+51 -11
View File
@@ -2928,6 +2928,31 @@ write_http_response_header(dir_connection_t *conn, ssize_t length,
cache_lifetime);
}
/** Parse the compression methods listed in an Accept-Encoding header <b>h</b>,
* and convert them to a bitfield where compression method x is supported if
* and only if 1 &lt;&lt; x is set in the bitfield. */
STATIC unsigned
parse_accept_encoding_header(const char *h)
{
unsigned result = (1u << NO_METHOD);
smartlist_t *methods = smartlist_new();
smartlist_split_string(methods, h, ",",
SPLIT_SKIP_SPACE|SPLIT_STRIP_SPACE|SPLIT_IGNORE_BLANK, 0);
SMARTLIST_FOREACH_BEGIN(methods, const char *, m) {
compress_method_t method = compression_method_get_by_name(m);
if (method != UNKNOWN_METHOD) {
tor_assert(method < 8*sizeof(unsigned));
result |= (1u << method);
}
} SMARTLIST_FOREACH_END(m);
SMARTLIST_FOREACH_BEGIN(methods, char *, m) {
tor_free(m);
} SMARTLIST_FOREACH_END(m);
smartlist_free(methods);
return result;
}
/** Decide whether a client would accept the consensus we have.
*
* Clients can say they only want a consensus if it's signed by more
@@ -3002,8 +3027,9 @@ choose_compression_level(ssize_t n_bytes)
/** Information passed to handle a GET request. */
typedef struct get_handler_args_t {
/** True if the client asked for compressed data. */
int compressed;
/** Bitmask of compression methods that the client said (or implied) it
* supported. */
unsigned compression_supported;
/** If nonzero, the time included an if-modified-since header with this
* value. */
time_t if_modified_since;
@@ -3077,8 +3103,9 @@ directory_handle_command_get,(dir_connection_t *conn, const char *headers,
{
char *url, *url_mem, *header;
time_t if_modified_since = 0;
int compressed;
int zlib_compressed_in_url;
size_t url_len;
unsigned compression_methods_supported;
/* We ignore the body of a GET request. */
(void)req_body;
@@ -3109,17 +3136,30 @@ directory_handle_command_get,(dir_connection_t *conn, const char *headers,
url_mem = url;
url_len = strlen(url);
compressed = url_len > 2 && !strcmp(url+url_len-2, ".z");
if (compressed) {
zlib_compressed_in_url = url_len > 2 && !strcmp(url+url_len-2, ".z");
if (zlib_compressed_in_url) {
url[url_len-2] = '\0';
url_len -= 2;
}
if ((header = http_get_header(headers, "Accept-Encoding"))) {
compression_methods_supported = parse_accept_encoding_header(header);
tor_free(header);
} else {
compression_methods_supported = (1u << NO_METHOD);
if (zlib_compressed_in_url)
compression_methods_supported |= (1u << ZLIB_METHOD);
}
/* Remove all methods that we don't both support. */
compression_methods_supported &= tor_compress_get_supported_method_bitmask();
get_handler_args_t args;
args.url = url;
args.headers = headers;
args.if_modified_since = if_modified_since;
args.compressed = compressed;
args.compression_supported = compression_methods_supported;
int i, result = -1;
for (i = 0; url_table[i].string; ++i) {
@@ -3198,7 +3238,7 @@ handle_get_current_consensus(dir_connection_t *conn,
const get_handler_args_t *args)
{
const char *url = args->url;
const int compressed = args->compressed;
const int compressed = args->compression_supported & (1u << ZLIB_METHOD);
const time_t if_modified_since = args->if_modified_since;
int clear_spool = 0;
@@ -3339,7 +3379,7 @@ static int
handle_get_status_vote(dir_connection_t *conn, const get_handler_args_t *args)
{
const char *url = args->url;
const int compressed = args->compressed;
const int compressed = args->compression_supported & (1u << ZLIB_METHOD);
{
int current;
ssize_t body_len = 0;
@@ -3446,7 +3486,7 @@ static int
handle_get_microdesc(dir_connection_t *conn, const get_handler_args_t *args)
{
const char *url = args->url;
const int compressed = args->compressed;
const int compressed = args->compression_supported & (1u << ZLIB_METHOD);
int clear_spool = 1;
{
conn->spool = smartlist_new();
@@ -3496,7 +3536,7 @@ static int
handle_get_descriptor(dir_connection_t *conn, const get_handler_args_t *args)
{
const char *url = args->url;
const int compressed = args->compressed;
const int compressed = args->compression_supported & (1u << ZLIB_METHOD);
const or_options_t *options = get_options();
int clear_spool = 1;
if (!strcmpstart(url,"/tor/server/") ||
@@ -3589,7 +3629,7 @@ static int
handle_get_keys(dir_connection_t *conn, const get_handler_args_t *args)
{
const char *url = args->url;
const int compressed = args->compressed;
const int compressed = args->compression_supported & (1u << ZLIB_METHOD);
const time_t if_modified_since = args->if_modified_since;
{
smartlist_t *certs = smartlist_new();
+1
View File
@@ -196,6 +196,7 @@ STATIC int next_random_exponential_delay(int delay, int max_delay);
STATIC int parse_hs_version_from_post(const char *url, const char *prefix,
const char **end_pos);
STATIC unsigned parse_accept_encoding_header(const char *h);
#endif
#endif