~ubuntu-branches/debian/stretch/haproxy/stretch

« back to all changes in this revision

Viewing changes to src/proto_http.c

  • Committer: Package Import Robot
  • Author(s): Vincent Bernat
  • Date: 2015-05-02 16:38:28 UTC
  • mfrom: (1.3.13)
  • Revision ID: package-import@ubuntu.com-20150502163828-lph2toctaqrw41x5
Tags: 1.5.12-1
* New upstream stable release including the following fixes:
  - BUG/MAJOR: http: don't read past buffer's end in http_replace_value
  - BUG/MAJOR: http: prevent risk of reading past end with balance
               url_param
  - BUG/MEDIUM: Do not consider an agent check as failed on L7 error
  - BUG/MEDIUM: patern: some entries are not deleted with case
                insensitive match
  - BUG/MEDIUM: buffer: one byte miss in buffer free space check
  - BUG/MEDIUM: http: thefunction "(req|res)-replace-value" doesn't
                respect the HTTP syntax
  - BUG/MEDIUM: peers: correctly configure the client timeout
  - BUG/MEDIUM: http: hdr_cnt would not count any header when called
                without name
  - BUG/MEDIUM: listener: don't report an error when resuming unbound
                listeners
  - BUG/MEDIUM: init: don't limit cpu-map to the first 32 processes only
  - BUG/MEDIUM: stream-int: always reset si->ops when si->end is
                nullified
  - BUG/MEDIUM: http: remove content-length from chunked messages
  - BUG/MEDIUM: http: do not restrict parsing of transfer-encoding to
                HTTP/1.1
  - BUG/MEDIUM: http: incorrect transfer-coding in the request is a bad
                request
  - BUG/MEDIUM: http: remove content-length form responses with bad
                transfer-encoding
  - BUG/MEDIUM: http: wait for the exact amount of body bytes in
                wait_for_request_body

Show diffs side-by-side

added added

removed removed

Lines of Context:
2478
2478
         */
2479
2479
 
2480
2480
        int cur_idx;
2481
 
        int use_close_only;
2482
2481
        struct http_txn *txn = &s->txn;
2483
2482
        struct http_msg *msg = &txn->req;
2484
2483
        struct hdr_ctx ctx;
2621
2620
                        if (txn->flags & TX_WAIT_NEXT_RQ)
2622
2621
                                goto failed_keep_alive;
2623
2622
 
 
2623
                        if (s->fe->options & PR_O_IGNORE_PRB)
 
2624
                                goto failed_keep_alive;
 
2625
 
2624
2626
                        /* we cannot return any message on error */
