]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: http: factor out the content-type checks
authorWilly Tarreau <w@1wt.eu>
Mon, 26 Nov 2012 15:33:37 +0000 (16:33 +0100)
committerWilly Tarreau <w@1wt.eu>
Mon, 26 Nov 2012 15:36:00 +0000 (16:36 +0100)
Let's only look up the content-type header once. This involves
inverting the condition which is not dramatic.

Also, we now always check the value length before comparing it, and we
always reset the ctx.idx before looking a header up. Otherwise that
could make header lookups depend on their on-wire order. It would be
a minor issue however since at worst it would cause some responses not
to be compressed.

src/proto_http.c

index f36c7b590e4d8c5d5603de5588fa4b04c4550811..6f1b9d796b0a68e16758015942e9d02617c33f8b 100644 (file)
@@ -2064,44 +2064,43 @@ int select_compression_response_header(struct session *s, struct buffer *res)
        if (txn->status != 200)
                goto fail;
 
-       ctx.idx = 0;
-
        /* Content-Length is null */
        if (!(msg->flags & HTTP_MSGF_TE_CHNK) && msg->body_len == 0)
                goto fail;
 
        /* content is already compressed */
+       ctx.idx = 0;
        if (http_find_header2("Content-Encoding", 16, res->p, &txn->hdr_idx, &ctx))
                goto fail;
 
        comp_type = NULL;
 
-       /* if there was a compression content-type option in the backend or the frontend
-        * The backend have priority.
+       /* we don't want to compress multipart content-types, nor content-types that are
+        * not listed in the "compression type" directive if any. If no content-type was
+        * found but configuration requires one, we don't compress either. Backend has
+        * the priority.
         */
-       if ((s->be->comp && (comp_type = s->be->comp->types)) || (s->fe->comp && (comp_type = s->fe->comp->types))) {
-               if (http_find_header2("Content-Type", 12, res->p, &txn->hdr_idx, &ctx)) {
+       ctx.idx = 0;
+       if (http_find_header2("Content-Type", 12, res->p, &txn->hdr_idx, &ctx)) {
+               if (ctx.vlen >= 9 && strncasecmp("multipart", ctx.line+ctx.val, 9) == 0)
+                       goto fail;
+
+               if ((s->be->comp && (comp_type = s->be->comp->types)) ||
+                   (s->fe->comp && (comp_type = s->fe->comp->types))) {
                        for (; comp_type; comp_type = comp_type->next) {
-                               if (strncasecmp(ctx.line+ctx.val, comp_type->name, comp_type->name_len) == 0)
+                               if (ctx.vlen >= comp_type->name_len &&
+                                   strncasecmp(ctx.line+ctx.val, comp_type->name, comp_type->name_len) == 0)
                                        /* this Content-Type should be compressed */
                                        break;
                        }
-               } else {
-                       /* there is no Content-Type header */
-                       goto fail;
+                       /* this Content-Type should not be compressed */
+                       if (comp_type == NULL)
+                               goto fail;
                }
-               /* this Content-Type should not be compressed */
-               if (comp_type == NULL)
-                       goto fail;
        }
-
-       ctx.idx = 0;
-
-       /* Don't compress multipart */
-       if (http_find_header2("Content-Type", 12, res->p, &txn->hdr_idx, &ctx)) {
-               if (strncasecmp("multipart", ctx.line+ctx.val, 9) == 0)
-                       goto fail;
-
+       else { /* no content-type header */
+               if ((s->be->comp && s->be->comp->types) || (s->fe->comp && s->fe->comp->types))
+                       goto fail; /* a content-type was required */
        }
 
        /* limit compression rate */
@@ -2120,6 +2119,7 @@ int select_compression_response_header(struct session *s, struct buffer *res)
        s->flags |= SN_COMP_READY;
 
        /* remove Content-Length header */
+       ctx.idx = 0;
        if ((msg->flags & HTTP_MSGF_CNT_LEN) && http_find_header2("Content-Length", 14, res->p, &txn->hdr_idx, &ctx))
                http_remove_header2(msg, &txn->hdr_idx, &ctx);