From c94fd60c1b2e74dfbceb842a96ce7eaea300568f Mon Sep 17 00:00:00 2001 From: Toby Collett Date: Mon, 18 May 2009 19:23:02 +0200 Subject: [PATCH] added some protocol detail to protocol file reworked some of the headers in the clients to match protocol file --- crccache/crccache.h | 5 ++- crccache/doc/http_crcsync_protocol.odt | Bin 36855 -> 9713 bytes crccache/mod_crccache_client.c | 13 ++++--- crccache/mod_crccache_server.c | 68 +++++++++++++++++---------------- 4 files changed, 48 insertions(+), 38 deletions(-) rewrite crccache/doc/http_crcsync_protocol.odt (99%) diff --git a/crccache/crccache.h b/crccache/crccache.h index 36b205b61..788eed30e 100644 --- a/crccache/crccache.h +++ b/crccache/crccache.h @@ -11,7 +11,10 @@ #ifndef CRCCACHE_H_ #define CRCCACHE_H_ -const char * CRCCACHE_ENCODING = "crccache"; +const char * CRCCACHE_ENCODING = "crcsync"; +const char * ENCODING_HEADER = "IM"; +const char * BLOCK_HEADER = "If-Block"; +const char * FILE_SIZE_HEADER = "File-Size"; // hashes per file, 40x5 gives us 200 bytes, acceptable overhead #define FULL_BLOCK_COUNT 40 const int HASH_SIZE=30; // bits per has, 30 bits is 5 bytes base 64 diff --git a/crccache/doc/http_crcsync_protocol.odt b/crccache/doc/http_crcsync_protocol.odt dissimilarity index 99% index c46a06ffc95d912b152bac4256a397631f7fabe4..8d8c09dd8cb5660bafc0eeb94d2e6eb2234b508f 100644 GIT binary patch literal 9713 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 = tail_block_size; ctx->state = DECODING_NEW_SECTION; ctx->cached_bucket = e; - + // Setup inflate for decompressing non-matched literal data ctx->decompression_stream = apr_palloc(r->pool, sizeof(*(ctx->decompression_stream))); ctx->decompression_stream->zalloc = Z_NULL; @@ -852,7 +852,7 @@ static apr_status_t recall_headers(cache_handle_t *h, request_rec *r) { char hash_set[HASH_HEADER_SIZE+HASH_BASE64_SIZE_PADDING+1]; // use buffer to set block size first snprintf(hash_set,HASH_HEADER_SIZE,"%zu",len); - apr_table_set(r->headers_in, "File-Size", hash_set); + apr_table_set(r->headers_in, FILE_SIZE_HEADER, hash_set); uint32_t crcs[block_count_including_final_block]; crc_of_blocks(data, len, blocksize, 30, crcs); @@ -864,7 +864,7 @@ static apr_status_t recall_headers(cache_handle_t *h, request_rec *r) { //ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server,"crccache: block %d, hash %08X",i,crcs[i]); } //apr_bucket_delete(e); - apr_table_set(r->headers_in, "Block-Hashes", hash_set); + apr_table_set(r->headers_in, BLOCK_HEADER, hash_set); // TODO: do we want to cache the hashes here? //ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "adding block-hashes header: %s",hash_set); @@ -1196,9 +1196,12 @@ static int crccache_decode_filter(ap_filter_t *f, apr_bucket_brigade *bb) { // TODO: set up context type struct crccache_client_ctx *ctx = f->ctx; + ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server, + "CRCSYNC retuned status code (%d)", r->status); + // TODO: make this work if we have multiple encodings const char * content_encoding; - content_encoding = apr_table_get(r->headers_out, "Content-Encoding"); + content_encoding = apr_table_get(r->headers_out, ENCODING_HEADER); if (content_encoding == NULL || strcmp(CRCCACHE_ENCODING, content_encoding) != 0) { ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server, @@ -1344,7 +1347,7 @@ static int crccache_decode_filter(ap_filter_t *f, apr_bucket_brigade *bb) { return APR_EGENERAL; } int have = sizeof(decompressed_data_buf) - strm->avail_out; - ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server, + ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server, "CRCSYNC-DECODE inflate rslt %d, consumed %d, produced %d", z_RC, avail_in_pre_inflate - strm->avail_in, have); if (have) diff --git a/crccache/mod_crccache_server.c b/crccache/mod_crccache_server.c index b3ffe81c3..5fef93f66 100644 --- a/crccache/mod_crccache_server.c +++ b/crccache/mod_crccache_server.c @@ -189,11 +189,12 @@ static ap_filter_rec_t *crccache_out_filter_handle; static int crccache_server_header_parser_handler(request_rec *r) { crccache_server_conf *conf = ap_get_module_config(r->server->module_config, &crccache_server_module); + int status = OK; if (conf->enabled) { const char * hashes, *file_size_header; - hashes = apr_table_get(r->headers_in, "Block-Hashes"); - file_size_header = apr_table_get(r->headers_in, "File-Size"); + hashes = apr_table_get(r->headers_in, BLOCK_HEADER); + file_size_header = apr_table_get(r->headers_in, FILE_SIZE_HEADER); if (hashes && file_size_header) { size_t file_size; @@ -204,7 +205,7 @@ static int crccache_server_header_parser_handler(request_rec *r) { return OK; } - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "CRCCACHE-ENCODE Block-Hashes header found so enabling protocol: %s",hashes); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "CRCCACHE-ENCODE Block Hashes header found so enabling protocol: %s",hashes); // Insert mod_deflate's INFLATE filter in the chain to unzip content // so that there is clear text available for the delta algorithm ap_filter_t *inflate_filter = ap_add_output_filter("INFLATE", NULL, r, r->connection); @@ -219,10 +220,12 @@ static int crccache_server_header_parser_handler(request_rec *r) { // And the crccache filter itself ofcourse ap_add_output_filter_handle(crccache_out_filter_handle, NULL, r, r->connection); + //r->status=226; + status = OK; } } - return OK; + return status; } /* PR 39727: we're screwing up our clients if we leave a strong ETag @@ -252,7 +255,7 @@ static apr_status_t write_compress_buffer(ap_filter_t *f, int flush) if (ctx->debug_skip_writing) return APR_SUCCESS; - + do { strm->avail_out = sizeof(compress_buf); @@ -303,7 +306,7 @@ static apr_status_t write_compress_buffer(ap_filter_t *f, int flush) return APR_SUCCESS; } - + static apr_status_t flush_compress_buffer(ap_filter_t *f) { @@ -312,7 +315,7 @@ static apr_status_t flush_compress_buffer(ap_filter_t *f) if (ctx->debug_skip_writing) return APR_SUCCESS; - + if (ctx->compression_state != COMPRESSION_BUFFER_EMPTY) { rslt = write_compress_buffer(f, Z_FINISH); // take the real status @@ -332,7 +335,7 @@ static apr_status_t write_literal(ap_filter_t *f, unsigned char *buffer, long co if (ctx->debug_skip_writing) return APR_SUCCESS; - + apr_status_t rslt; if (ctx->compression_state == COMPRESSION_BUFFER_EMPTY) { @@ -363,7 +366,7 @@ static apr_status_t write_block_reference(ap_filter_t *f, long result) if (ctx->debug_skip_writing) return APR_SUCCESS; - + unsigned bucket_size = ENCODING_BLOCK_HEADER_SIZE; ctx->tx_length += bucket_size; ctx->tx_uncompressed_length += bucket_size; @@ -395,7 +398,7 @@ static apr_status_t process_block(ap_filter_t *f) ap_log_error(APLOG_MARK, APLOG_ERR, APR_SUCCESS, r->server,"CRCCACHE-ENCODE crcctx = null"); return APR_EGENERAL; } - + long rd_block_rslt; size_t ndigested = crc_read_block( ctx->crcctx, @@ -406,7 +409,7 @@ static apr_status_t process_block(ap_filter_t *f) ap_log_error_wrapper(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server, "CRCCACHE-ENCODE crc_read_block ndigested: %zu, result %ld", ndigested, rd_block_rslt); - + // rd_block_rslt = 0: do nothing (it is a 'literal' block of exactly 'blocksize' bytes at the end of the buffer, it will have to be moved // to the beginning of the moving window so that it can be written upon the next call to crc_read_block or crc_read_flush) // rd_block_rslt > 0: send literal @@ -422,7 +425,7 @@ static apr_status_t process_block(ap_filter_t *f) unsigned char blocknum = (unsigned char) ((-rd_block_rslt)-1); ctx->buffer_read_getpos += (blocknum == FULL_BLOCK_COUNT) ? ctx->tail_block_size : ctx->block_size; } - + // Update the context with the results ctx->crc_read_block_result = rd_block_rslt; ctx->crc_read_block_ndigested = ndigested; @@ -440,7 +443,7 @@ static apr_status_t flush_block(ap_filter_t *f) request_rec *r = f->r; crccache_ctx *ctx = f->ctx; apr_status_t rslt = APR_SUCCESS; - + // ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server,"CRCCACHE-ENCODE invoking crc_read_flush"); if (ctx->crcctx == NULL) { @@ -465,7 +468,7 @@ static apr_status_t flush_block(ap_filter_t *f) unsigned char blocknum = (unsigned char) ((-rd_flush_rslt)-1); ctx->buffer_read_getpos += (blocknum == FULL_BLOCK_COUNT) ? ctx->tail_block_size : ctx->block_size; } - + // Update the context with the results ctx->crc_read_block_result = rd_flush_rslt; ctx->crc_read_block_ndigested = 0; @@ -505,7 +508,7 @@ static apr_status_t process_eos(ap_filter_t *f) { crccache_ctx *ctx = f->ctx; apr_status_t rslt; - + ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, f->r->server,"CRCCACHE-ENCODE EOS reached for APR bucket"); @@ -518,18 +521,18 @@ static apr_status_t process_eos(ap_filter_t *f) return rslt; } } - + do { // Flush remaining block in the crcctx rslt = flush_block(f); if (rslt != APR_SUCCESS) { - return rslt; + return rslt; } } while (ctx->crc_read_block_result != 0); - + // Flush anything that is remaining in the compress buffer rslt = flush_compress_buffer(f); if (rslt != APR_SUCCESS) @@ -581,7 +584,7 @@ static apr_status_t process_data_bucket(ap_filter_t *f, apr_bucket *e) { // Buffer is filled to the end. Flush as much as possible ap_log_error_wrapper(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server, - "CRCCACHE-ENCODE Buffer is filled to end, read_getpos: %zu, digest_getpos: %zu, putpos: %zu, putpos-digest_getpos: %zu (blocksize: %zu)", + "CRCCACHE-ENCODE Buffer is filled to end, read_getpos: %zu, digest_getpos: %zu, putpos: %zu, putpos-digest_getpos: %zu (blocksize: %zu)", ctx->buffer_read_getpos, ctx->buffer_digest_getpos, ctx->buffer_putpos, ctx->buffer_putpos-ctx->buffer_digest_getpos, ctx->block_size); while (ctx->buffer_putpos - ctx->buffer_digest_getpos > ctx->block_size) { @@ -592,7 +595,7 @@ static apr_status_t process_data_bucket(ap_filter_t *f, apr_bucket *e) return rslt; } ap_log_error_wrapper(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server, - "CRCCACHE-ENCODE Processed a block, read_getpos: %zu, digest_getpos: %zu, putpos: %zu, putpos-digest_getpos: %zu (blocksize: %zu)", + "CRCCACHE-ENCODE Processed a block, read_getpos: %zu, digest_getpos: %zu, putpos: %zu, putpos-digest_getpos: %zu (blocksize: %zu)", ctx->buffer_read_getpos, ctx->buffer_digest_getpos, ctx->buffer_putpos, ctx->buffer_putpos-ctx->buffer_digest_getpos, ctx->block_size); } @@ -601,7 +604,7 @@ static apr_status_t process_data_bucket(ap_filter_t *f, apr_bucket *e) // Copy the remaining part of the buffer to the start of the buffer, // so that it can be filled again as new data arrive ap_log_error_wrapper(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server, - "CRCCACHE-ENCODE Moving %zu bytes to begin of buffer", + "CRCCACHE-ENCODE Moving %zu bytes to begin of buffer", ctx->buffer_putpos - ctx->buffer_read_getpos); memcpy(ctx->buffer, ctx->buffer + ctx->buffer_read_getpos, ctx->buffer_putpos - ctx->buffer_read_getpos); } @@ -614,7 +617,7 @@ static apr_status_t process_data_bucket(ap_filter_t *f, apr_bucket *e) { // Previous block matched exactly. Let's hope the next block as well ap_log_error_wrapper(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server, - "CRCCACHE-ENCODE Previous block matched, read_getpos: %zu, digest_getpos: %zu, putpos: %zu, putpos-digest_getpos: %zu (blocksize: %zu)", + "CRCCACHE-ENCODE Previous block matched, read_getpos: %zu, digest_getpos: %zu, putpos: %zu, putpos-digest_getpos: %zu (blocksize: %zu)", ctx->buffer_read_getpos, ctx->buffer_digest_getpos, ctx->buffer_putpos, ctx->buffer_putpos-ctx->buffer_digest_getpos, ctx->block_size); rslt = process_block(f); if (rslt != APR_SUCCESS) @@ -670,14 +673,14 @@ static apr_status_t crccache_out_filter(ap_filter_t *f, apr_bucket_brigade *bb) * If it's already encoded by crccache: don't compress again. * (We could, but let's not.) */ - encoding = apr_table_get(r->headers_out, "Content-Encoding"); + encoding = apr_table_get(r->headers_out, ENCODING_HEADER); if (encoding && strcasecmp(CRCCACHE_ENCODING,encoding) == 0) { /* Even if we don't accept this request based on it not having * the Accept-Encoding, we need to note that we were looking * for this header and downstream proxies should be aware of that. */ - apr_table_mergen(r->headers_out, "Vary", "Accept-Encoding"); + apr_table_mergen(r->headers_out, "Vary", "A-IM"); ap_remove_output_filter(f); return ap_pass_brigade(f->next, bb); } @@ -708,8 +711,8 @@ static apr_status_t crccache_out_filter(ap_filter_t *f, apr_bucket_brigade *bb) /* Parse the input headers */ const char * hashes, *file_size_header; - hashes = apr_table_get(r->headers_in, "Block-Hashes"); - file_size_header = apr_table_get(r->headers_in, "File-Size"); + hashes = apr_table_get(r->headers_in, BLOCK_HEADER); + file_size_header = apr_table_get(r->headers_in, FILE_SIZE_HEADER); ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server, "CRCCACHE-ENCODE encoding file size header %s", file_size_header); @@ -741,7 +744,7 @@ static apr_status_t crccache_out_filter(ap_filter_t *f, apr_bucket_brigade *bb) // much sense to even keep invoking the crc_read_block(...) function as soon as a difference has been found. // Hence, no need to make a (potentially huge) buffer for these type of compressed (potentially huge, think about movies) // data types. - ctx->buffer_size = ctx->block_size*4 + 1; + ctx->buffer_size = ctx->block_size*4 + 1; ctx->buffer_digest_getpos = 0; ctx->buffer_read_getpos = 0; ctx->buffer_putpos = 0; @@ -758,9 +761,9 @@ static apr_status_t crccache_out_filter(ap_filter_t *f, apr_bucket_brigade *bb) /* Setup deflate for compressing non-matched literal data */ ctx->compression_state = COMPRESSION_BUFFER_EMPTY; - // TODO: should I pass some apr_palloc based function to prevent memory leaks + // TODO: should I pass some apr_palloc based function to prevent memory leaks //in case of unexpected errors? - + ap_log_error_wrapper(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server,"CRCCACHE-ENCODE size of compression stream: %zd",sizeof(*(ctx->compression_stream))); ctx->compression_stream = apr_palloc(r->pool, sizeof(*(ctx->compression_stream))); ctx->compression_stream->zalloc = Z_NULL; @@ -793,10 +796,11 @@ static apr_status_t crccache_out_filter(ap_filter_t *f, apr_bucket_brigade *bb) // TODO: the crccache-client could recalculate these headers once it has // reconstructed the page, before handling the reconstructed page // back to the client - apr_table_setn(r->headers_out, "Content-Encoding", CRCCACHE_ENCODING); + apr_table_setn(r->headers_out, ENCODING_HEADER, CRCCACHE_ENCODING); apr_table_unset(r->headers_out, "Content-Length"); apr_table_unset(r->headers_out, "Content-MD5"); crccache_check_etag(r, CRCCACHE_ENCODING); + } @@ -805,7 +809,7 @@ static apr_status_t crccache_out_filter(ap_filter_t *f, apr_bucket_brigade *bb) const char *data; apr_size_t len; apr_status_t rslt; - + e = APR_BRIGADE_FIRST(bb); if (APR_BUCKET_IS_EOS(e)) @@ -825,7 +829,7 @@ static apr_status_t crccache_out_filter(ap_filter_t *f, apr_bucket_brigade *bb) { return rslt; // A problem occurred. Abort the processing } - + /* Okay, we've seen the EOS. * Time to pass it along down the chain. */ -- 2.11.4.GIT