| 88 |
* If a request has multiple encodings, we need the gzip |
* If a request has multiple encodings, we need the gzip |
| 89 |
* to be the outermost non-identity encoding. |
* to be the outermost non-identity encoding. |
| 90 |
*/ |
*/ |
| 91 |
static int check_gzip(apr_pool_t *pool, apr_table_t *hdrs, |
static int check_gzip(request_rec *r, apr_table_t *hdrs1, apr_table_t *hdrs2) |
|
apr_table_t *hdrs2, const char *enc_in) |
|
| 92 |
{ |
{ |
| 93 |
int found = 0; |
int found = 0; |
| 94 |
|
apr_table_t *hdrs = hdrs1; |
| 95 |
const char *encoding = apr_table_get(hdrs, "Content-Encoding"); |
const char *encoding = apr_table_get(hdrs, "Content-Encoding"); |
| 96 |
|
|
| 97 |
if (!encoding && (hdrs2 != NULL)) { |
if (!encoding && (hdrs2 != NULL)) { |
| 98 |
|
/* the output filter has two tables and a content_encoding to check */ |
| 99 |
encoding = apr_table_get(hdrs2, "Content-Encoding"); |
encoding = apr_table_get(hdrs2, "Content-Encoding"); |
| 100 |
} |
hdrs = hdrs2; |
| 101 |
if (!encoding) { |
if (!encoding) { |
| 102 |
encoding = enc_in; |
encoding = r->content_encoding; |
| 103 |
|
hdrs = NULL; |
| 104 |
|
} |
| 105 |
} |
} |
| 106 |
if (encoding && *encoding) { |
if (encoding && *encoding) { |
| 107 |
|
|
| 109 |
if (!strcasecmp(encoding, "gzip") |
if (!strcasecmp(encoding, "gzip") |
| 110 |
|| !strcasecmp(encoding, "x-gzip")) { |
|| !strcasecmp(encoding, "x-gzip")) { |
| 111 |
found = 1; |
found = 1; |
| 112 |
|
if (hdrs) { |
| 113 |
apr_table_unset(hdrs, "Content-Encoding"); |
apr_table_unset(hdrs, "Content-Encoding"); |
| 114 |
} |
} |
| 115 |
|
else { |
| 116 |
|
r->content_encoding = NULL; |
| 117 |
|
} |
| 118 |
|
} |
| 119 |
else if (ap_strchr_c(encoding, ',') != NULL) { |
else if (ap_strchr_c(encoding, ',') != NULL) { |
| 120 |
/* If the outermost encoding isn't gzip, there's nowt |
/* If the outermost encoding isn't gzip, there's nowt |
| 121 |
* we can do. So only check the last non-identity token |
* we can do. So only check the last non-identity token |
| 122 |
*/ |
*/ |
| 123 |
char *new_encoding = apr_pstrdup(pool, encoding); |
char *new_encoding = apr_pstrdup(r->pool, encoding); |
| 124 |
char *ptr; |
char *ptr; |
| 125 |
for(;;) { |
for(;;) { |
| 126 |
char *token = ap_strrchr(new_encoding, ','); |
char *token = ap_strrchr(new_encoding, ','); |
| 127 |
if (!token) { /* gzip:identity or other:identity */ |
if (!token) { /* gzip:identity or other:identity */ |
| 128 |
if (!strcasecmp(new_encoding, "gzip") |
if (!strcasecmp(new_encoding, "gzip") |
| 129 |
|| !strcasecmp(new_encoding, "x-gzip")) { |
|| !strcasecmp(new_encoding, "x-gzip")) { |
|
apr_table_unset(hdrs, "Content-Encoding"); |
|
| 130 |
found = 1; |
found = 1; |
| 131 |
|
if (hdrs) { |
| 132 |
|
apr_table_unset(hdrs, "Content-Encoding"); |
| 133 |
|
} |
| 134 |
|
else { |
| 135 |
|
r->content_encoding = NULL; |
| 136 |
|
} |
| 137 |
} |
} |
| 138 |
break; /* seen all tokens */ |
break; /* seen all tokens */ |
| 139 |
} |
} |
| 141 |
if (!strcasecmp(ptr, "gzip") |
if (!strcasecmp(ptr, "gzip") |
| 142 |
|| !strcasecmp(ptr, "x-gzip")) { |
|| !strcasecmp(ptr, "x-gzip")) { |
| 143 |
*token = '\0'; |
*token = '\0'; |
| 144 |
|
if (hdrs) { |
| 145 |
apr_table_setn(hdrs, "Content-Encoding", new_encoding); |
apr_table_setn(hdrs, "Content-Encoding", new_encoding); |
| 146 |
|
} |
| 147 |
|
else { |
| 148 |
|
r->content_encoding = new_encoding; |
| 149 |
|
} |
| 150 |
found = 1; |
found = 1; |
| 151 |
} |
} |
| 152 |
else if (!ptr[0] || !strcasecmp(ptr, "identity")) { |
else if (!ptr[0] || !strcasecmp(ptr, "identity")) { |
| 761 |
* |
* |
| 762 |
* If not, we just remove ourself. |
* If not, we just remove ourself. |
| 763 |
*/ |
*/ |
| 764 |
if (check_gzip(r->pool, r->headers_in, NULL, NULL) == 0) { |
if (check_gzip(r, r->headers_in, NULL) == 0) { |
| 765 |
ap_remove_input_filter(f); |
ap_remove_input_filter(f); |
| 766 |
return ap_get_brigade(f->next, bb, mode, block, readbytes); |
return ap_get_brigade(f->next, bb, mode, block, readbytes); |
| 767 |
} |
} |
| 1016 |
* Let's see what our current Content-Encoding is. |
* Let's see what our current Content-Encoding is. |
| 1017 |
* Only inflate if gzipped. |
* Only inflate if gzipped. |
| 1018 |
*/ |
*/ |
| 1019 |
if (check_gzip(r->pool, r->headers_out, r->err_headers_out, |
if (check_gzip(r, r->headers_out, r->err_headers_out) == 0) { |
|
r->content_encoding) == 0) { |
|
| 1020 |
ap_remove_output_filter(f); |
ap_remove_output_filter(f); |
| 1021 |
return ap_pass_brigade(f->next, bb); |
return ap_pass_brigade(f->next, bb); |
| 1022 |
} |
} |