mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-16 08:24:42 +00:00
MEDIUM: compression: add a distinction between UA- and config- algorithms
Thanks to MSIE/IIS, the "deflate" name is ambigous. According to the RFC it's a zlib-wrapped deflate stream, but IIS used to send only a raw deflate stream, which is the only format MSIE understands for "deflate". The other widely used browsers do support both formats. For this reason some people prefer to emit a raw deflate stream on "deflate" to serve more users even it that means violating the standards. Haproxy only follows the standard, so they cannot do this. This patch makes it possible to have one algorithm name in the configuration and another one in the protocol. This will make it possible to have a new configuration token to add a different algorithm so that users can decide if they want a raw deflate or the standard one.
This commit is contained in:
parent
9f640a1eab
commit
615105e7e8
@ -47,9 +47,19 @@ struct comp_ctx {
|
||||
int cur_lvl;
|
||||
};
|
||||
|
||||
/* Thanks to MSIE/IIS, the "deflate" name is ambigous, as according to the RFC
|
||||
* it's a zlib-wrapped deflate stream, but MSIE only understands a raw deflate
|
||||
* stream. For this reason some people prefer to emit a raw deflate stream on
|
||||
* "deflate" and we'll need two algos for the same name, they are distinguished
|
||||
* with the config name.
|
||||
*/
|
||||
struct comp_algo {
|
||||
char *name;
|
||||
int name_len;
|
||||
char *cfg_name; /* config name */
|
||||
int cfg_name_len;
|
||||
|
||||
char *ua_name; /* name for the user-agent */
|
||||
int ua_name_len;
|
||||
|
||||
int (*init)(struct comp_ctx **comp_ctx, int level);
|
||||
int (*add_data)(struct comp_ctx *comp_ctx, const char *in_data, int in_len, struct buffer *out);
|
||||
int (*flush)(struct comp_ctx *comp_ctx, struct buffer *out, int flag);
|
||||
|
@ -73,12 +73,12 @@ static int deflate_end(struct comp_ctx **comp_ctx);
|
||||
|
||||
const struct comp_algo comp_algos[] =
|
||||
{
|
||||
{ "identity", 8, identity_init, identity_add_data, identity_flush, identity_reset, identity_end },
|
||||
{ "identity", 8, "identity", 8, identity_init, identity_add_data, identity_flush, identity_reset, identity_end },
|
||||
#ifdef USE_ZLIB
|
||||
{ "deflate", 7, deflate_init, deflate_add_data, deflate_flush, deflate_reset, deflate_end },
|
||||
{ "gzip", 4, gzip_init, deflate_add_data, deflate_flush, deflate_reset, deflate_end },
|
||||
{ "deflate", 7, "deflate", 7, deflate_init, deflate_add_data, deflate_flush, deflate_reset, deflate_end },
|
||||
{ "gzip", 4, "gzip", 4, gzip_init, deflate_add_data, deflate_flush, deflate_reset, deflate_end },
|
||||
#endif /* USE_ZLIB */
|
||||
{ NULL, 0, NULL , NULL, NULL, NULL, NULL }
|
||||
{ NULL, 0, NULL, 0, NULL , NULL, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
/*
|
||||
@ -104,8 +104,8 @@ int comp_append_algo(struct comp *comp, const char *algo)
|
||||
struct comp_algo *comp_algo;
|
||||
int i;
|
||||
|
||||
for (i = 0; comp_algos[i].name; i++) {
|
||||
if (!strcmp(algo, comp_algos[i].name)) {
|
||||
for (i = 0; comp_algos[i].cfg_name; i++) {
|
||||
if (!strcmp(algo, comp_algos[i].cfg_name)) {
|
||||
comp_algo = calloc(1, sizeof(struct comp_algo));
|
||||
memmove(comp_algo, &comp_algos[i], sizeof(struct comp_algo));
|
||||
comp_algo->next = comp->algos;
|
||||
@ -669,8 +669,8 @@ smp_fetch_res_comp_algo(struct proxy *px, struct session *l4, void *l7, unsigned
|
||||
|
||||
smp->type = SMP_T_STR;
|
||||
smp->flags = SMP_F_CONST;
|
||||
smp->data.str.str = l4->comp_algo->name;
|
||||
smp->data.str.len = l4->comp_algo->name_len;
|
||||
smp->data.str.str = l4->comp_algo->cfg_name;
|
||||
smp->data.str.len = l4->comp_algo->cfg_name_len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -262,8 +262,8 @@ void display_build_opts()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; comp_algos[i].name; i++) {
|
||||
printf("%s %s", (i == 0 ? "" : ","), comp_algos[i].name);
|
||||
for (i = 0; comp_algos[i].cfg_name; i++) {
|
||||
printf("%s %s(\"%s\")", (i == 0 ? "" : ","), comp_algos[i].cfg_name, comp_algos[i].ua_name);
|
||||
}
|
||||
if (i == 0) {
|
||||
printf("none");
|
||||
|
@ -2309,7 +2309,7 @@ int select_compression_request_header(struct session *s, struct buffer *req)
|
||||
|
||||
for (comp_algo = comp_algo_back; comp_algo; comp_algo = comp_algo->next) {
|
||||
if (*(ctx.line + ctx.val) == '*' ||
|
||||
word_match(ctx.line + ctx.val, toklen, comp_algo->name, comp_algo->name_len)) {
|
||||
word_match(ctx.line + ctx.val, toklen, comp_algo->ua_name, comp_algo->ua_name_len)) {
|
||||
s->comp_algo = comp_algo;
|
||||
best_q = q;
|
||||
break;
|
||||
@ -2333,7 +2333,7 @@ int select_compression_request_header(struct session *s, struct buffer *req)
|
||||
/* identity is implicit does not require headers */
|
||||
if ((s->be->comp && (comp_algo_back = s->be->comp->algos)) || (s->fe->comp && (comp_algo_back = s->fe->comp->algos))) {
|
||||
for (comp_algo = comp_algo_back; comp_algo; comp_algo = comp_algo->next) {
|
||||
if (comp_algo->name_len == 8 && memcmp(comp_algo->name, "identity", 8) == 0) {
|
||||
if (comp_algo->cfg_name_len == 8 && memcmp(comp_algo->cfg_name, "identity", 8) == 0) {
|
||||
s->comp_algo = comp_algo;
|
||||
return 1;
|
||||
}
|
||||
@ -2445,11 +2445,11 @@ int select_compression_response_header(struct session *s, struct buffer *res)
|
||||
* Accept-Encoding header, and SHOULD NOT be used in the Content-Encoding
|
||||
* header.
|
||||
*/
|
||||
if (s->comp_algo->name_len != 8 || memcmp(s->comp_algo->name, "identity", 8) != 0) {
|
||||
if (s->comp_algo->cfg_name_len != 8 || memcmp(s->comp_algo->cfg_name, "identity", 8) != 0) {
|
||||
trash.len = 18;
|
||||
memcpy(trash.str, "Content-Encoding: ", trash.len);
|
||||
memcpy(trash.str + trash.len, s->comp_algo->name, s->comp_algo->name_len);
|
||||
trash.len += s->comp_algo->name_len;
|
||||
memcpy(trash.str + trash.len, s->comp_algo->ua_name, s->comp_algo->ua_name_len);
|
||||
trash.len += s->comp_algo->ua_name_len;
|
||||
trash.str[trash.len] = '\0';
|
||||
http_header_add_tail2(&txn->rsp, &txn->hdr_idx, trash.str, trash.len);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user