diff --git a/src/or/directory.c b/src/or/directory.c index 6504e2e7ad..cf6f0db977 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -3677,6 +3677,13 @@ parse_or_diff_from_header(smartlist_t **digests_out, const char *headers) return 0; } +/** Fallback compression method. The fallback compression method is used in + * case a client requests a non-compressed document. We only store compressed + * documents, so we use this compression method to fetch the document and let + * the spooling system do the streaming decompression. + */ +#define FALLBACK_COMPRESS_METHOD ZLIB_METHOD + /** * Try to find the best consensus diff possible in order to serve a client * request for a diff from one of the consensuses in digests to the @@ -3706,6 +3713,16 @@ find_best_diff(const smartlist_t *digests, int flav, } } } SMARTLIST_FOREACH_END(diff_from); + + SMARTLIST_FOREACH_BEGIN(digests, const uint8_t *, diff_from) { + if (consdiffmgr_find_diff_from(&result, flav, DIGEST_SHA3_256, diff_from, + DIGEST256_LEN, FALLBACK_COMPRESS_METHOD) == CONSDIFF_AVAILABLE) { + tor_assert_nonfatal(result); + *compression_used_out = FALLBACK_COMPRESS_METHOD; + return result; + } + } SMARTLIST_FOREACH_END(diff_from); + return NULL; } @@ -3735,6 +3752,13 @@ find_best_consensus(int flav, } } + if (consdiffmgr_find_consensus(&result, flav, + FALLBACK_COMPRESS_METHOD) == CONSDIFF_AVAILABLE) { + tor_assert_nonfatal(result); + *compression_used_out = FALLBACK_COMPRESS_METHOD; + return result; + } + return NULL; } @@ -3911,12 +3935,15 @@ handle_get_current_consensus(dir_connection_t *conn, } clear_spool = 0; + + // The compress_method might have been NO_METHOD, but we store the data + // compressed. Decompress them using `compression_used`. See fallback code in + // find_best_consensus() and find_best_diff(). write_http_response_header(conn, -1, - compression_used, + compress_method == NO_METHOD ? + NO_METHOD : compression_used, smartlist_len(conn->spool) == 1 ? lifetime : 0); - // The compress_method requested was NO_METHOD, but we store the data - // compressed. Decompress them using `compression_used`. if (compress_method == NO_METHOD) conn->compress_state = tor_compress_new(0, compression_used, HIGH_COMPRESSION);