Lines 784-795
Link Here
|
784 |
ctx->bb = apr_brigade_create(r->pool, f->c->bucket_alloc); |
784 |
ctx->bb = apr_brigade_create(r->pool, f->c->bucket_alloc); |
785 |
ctx->proc_bb = apr_brigade_create(r->pool, f->c->bucket_alloc); |
785 |
ctx->proc_bb = apr_brigade_create(r->pool, f->c->bucket_alloc); |
786 |
ctx->buffer = apr_palloc(r->pool, c->bufferSize); |
786 |
ctx->buffer = apr_palloc(r->pool, c->bufferSize); |
|
|
787 |
ctx->libz_end_func = inflateEnd; |
788 |
ctx->validation_buffer = NULL; |
789 |
ctx->validation_buffer_length = 0; |
787 |
|
790 |
|
788 |
rv = ap_get_brigade(f->next, ctx->bb, AP_MODE_READBYTES, block, 10); |
791 |
rv = ap_get_brigade(f->next, ctx->bb, AP_MODE_READBYTES, block, 10); |
789 |
if (rv != APR_SUCCESS) { |
792 |
if (rv != APR_SUCCESS) { |
790 |
return rv; |
793 |
return rv; |
791 |
} |
794 |
} |
792 |
|
795 |
|
|
|
796 |
/* |
797 |
* Register a cleanup function to ensure that we cleanup the internal |
798 |
* libz resources. |
799 |
*/ |
800 |
apr_pool_cleanup_register(r->pool, ctx, deflate_ctx_cleanup, |
801 |
apr_pool_cleanup_null); |
802 |
|
793 |
apr_table_unset(r->headers_in, "Content-Length"); |
803 |
apr_table_unset(r->headers_in, "Content-Length"); |
794 |
apr_table_unset(r->headers_in, "Content-MD5"); |
804 |
apr_table_unset(r->headers_in, "Content-MD5"); |
795 |
|
805 |
|
Lines 803-808
Link Here
|
803 |
if (len != 10 || |
813 |
if (len != 10 || |
804 |
deflate_hdr[0] != deflate_magic[0] || |
814 |
deflate_hdr[0] != deflate_magic[0] || |
805 |
deflate_hdr[1] != deflate_magic[1]) { |
815 |
deflate_hdr[1] != deflate_magic[1]) { |
|
|
816 |
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, |
817 |
"Zlib: didn't recieve valid gzip magic bytes"); |
806 |
return APR_EGENERAL; |
818 |
return APR_EGENERAL; |
807 |
} |
819 |
} |
808 |
|
820 |
|
Lines 829-834
Link Here
|
829 |
ctx->stream.avail_out = c->bufferSize; |
841 |
ctx->stream.avail_out = c->bufferSize; |
830 |
|
842 |
|
831 |
apr_brigade_cleanup(ctx->bb); |
843 |
apr_brigade_cleanup(ctx->bb); |
|
|
844 |
ctx->inflate_init = 1; |
832 |
} |
845 |
} |
833 |
|
846 |
|
834 |
if (APR_BRIGADE_EMPTY(ctx->proc_bb)) { |
847 |
if (APR_BRIGADE_EMPTY(ctx->proc_bb)) { |
Lines 847-856
Link Here
|
847 |
const char *data; |
860 |
const char *data; |
848 |
apr_size_t len; |
861 |
apr_size_t len; |
849 |
|
862 |
|
850 |
/* If we actually see the EOS, that means we screwed up! */ |
|
|
851 |
if (APR_BUCKET_IS_EOS(bkt)) { |
863 |
if (APR_BUCKET_IS_EOS(bkt)) { |
|
|
864 |
apr_bucket *eos; |
865 |
ap_remove_output_filter(f); |
866 |
ctx->stream.avail_in = 0; |
867 |
if (ctx->validation_buffer_length == VALIDATION_SIZE) { |
868 |
unsigned long compCRC, compLen; |
869 |
compCRC = getLong(ctx->validation_buffer); |
870 |
if (ctx->crc != compCRC) { |
871 |
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, |
872 |
"Zlib: Checksum of inflated stream invalid: " |
873 |
"%ld != %ld", |
874 |
ctx->crc, compCRC); |
875 |
return APR_EGENERAL; |
876 |
} |
877 |
ctx->validation_buffer += VALIDATION_SIZE / 2; |
878 |
compLen = getLong(ctx->validation_buffer); |
879 |
if (ctx->stream.total_out != compLen) { |
880 |
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, |
881 |
"Zlib: Length of inflated stream invalid: " |
882 |
"%ld != %ld", ctx->stream.total_out, |
883 |
compLen); |
884 |
return APR_EGENERAL; |
885 |
} |
886 |
} else if (ctx->inflate_init != -1){ |
887 |
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, |
888 |
"Zlib: Validation bytes not present"); |
889 |
return APR_EGENERAL; |
890 |
} |
852 |
inflateEnd(&ctx->stream); |
891 |
inflateEnd(&ctx->stream); |
853 |
return APR_EGENERAL; |
892 |
ctx->validation_buffer = NULL; |
|
|
893 |
ctx->validation_buffer_length = 0; |
894 |
/* No need for cleanup any longer */ |
895 |
apr_pool_cleanup_kill(r->pool, ctx, deflate_ctx_cleanup); |
896 |
|
897 |
eos = apr_bucket_eos_create(f->c->bucket_alloc); |
898 |
APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, eos); |
899 |
|
900 |
/* |
901 |
* Okay, we've seen the EOS. |
902 |
* Time to pass it along down the chain. |
903 |
*/ |
904 |
|
905 |
ctx->inflate_init = -1; |
906 |
return ap_pass_brigade(f->next, ctx->bb); |
854 |
} |
907 |
} |
855 |
|
908 |
|
856 |
if (APR_BUCKET_IS_FLUSH(bkt)) { |
909 |
if (APR_BUCKET_IS_FLUSH(bkt)) { |
Lines 885-890
Link Here
|
885 |
|
938 |
|
886 |
zRC = Z_OK; |
939 |
zRC = Z_OK; |
887 |
|
940 |
|
|
|
941 |
if (ctx->validation_buffer) { |
942 |
if (ctx->validation_buffer_length < VALIDATION_SIZE) { |
943 |
apr_size_t copy_size; |
944 |
|
945 |
copy_size = VALIDATION_SIZE - ctx->validation_buffer_length; |
946 |
if (copy_size > ctx->stream.avail_in) |
947 |
copy_size = ctx->stream.avail_in; |
948 |
memcpy(ctx->validation_buffer + ctx->validation_buffer_length, |
949 |
ctx->stream.next_in, copy_size); |
950 |
/* Saved copy_size bytes */ |
951 |
ctx->stream.avail_in -= copy_size; |
952 |
ctx->validation_buffer_length += copy_size; |
953 |
} |
954 |
|
955 |
if (ctx->stream.avail_in) { |
956 |
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, |
957 |
"Zlib: %d bytes of garbage at the end of " |
958 |
"compressed stream.", ctx->stream.avail_in); |
959 |
/* |
960 |
* There is nothing worth consuming for zlib left, because it is |
961 |
* either garbage data or the data has been copied to the |
962 |
* validation buffer (processing validation data is no business |
963 |
* for zlib). So set ctx->stream.avail_in to zero to indicate |
964 |
* this to the following while loop. |
965 |
*/ |
966 |
ctx->stream.avail_in = 0; |
967 |
} |
968 |
} |
969 |
|
888 |
while (ctx->stream.avail_in != 0) { |
970 |
while (ctx->stream.avail_in != 0) { |
889 |
if (ctx->stream.avail_out == 0) { |
971 |
if (ctx->stream.avail_out == 0) { |
890 |
apr_bucket *tmp_heap; |
972 |
apr_bucket *tmp_heap; |
Lines 910-916
Link Here
|
910 |
} |
992 |
} |
911 |
} |
993 |
} |
912 |
if (zRC == Z_STREAM_END) { |
994 |
if (zRC == Z_STREAM_END) { |
913 |
apr_bucket *tmp_heap, *eos; |
995 |
apr_bucket *tmp_heap; |
914 |
|
996 |
|
915 |
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, |
997 |
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, |
916 |
"Zlib: Inflated %ld to %ld : URL %s", |
998 |
"Zlib: Inflated %ld to %ld : URL %s", |
Lines 925-960
Link Here
|
925 |
APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_heap); |
1007 |
APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_heap); |
926 |
ctx->stream.avail_out = c->bufferSize; |
1008 |
ctx->stream.avail_out = c->bufferSize; |
927 |
|
1009 |
|
928 |
/* Is the remaining 8 bytes already in the avail stream? */ |
1010 |
/* |
929 |
if (ctx->stream.avail_in >= 8) { |
1011 |
* We have inflated all data. Now try to capture the |
930 |
unsigned long compCRC, compLen; |
1012 |
* validation bytes. We may not have them all available |
931 |
compCRC = getLong(ctx->stream.next_in); |
1013 |
* right now, but capture what is there. |
932 |
if (ctx->crc != compCRC) { |
1014 |
*/ |
933 |
inflateEnd(&ctx->stream); |
1015 |
ctx->validation_buffer = apr_pcalloc(f->r->pool, |
934 |
return APR_EGENERAL; |
1016 |
VALIDATION_SIZE); |
935 |
} |
1017 |
if (ctx->stream.avail_in > VALIDATION_SIZE) { |
936 |
ctx->stream.next_in += 4; |
1018 |
ctx->validation_buffer_length = VALIDATION_SIZE; |
937 |
compLen = getLong(ctx->stream.next_in); |
|
|
938 |
if (ctx->stream.total_out != compLen) { |
939 |
inflateEnd(&ctx->stream); |
940 |
return APR_EGENERAL; |
941 |
} |
942 |
} |
943 |
else { |
944 |
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, |
1019 |
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, |
945 |
"bytes left after Z_STREAM_END bucket:%ld", |
1020 |
"Zlib: %d bytes of garbage at the end of " |
946 |
ctx->stream.avail_in); |
1021 |
"compressed stream.", |
947 |
/* FIXME: We need to grab the 8 verification bytes |
1022 |
ctx->stream.avail_in - VALIDATION_SIZE); |
948 |
* from the wire! */ |
1023 |
} else if (ctx->stream.avail_in > 0) { |
949 |
inflateEnd(&ctx->stream); |
1024 |
ctx->validation_buffer_length = ctx->stream.avail_in; |
950 |
return APR_EGENERAL; |
1025 |
} |
951 |
} |
1026 |
if (ctx->validation_buffer_length) |
952 |
|
1027 |
memcpy(ctx->validation_buffer, ctx->stream.next_in, |
953 |
inflateEnd(&ctx->stream); |
1028 |
ctx->validation_buffer_length); |
954 |
|
|
|
955 |
eos = apr_bucket_eos_create(f->c->bucket_alloc); |
956 |
APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, eos); |
957 |
break; |
958 |
} |
1029 |
} |
959 |
|
1030 |
|
960 |
} |
1031 |
} |