2625
2627
                        if (msg->err_pos >= 0) {
2626
2628
                                http_capture_bad_message(&s->fe->invalid_req, s, msg, msg->msg_state, s->fe);
2651
2653
                        if (txn->flags & TX_WAIT_NEXT_RQ)
2652
2654
                                goto failed_keep_alive;
2653
2655
 
 
2656
                        if (s->fe->options & PR_O_IGNORE_PRB)
 
2657
                                goto failed_keep_alive;
 
2658
 
2654
2659
                        /* read timeout : give up with an error message. */
2655
2660
                        if (msg->err_pos >= 0) {
2656
2661
                                http_capture_bad_message(&s->fe->invalid_req, s, msg, msg->msg_state, s->fe);
2680
2685
                        if (txn->flags & TX_WAIT_NEXT_RQ)
2681
2686
                                goto failed_keep_alive;
2682
2687
 
 
2688
                        if (s->fe->options & PR_O_IGNORE_PRB)
 
2689
                                goto failed_keep_alive;
 
2690
 
2683
2691
                        if (msg->err_pos >= 0)
2684
2692
                                http_capture_bad_message(&s->fe->invalid_req, s, msg, msg->msg_state, s->fe);
2685
2693
                        txn->status = 400;
2854
2862
        if (unlikely(msg->sl.rq.v_l == 0) && !http_upgrade_v09_to_v10(txn))
2855
2863
                goto return_bad_req;
2856
2864
 
 
2865
        /* RFC7230#2.6 has enforced the format of the HTTP version string to be
 
2866
         * exactly one digit "." one digit. This check may be disabled using
 
2867
         * option accept-invalid-http-request.
 
2868
         */
 
2869
        if (!(s->fe->options2 & PR_O2_REQBUG_OK)) {
 
2870
                if (msg->sl.rq.v_l != 8) {
 
2871
                        msg->err_pos = msg->sl.rq.v;
 
2872
                        goto return_bad_req;
 
2873
                }
 
2874
 
 
2875
                if (req->buf->p[msg->sl.rq.v + 4] != '/' ||
 
2876
                    !isdigit((unsigned char)req->buf->p[msg->sl.rq.v + 5]) ||
 
2877
                    req->buf->p[msg->sl.rq.v + 6] != '.' ||
 
2878
                    !isdigit((unsigned char)req->buf->p[msg->sl.rq.v + 7])) {
 
2879
                        msg->err_pos = msg->sl.rq.v + 4;
 
2880
                        goto return_bad_req;
 
2881
                }
 
2882
        }
 
2883
 
2857
2884
        /* ... and check if the request is HTTP/1.1 or above */
2858
2885
        if ((msg->sl.rq.v_l == 8) &&
2859
2886
            ((req->buf->p[msg->sl.rq.v + 5] > '1') ||
2885
2912
                capture_headers(req->buf->p, &txn->hdr_idx,
2886
2913
                                txn->req.cap, s->fe->req_cap);
2887
2914
 
2888
 
        /* 6: determine the transfer-length.
2889
 
         * According to RFC2616 #4.4, amended by the HTTPbis working group,
2890
 
         * the presence of a message-body in a REQUEST and its transfer length
2891
 
         * must be determined that way (in order of precedence) :
2892
 
         *   1. The presence of a message-body in a request is signaled by the
2893
 
         *      inclusion of a Content-Length or Transfer-Encoding header field
2894
 
         *      in the request's header fields.  When a request message contains
2895
 
         *      both a message-body of non-zero length and a method that does
2896
 
         *      not define any semantics for that request message-body, then an
2897
 
         *      origin server SHOULD either ignore the message-body or respond
2898
 
         *      with an appropriate error message (e.g., 413).  A proxy or
2899
 
         *      gateway, when presented the same request, SHOULD either forward
2900
 
         *      the request inbound with the message- body or ignore the
2901
 
         *      message-body when determining a response.
2902
 
         *
2903
 
         *   2. If a Transfer-Encoding header field (Section 9.7) is present
2904
 
         *      and the "chunked" transfer-coding (Section 6.2) is used, the
2905
 
         *      transfer-length is defined by the use of this transfer-coding.
2906
 
         *      If a Transfer-Encoding header field is present and the "chunked"
2907
 
         *      transfer-coding is not present, the transfer-length is defined
2908
 
         *      by the sender closing the connection.
2909
 
         *
2910
 
         *   3. If a Content-Length header field is present, its decimal value in
2911
 
         *      OCTETs represents both the entity-length and the transfer-length.
2912
 
         *      If a message is received with both a Transfer-Encoding header
2913
 
         *      field and a Content-Length header field, the latter MUST be ignored.
2914
 
         *
2915
 
         *   4. By the server closing the connection. (Closing the connection
2916
 
         *      cannot be used to indicate the end of a request body, since that
2917
 
         *      would leave no possibility for the server to send back a response.)
2918
 
         *
2919
 
         *   Whenever a transfer-coding is applied to a message-body, the set of
2920
 
         *   transfer-codings MUST include "chunked", unless the message indicates
2921
 
         *   it is terminated by closing the connection.  When the "chunked"
2922
 
         *   transfer-coding is used, it MUST be the last transfer-coding applied
2923
 
         *   to the message-body.
 
2915
        /* 6: determine the transfer-length according to RFC2616 #4.4, updated
 
2916
         * by RFC7230#3.3.3 :
 
2917
         *
 
2918
         * The length of a message body is determined by one of the following
 
2919
         *   (in order of precedence):
 
2920
         *
 
2921
         *   1.  Any response to a HEAD request and any response with a 1xx
 
2922
         *       (Informational), 204 (No Content), or 304 (Not Modified) status
 
2923
         *       code is always terminated by the first empty line after the
 
2924
         *       header fields, regardless of the header fields present in the
 
2925
         *       message, and thus cannot contain a message body.
 
2926
         *
 
2927
         *   2.  Any 2xx (Successful) response to a CONNECT request implies that
 
2928
         *       the connection will become a tunnel immediately after the empty
 
2929
         *       line that concludes the header fields.  A client MUST ignore any
 
2930
         *       Content-Length or Transfer-Encoding header fields received in
 
2931
         *       such a message.
 
2932
         *
 
2933
         *   3.  If a Transfer-Encoding header field is present and the chunked
 
2934
         *       transfer coding (Section 4.1) is the final encoding, the message
 
2935
         *       body length is determined by reading and decoding the chunked
 
2936
         *       data until the transfer coding indicates the data is complete.
 
2937
         *
 
2938
         *       If a Transfer-Encoding header field is present in a response and
 
2939
         *       the chunked transfer coding is not the final encoding, the
 
2940
         *       message body length is determined by reading the connection until
 
2941
         *       it is closed by the server.  If a Transfer-Encoding header field
 
2942
         *       is present in a request and the chunked transfer coding is not
 
2943
         *       the final encoding, the message body length cannot be determined
 
2944
         *       reliably; the server MUST respond with the 400 (Bad Request)
 
2945
         *       status code and then close the connection.
 
2946
         *
 
2947
         *       If a message is received with both a Transfer-Encoding and a
 
2948
         *       Content-Length header field, the Transfer-Encoding overrides the
 
2949
         *       Content-Length.  Such a message might indicate an attempt to
 
2950
         *       perform request smuggling (Section 9.5) or response splitting
 
2951
         *       (Section 9.4) and ought to be handled as an error.  A sender MUST
 
2952
         *       remove the received Content-Length field prior to forwarding such
 
2953
         *       a message downstream.
 
2954
         *
 
2955
         *   4.  If a message is received without Transfer-Encoding and with
 
2956
         *       either multiple Content-Length header fields having differing
 
2957
         *       field-values or a single Content-Length header field having an
 
2958
         *       invalid value, then the message framing is invalid and the
 
2959
         *       recipient MUST treat it as an unrecoverable error.  If this is a
 
2960
         *       request message, the server MUST respond with a 400 (Bad Request)
 
2961
         *       status code and then close the connection.  If this is a response
 
2962
         *       message received by a proxy, the proxy MUST close the connection
 
2963
         *       to the server, discard the received response, and send a 502 (Bad
 
2964
         *       Gateway) response to the client.  If this is a response message
 
2965
         *       received by a user agent, the user agent MUST close the
 
2966
         *       connection to the server and discard the received response.
 
2967
         *
 
2968
         *   5.  If a valid Content-Length header field is present without
 
2969
         *       Transfer-Encoding, its decimal value defines the expected message
 
2970
         *       body length in octets.  If the sender closes the connection or
 
2971
         *       the recipient times out before the indicated number of octets are
 
2972
         *       received, the recipient MUST consider the message to be
 
2973
         *       incomplete and close the connection.
 
2974
         *
 
2975
         *   6.  If this is a request message and none of the above are true, then
 
2976
         *       the message body length is zero (no message body is present).
 
2977
         *
 
2978
         *   7.  Otherwise, this is a response message without a declared message
 
2979
         *       body length, so the message body length is determined by the
 
2980
         *       number of octets received prior to the server closing the
 
2981
         *       connection.
2924
2982
         */
2925
2983
 
2926
 
        use_close_only = 0;
2927
2984
        ctx.idx = 0;
2928
2985
        /* set TE_CHNK and XFER_LEN only if "chunked" is seen last */
2929
 
        while ((msg->flags & HTTP_MSGF_VER_11) &&
2930
 
               http_find_header2("Transfer-Encoding", 17, req->buf->p, &txn->hdr_idx, &ctx)) {
 
2986
        while (http_find_header2("Transfer-Encoding", 17, req->buf->p, &txn->hdr_idx, &ctx)) {
2931
2987
                if (ctx.vlen == 7 && strncasecmp(ctx.line + ctx.val, "chunked", 7) == 0)
2932
2988
                        msg->flags |= (HTTP_MSGF_TE_CHNK | HTTP_MSGF_XFER_LEN);
2933
2989
                else if (msg->flags & HTTP_MSGF_TE_CHNK) {
2934
 
                        /* bad transfer-encoding (chunked followed by something else) */
2935
 
                        use_close_only = 1;
2936
 
                        msg->flags &= ~(HTTP_MSGF_TE_CHNK | HTTP_MSGF_XFER_LEN);
2937
 
                        break;
 
2990
                        /* chunked not last, return badreq */
 
2991
                        goto return_bad_req;
2938
2992
                }
2939
2993
        }
2940
2994
 
 
2995
        /* Chunked requests must have their content-length removed */
2941
2996
        ctx.idx = 0;
2942
 
        while (!(msg->flags & HTTP_MSGF_TE_CHNK) && !use_close_only &&
2943
 
               http_find_header2("Content-Length", 14, req->buf->p, &txn->hdr_idx, &ctx)) {
 
2997
        if (msg->flags & HTTP_MSGF_TE_CHNK) {
 
2998
                while (http_find_header2("Content-Length", 14, req->buf->p, &txn->hdr_idx, &ctx))
 
2999
                        http_remove_header2(msg, &txn->hdr_idx, &ctx);
 
3000
        }
 
3001
        else while (http_find_header2("Content-Length", 14, req->buf->p, &txn->hdr_idx, &ctx)) {
2944
3002
                signed long long cl;
2945
3003
 
2946
3004
                if (!ctx.vlen) {
2967
3025
                msg->body_len = msg->chunk_len = cl;
2968
3026
        }
2969
3027
 
2970
 
        /* bodyless requests have a known length */
2971
 
        if (!use_close_only)
2972
 
                msg->flags |= HTTP_MSGF_XFER_LEN;
 
3028
        /* even bodyless requests have a known length */
 
3029
        msg->flags |= HTTP_MSGF_XFER_LEN;
2973
3030
 
2974
3031
        /* Until set to anything else, the connection mode is set as Keep-Alive. It will
2975
3032
         * only change if both the request and the config reference something else.
3179
3236
#endif
3180
3237
}
3181
3238
 
3182
 
/* Returns the number of characters written to destination,
3183
 
 * -1 on internal error and -2 if no replacement took place.
3184
 
 */
3185
 
static int http_replace_header(struct my_regex *re, char *dst, uint dst_size, char *val, int len,
3186
 
                               const char *rep_str)
3187
 
{
3188
 
        if (!regex_exec_match2(re, val, len, MAX_MATCH, pmatch))
3189
 
                return -2;
3190
 
 
3191
 
        return exp_replace(dst, dst_size, val, rep_str, pmatch);
3192
 
}
3193
 
 
3194
 
/* Returns the number of characters written to destination,
3195
 
 * -1 on internal error and -2 if no replacement took place.
3196
 
 */
3197
 
static int http_replace_value(struct my_regex *re, char *dst, uint dst_size, char *val, int len, char delim,
3198
 
                              const char *rep_str)
3199
 
{
3200
 
        char* p = val;
3201
 
        char* dst_end = dst + dst_size;
3202
 
        char* dst_p = dst;
3203
 
 
3204
 
        for (;;) {
3205
 
                char *p_delim;
3206
 
 
3207
 
                /* look for delim. */
3208
 
                p_delim = p;
3209
 
                while (p_delim < p + len && *p_delim != delim)
3210
 
                        p_delim++;
3211
 
 
3212
 
                if (regex_exec_match2(re, p, p_delim-p, MAX_MATCH, pmatch)) {
3213
 
                        int replace_n = exp_replace(dst_p, dst_end - dst_p, p, rep_str, pmatch);
3214
 
 
3215
 
                        if (replace_n < 0)
3216
 
                                return -1;
3217
 
 
3218
 
                        dst_p += replace_n;
3219
 
                } else {
3220
 
                        uint len = p_delim - p;
3221
 
 
3222
 
                        if (dst_p + len >= dst_end)
3223
 
                                return -1;
3224
 
 
3225
 
                        memcpy(dst_p, p, len);
3226
 
                        dst_p += len;
3227
 
                }
3228
 
 
3229
 
                if (dst_p >= dst_end)
3230
 
                        return -1;
3231
 
 
3232
 
                /* end of the replacements. */
3233
 
                if (p_delim >= p + len)
3234
 
                        break;
3235
 
 
3236
 
                /* Next part. */
3237
 
                *dst_p++ = delim;
3238
 
                p = p_delim + 1;
3239
 
        }
3240
 
 
3241
 
        return dst_p - dst;
3242
 
}
3243
 
 
3244
3239
static int http_transform_header(struct session* s, struct http_msg *msg, const char* name, uint name_len,
3245
3240
                                 char* buf, struct hdr_idx* idx, struct list *fmt, struct my_regex *re,
3246
3241
                                 struct hdr_ctx* ctx, int action)
3247
3242
{
 
3243
        int (*http_find_hdr_func)(const char *name, int len, char *sol,
 
3244
                                  struct hdr_idx *idx, struct hdr_ctx *ctx);
 
3245
        struct chunk *replace = get_trash_chunk();
 
3246
        struct chunk *output = get_trash_chunk();
 
3247
 
 
3248
        replace->len = build_logline(s, replace->str, replace->size, fmt);
 
3249
        if (replace->len >= replace->size - 1)
 
3250
                return -1;
 
3251
 
3248
3252
        ctx->idx = 0;
3249
3253
 
3250
 
        while (http_find_full_header2(name, name_len, buf, idx, ctx)) {
 
3254
        /* Choose the header browsing function. */
 
3255
        switch (action) {
 
3256
        case HTTP_REQ_ACT_REPLACE_VAL:
 
3257
        case HTTP_RES_ACT_REPLACE_VAL:
 
3258
                http_find_hdr_func = http_find_header2;
 
3259
                break;
 
3260
        case HTTP_REQ_ACT_REPLACE_HDR:
 
3261
        case HTTP_RES_ACT_REPLACE_HDR:
 
3262
                http_find_hdr_func = http_find_full_header2;
 
3263
                break;
 
3264
        default: /* impossible */
 
3265
                return -1;
 
3266
        }
 
3267
 
 
3268
        while (http_find_hdr_func(name, name_len, buf, idx, ctx)) {
3251
3269
                struct hdr_idx_elem *hdr = idx->v + ctx->idx;
3252
3270
                int delta;
3253
 
                char* val = (char*)ctx->line + ctx->val;
3254
 
                char* val_end = (char*)ctx->line + hdr->len;
3255
 
                char* reg_dst_buf;
3256
 
                uint reg_dst_buf_size;
3257
 
                int n_replaced;
3258
 
 
3259
 
                trash.len = build_logline(s, trash.str, trash.size, fmt);
3260
 
 
3261
 
                if (trash.len >= trash.size - 1)
3262
 
                        return -1;
3263
 
 
3264
 
                reg_dst_buf = trash.str + trash.len + 1;
3265
 
                reg_dst_buf_size = trash.size - trash.len - 1;
3266
 
 
3267
 
                switch (action) {
3268
 
                case HTTP_REQ_ACT_REPLACE_VAL:
3269
 
                case HTTP_RES_ACT_REPLACE_VAL:
3270
 
                        n_replaced = http_replace_value(re, reg_dst_buf, reg_dst_buf_size, val, val_end-val, ',', trash.str);
3271
 
                        break;
3272
 
                case HTTP_REQ_ACT_REPLACE_HDR:
3273
 
                case HTTP_RES_ACT_REPLACE_HDR:
3274
 
                        n_replaced = http_replace_header(re, reg_dst_buf, reg_dst_buf_size, val, val_end-val, trash.str);
3275
 
                        break;
3276
 
                default: /* impossible */
3277
 
                        return -1;
3278
 
                }
3279
 
 
3280
 
                switch (n_replaced) {
3281
 
                case -1: return -1;
3282
 
                case -2: continue;
3283
 
                }
3284
 
 
3285
 
                delta = buffer_replace2(msg->chn->buf, val, val_end, reg_dst_buf, n_replaced);
 
3271
                char *val = ctx->line + ctx->val;
 
3272
                char* val_end = val + ctx->vlen;
 
3273
 
 
3274
                if (!regex_exec_match2(re, val, val_end-val, MAX_MATCH, pmatch))
 
3275
                        continue;
 
3276
 
 
3277
                output->len = exp_replace(output->str, output->size, val, replace->str, pmatch);
 
3278
                if (output->len == -1)
 
3279
                        return -1;
 
3280
 
 
3281
                delta = buffer_replace2(msg->chn->buf, val, val_end, output->str, output->len);
3286
3282
 
3287
3283
                hdr->len += delta;
3288
3284
                http_msg_move_end(msg, delta);
 
3285
 
 
3286
                /* Adjust the length of the current value of the index. */
 
3287
                ctx->vlen += delta;
3289
3288
        }
3290
3289
 
3291
3290
        return 0;
4649
4648
 
4650
4649
        if (!(msg->flags & HTTP_MSGF_TE_CHNK)) {
4651
4650
                /* We're in content-length mode, we just have to wait for enough data. */
4652
 
                if (req->buf->i - msg->sov < msg->body_len)
 
4651
                if (http_body_bytes(msg) < msg->body_len)
4653
4652
                        goto missing_data;
4654
4653
 
4655
4654
                /* OK we have everything we need now */
4674
4673
        }
4675
4674
 
4676
4675
        /* Now we're in HTTP_MSG_DATA or HTTP_MSG_TRAILERS state.
4677
 
         * We have the first data byte is in msg->sov. We're waiting for at
4678
 
         * least a whole chunk or the whole content length bytes after msg->sov.
 
4676
         * We have the first data byte is in msg->sov + msg->sol. We're waiting
 
4677
         * for at least a whole chunk or the whole content length bytes after
 
4678
         * msg->sov + msg->sol.
4679
4679
         */
4680
4680
        if (msg->msg_state == HTTP_MSG_TRAILERS)
4681
4681
                goto http_end;
4682
4682
 
4683
 
        if (req->buf->i - msg->sov >= msg->body_len)   /* we have enough bytes now */
 
4683
        if (http_body_bytes(msg) >= msg->body_len)   /* we have enough bytes now */
4684
4684
                goto http_end;
4685
4685
 
4686
4686
 missing_data:
5899
5899
        if (objt_server(s->target))
5900
5900
                objt_server(s->target)->counters.p.http.rsp[n]++;
5901
5901
 
 
5902
        /* RFC7230#2.6 has enforced the format of the HTTP version string to be
 
5903
         * exactly one digit "." one digit. This check may be disabled using
 
5904
         * option accept-invalid-http-response.
 
5905
         */
 
5906
        if (!(s->be->options2 & PR_O2_RSPBUG_OK)) {
 
5907
                if (msg->sl.st.v_l != 8) {
 
5908
                        msg->err_pos = 0;
 
5909
                        goto hdr_response_bad;
 
5910
                }
 
5911
 
 
5912
                if (rep->buf->p[4] != '/' ||
 
5913
                    !isdigit((unsigned char)rep->buf->p[5]) ||
 
5914
                    rep->buf->p[6] != '.' ||
 
5915
                    !isdigit((unsigned char)rep->buf->p[7])) {
 
5916
                        msg->err_pos = 4;
 
5917
                        goto hdr_response_bad;
 
5918
                }
 
5919
        }
 
5920
 
5902
5921
        /* check if the response is HTTP/1.1 or above */
5903
5922
        if ((msg->sl.st.v_l == 8) &&
5904
5923
            ((rep->buf->p[5] > '1') ||
5976
5995
                capture_headers(rep->buf->p, &txn->hdr_idx,
5977
5996
                                txn->rsp.cap, s->fe->rsp_cap);
5978
5997
 
5979
 
        /* 4: determine the transfer-length.
5980
 
         * According to RFC2616 #4.4, amended by the HTTPbis working group,
5981
 
         * the presence of a message-body in a RESPONSE and its transfer length
5982
 
         * must be determined that way :
5983
 
         *
5984
 
         *   All responses to the HEAD request method MUST NOT include a
5985
 
         *   message-body, even though the presence of entity-header fields
5986
 
         *   might lead one to believe they do.  All 1xx (informational), 204
5987
 
         *   (No Content), and 304 (Not Modified) responses MUST NOT include a
5988
 
         *   message-body.  All other responses do include a message-body,
5989
 
         *   although it MAY be of zero length.
5990
 
         *
5991
 
         *   1. Any response which "MUST NOT" include a message-body (such as the
5992
 
         *      1xx, 204 and 304 responses and any response to a HEAD request) is
5993
 
         *      always terminated by the first empty line after the header fields,
5994
 
         *      regardless of the entity-header fields present in the message.
5995
 
         *
5996
 
         *   2. If a Transfer-Encoding header field (Section 9.7) is present and
5997
 
         *      the "chunked" transfer-coding (Section 6.2) is used, the
5998
 
         *      transfer-length is defined by the use of this transfer-coding.
5999
 
         *      If a Transfer-Encoding header field is present and the "chunked"
6000
 
         *      transfer-coding is not present, the transfer-length is defined by
6001
 
         *      the sender closing the connection.
6002
 
         *
6003
 
         *   3. If a Content-Length header field is present, its decimal value in
6004
 
         *      OCTETs represents both the entity-length and the transfer-length.
6005
 
         *      If a message is received with both a Transfer-Encoding header
6006
 
         *      field and a Content-Length header field, the latter MUST be ignored.
6007
 
         *
6008
 
         *   4. If the message uses the media type "multipart/byteranges", and
6009
 
         *      the transfer-length is not otherwise specified, then this self-
6010
 
         *      delimiting media type defines the transfer-length.  This media
6011
 
         *      type MUST NOT be used unless the sender knows that the recipient
6012
 
         *      can parse it; the presence in a request of a Range header with
6013
 
         *      multiple byte-range specifiers from a 1.1 client implies that the
6014
 
         *      client can parse multipart/byteranges responses.
6015
 
         *
6016
 
         *   5. By the server closing the connection.
 
5998
        /* 4: determine the transfer-length according to RFC2616 #4.4, updated
 
5999
         * by RFC7230#3.3.3 :
 
6000
         *
 
6001
         * The length of a message body is determined by one of the following
 
6002
         *   (in order of precedence):
 
6003
         *
 
6004
         *   1.  Any response to a HEAD request and any response with a 1xx
 
6005
         *       (Informational), 204 (No Content), or 304 (Not Modified) status
 
6006
         *       code is always terminated by the first empty line after the
 
6007
         *       header fields, regardless of the header fields present in the
 
6008
         *       message, and thus cannot contain a message body.
 
6009
         *
 
6010
         *   2.  Any 2xx (Successful) response to a CONNECT request implies that
 
6011
         *       the connection will become a tunnel immediately after the empty
 
6012
         *       line that concludes the header fields.  A client MUST ignore any
 
6013
         *       Content-Length or Transfer-Encoding header fields received in
 
6014
         *       such a message.
 
6015
         *
 
6016
         *   3.  If a Transfer-Encoding header field is present and the chunked
 
6017
         *       transfer coding (Section 4.1) is the final encoding, the message
 
6018
         *       body length is determined by reading and decoding the chunked
 
6019
         *       data until the transfer coding indicates the data is complete.
 
6020
         *
 
6021
         *       If a Transfer-Encoding header field is present in a response and
 
6022
         *       the chunked transfer coding is not the final encoding, the
 
6023
         *       message body length is determined by reading the connection until
 
6024
         *       it is closed by the server.  If a Transfer-Encoding header field
 
6025
         *       is present in a request and the chunked transfer coding is not
 
6026
         *       the final encoding, the message body length cannot be determined
 
6027
         *       reliably; the server MUST respond with the 400 (Bad Request)
 
6028
         *       status code and then close the connection.
 
6029
         *
 
6030
         *       If a message is received with both a Transfer-Encoding and a
 
6031
         *       Content-Length header field, the Transfer-Encoding overrides the
 
6032
         *       Content-Length.  Such a message might indicate an attempt to
 
6033
         *       perform request smuggling (Section 9.5) or response splitting
 
6034
         *       (Section 9.4) and ought to be handled as an error.  A sender MUST
 
6035
         *       remove the received Content-Length field prior to forwarding such
 
6036
         *       a message downstream.
 
6037
         *
 
6038
         *   4.  If a message is received without Transfer-Encoding and with
 
6039
         *       either multiple Content-Length header fields having differing
 
6040
         *       field-values or a single Content-Length header field having an
 
6041
         *       invalid value, then the message framing is invalid and the
 
6042
         *       recipient MUST treat it as an unrecoverable error.  If this is a
 
6043
         *       request message, the server MUST respond with a 400 (Bad Request)
 
6044
         *       status code and then close the connection.  If this is a response
 
6045
         *       message received by a proxy, the proxy MUST close the connection
 
6046
         *       to the server, discard the received response, and send a 502 (Bad
 
6047
         *       Gateway) response to the client.  If this is a response message
 
6048
         *       received by a user agent, the user agent MUST close the
 
6049
         *       connection to the server and discard the received response.
 
6050
         *
 
6051
         *   5.  If a valid Content-Length header field is present without
 
6052
         *       Transfer-Encoding, its decimal value defines the expected message
 
6053
         *       body length in octets.  If the sender closes the connection or
 
6054
         *       the recipient times out before the indicated number of octets are
 
6055
         *       received, the recipient MUST consider the message to be
 
6056
         *       incomplete and close the connection.
 
6057
         *
 
6058
         *   6.  If this is a request message and none of the above are true, then
 
6059
         *       the message body length is zero (no message body is present).
 
6060
         *
 
6061
         *   7.  Otherwise, this is a response message without a declared message
 
6062
         *       body length, so the message body length is determined by the
 
6063
         *       number of octets received prior to the server closing the
 
6064
         *       connection.
6017
6065
         */
6018
6066
 
6019
6067
        /* Skip parsing if no content length is possible. The response flags
6031
6079
 
6032
6080
        use_close_only = 0;
6033
6081
        ctx.idx = 0;
6034
 
        while ((msg->flags & HTTP_MSGF_VER_11) &&
6035
 
               http_find_header2("Transfer-Encoding", 17, rep->buf->p, &txn->hdr_idx, &ctx)) {
 
6082
        while (http_find_header2("Transfer-Encoding", 17, rep->buf->p, &txn->hdr_idx, &ctx)) {
6036
6083
                if (ctx.vlen == 7 && strncasecmp(ctx.line + ctx.val, "chunked", 7) == 0)
6037
6084
                        msg->flags |= (HTTP_MSGF_TE_CHNK | HTTP_MSGF_XFER_LEN);
6038
6085
                else if (msg->flags & HTTP_MSGF_TE_CHNK) {
6043
6090
                }
6044
6091
        }
6045
6092
 
6046
 
        /* FIXME: below we should remove the content-length header(s) in case of chunked encoding */
 
6093
        /* Chunked responses must have their content-length removed */
6047
6094
        ctx.idx = 0;
6048
 
        while (!(msg->flags & HTTP_MSGF_TE_CHNK) && !use_close_only &&
6049
 
               http_find_header2("Content-Length", 14, rep->buf->p, &txn->hdr_idx, &ctx)) {
 
6095
        if (use_close_only || (msg->flags & HTTP_MSGF_TE_CHNK)) {
 
6096
                while (http_find_header2("Content-Length", 14, rep->buf->p, &txn->hdr_idx, &ctx))
 
6097
                        http_remove_header2(msg, &txn->hdr_idx, &ctx);
 
6098
        }
 
6099
        else while (http_find_header2("Content-Length", 14, rep->buf->p, &txn->hdr_idx, &ctx)) {
6050
6100
                signed long long cl;
6051
6101
 
6052
6102
                if (!ctx.vlen) {
10072
10122
        struct hdr_ctx ctx;
10073
10123
        const struct http_msg *msg = ((opt & SMP_OPT_DIR) == SMP_OPT_DIR_REQ) ? &txn->req : &txn->rsp;
10074
10124
        int cnt;
 
10125
        const char *name = NULL;
 
10126
        int len = 0;
10075
10127
 
10076
 
        if (!args || args->type != ARGT_STR)
10077
 
                return 0;
 
10128
        if (args && args->type == ARGT_STR) {
 
10129
                name = args->data.str.str;
 
10130
                len = args->data.str.len;
 
10131
        }
10078
10132
 
10079
10133
        CHECK_HTTP_MESSAGE_FIRST();
10080
10134
 
10081
10135
        ctx.idx = 0;
10082
10136
        cnt = 0;
10083
 
        while (http_find_full_header2(args->data.str.str, args->data.str.len, msg->chn->buf->p, idx, &ctx))
 
10137
        while (http_find_full_header2(name, len, msg->chn->buf->p, idx, &ctx))
10084
10138
                cnt++;
10085
10139
 
10086
10140
        smp->type = SMP_T_UINT;
10159
10213
        struct hdr_ctx ctx;
10160
10214
        const struct http_msg *msg = ((opt & SMP_OPT_DIR) == SMP_OPT_DIR_REQ) ? &txn->req : &txn->rsp;
10161
10215
        int cnt;
 
10216
        const char *name = NULL;
 
10217
        int len = 0;
10162
10218
 
10163
 
        if (!args || args->type != ARGT_STR)
10164
 
                return 0;
 
10219
        if (args && args->type == ARGT_STR) {
 
10220
                name = args->data.str.str;
 
10221
                len = args->data.str.len;
 
10222
        }
10165
10223
 
10166
10224
        CHECK_HTTP_MESSAGE_FIRST();
10167
10225
 
10168
10226
        ctx.idx = 0;
10169
10227
        cnt = 0;
10170
 
        while (http_find_header2(args->data.str.str, args->data.str.len, msg->chn->buf->p, idx, &ctx))
 
10228
        while (http_find_header2(name, len, msg->chn->buf->p, idx, &ctx))
10171
10229
                cnt++;
10172
10230
 
10173
10231
        smp->type = SMP_T_UINT;