View | Details | Raw Unified | Return to bug 63855
Collapse All | Expand All

(-)include/http_protocol.h (+11 lines)
Lines 466-471 AP_DECLARE(int) ap_index_of_response(int status); Link Here
466
 */
466
 */
467
AP_DECLARE(const char *) ap_get_status_line(int status);
467
AP_DECLARE(const char *) ap_get_status_line(int status);
468
468
469
/**
470
 * Return the Status-Line for a given status code (excluding the
471
 * HTTP-Version field). If an invalid status code is passed,
472
 * "500 Internal Server Error" will be returned, whereas an unknown
473
 * status will be returned like "xxx Status xxx".
474
 * @param p The pool to allocate from when status is unknown
475
 * @param status The HTTP status code
476
 * @return The Status-Line
477
 */
478
AP_DECLARE(const char *) ap_get_status_line_ex(apr_pool_t *p, int status);
479
469
/* Reading a block of data from the client connection (e.g., POST arg) */
480
/* Reading a block of data from the client connection (e.g., POST arg) */
470
481
471
/**
482
/**
(-)modules/http/http_protocol.c (-7 / +28 lines)
Lines 987-1001 AP_DECLARE(const char *) ap_method_name_of(apr_poo Link Here
987
 * from status_lines[shortcut[i]] to status_lines[shortcut[i+1]-1];
987
 * from status_lines[shortcut[i]] to status_lines[shortcut[i+1]-1];
988
 * or use NULL to fill the gaps.
988
 * or use NULL to fill the gaps.
989
 */
989
 */
990
AP_DECLARE(int) ap_index_of_response(int status)
990
static int index_of_response(int status)
991
{
991
{
992
    static int shortcut[6] = {0, LEVEL_200, LEVEL_300, LEVEL_400,
992
    static int shortcut[6] = {0, LEVEL_200, LEVEL_300, LEVEL_400, LEVEL_500,
993
    LEVEL_500, RESPONSE_CODES};
993
                                 RESPONSE_CODES};
994
    int i, pos;
994
    int i, pos;
995
995
996
    if (status < 100) {               /* Below 100 is illegal for HTTP status */
996
    if (status < 100) {     /* Below 100 is illegal for HTTP status */
997
        return LEVEL_500;
997
        return -1;
998
    }
998
    }
999
    if (status > 999) {     /* Above 999 is also illegal for HTTP status */
1000
        return -1;
1001
    }
999
1002
1000
    for (i = 0; i < 5; i++) {
1003
    for (i = 0; i < 5; i++) {
1001
        status -= 100;
1004
        status -= 100;
Lines 1005-1017 AP_DECLARE(const char *) ap_method_name_of(apr_poo Link Here
1005
                return pos;
1008
                return pos;
1006
            }
1009
            }
1007
            else {
1010
            else {
1008
                return LEVEL_500;            /* status unknown (falls in gap) */
1011
                break;
1009
            }
1012
            }
1010
        }
1013
        }
1011
    }
1014
    }
1012
    return LEVEL_500;                         /* 600 or above is also illegal */
1015
    return -2;              /* Status unknown (falls in gap) or above 600 */
1013
}
1016
}
1014
1017
1018
AP_DECLARE(int) ap_index_of_response(int status)
1019
{
1020
    int index = index_of_response(status);
1021
    return (index < 0) ? LEVEL_500 : index;
1022
}
1023
1024
AP_DECLARE(const char *) ap_get_status_line_ex(apr_pool_t *p, int status)
1025
{
1026
    int index = index_of_response(status);
1027
    if (index >= 0) {
1028
        return status_lines[index];
1029
    }
1030
    else if (index == -2) {
1031
        return apr_psprintf(p, "%i Status %i", status, status);
1032
    }
1033
    return status_lines[LEVEL_500];
1034
}
1035
1015
AP_DECLARE(const char *) ap_get_status_line(int status)
1036
AP_DECLARE(const char *) ap_get_status_line(int status)
1016
{
1037
{
1017
    return status_lines[ap_index_of_response(status)];
1038
    return status_lines[ap_index_of_response(status)];
(-)modules/proxy/mod_proxy_http.c (+27 lines)
Lines 438-443 static int spool_reqbody_cl(proxy_http_req_t *req, Link Here
438
    apr_file_t *tmpfile = NULL;
438
    apr_file_t *tmpfile = NULL;
439
    apr_off_t limit;
439
    apr_off_t limit;
440
440
441
    /* Send "100 Continue" now if the client expects one, before
442
     * blocking on the body, otherwise we'd wait for each other.
443
     */
444
    if (req->expecting_100) {
445
        int saved_status = r->status;
446
447
        r->expecting_100 = 1;
448
        r->status = HTTP_CONTINUE;
449
        ap_send_interim_response(r, 0);
450
        AP_DEBUG_ASSERT(!r->expecting_100);
451
452
        r->status = saved_status;
453
        req->expecting_100 = 0;
454
    }
455
441
    body_brigade = apr_brigade_create(p, bucket_alloc);
456
    body_brigade = apr_brigade_create(p, bucket_alloc);
442
    *bytes_spooled = 0;
457
    *bytes_spooled = 0;
443
458
Lines 668-673 static int ap_proxy_http_prefetch(proxy_http_req_t Link Here
668
        apr_brigade_length(temp_brigade, 1, &bytes);
683
        apr_brigade_length(temp_brigade, 1, &bytes);
669
        bytes_read += bytes;
684
        bytes_read += bytes;
670
685
686
        /* From https://tools.ietf.org/html/rfc7231#section-5.1.1
687
         *   A server MAY omit sending a 100 (Continue) response if it has
688
         *   already received some or all of the message body for the
689
         *   corresponding request, or if [snip].
690
         */
691
        if (req->expecting_100 && bytes > 0) {
692
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r, APLOGNO(10206)
693
                          "prefetching request body while 100-continue is"
694
                          "expected, omit sending interim response");
695
            req->expecting_100 = 0;
696
        }
697
671
        /*
698
        /*
672
         * Save temp_brigade in input_brigade. (At least) in the SSL case
699
         * Save temp_brigade in input_brigade. (At least) in the SSL case
673
         * temp_brigade contains transient buckets whose data would get
700
         * temp_brigade contains transient buckets whose data would get
(-)server/protocol.c (-4 / +11 lines)
Lines 2176-2182 static int send_header(void *data, const char *key Link Here
2176
AP_DECLARE(void) ap_send_interim_response(request_rec *r, int send_headers)
2176
AP_DECLARE(void) ap_send_interim_response(request_rec *r, int send_headers)
2177
{
2177
{
2178
    hdr_ptr x;
2178
    hdr_ptr x;
2179
    char *status_line = NULL;
2179
    char *response_line = NULL;
2180
    const char *status_line;
2180
    request_rec *rr;
2181
    request_rec *rr;
2181
2182
2182
    if (r->proto_num < HTTP_VERSION(1,1)) {
2183
    if (r->proto_num < HTTP_VERSION(1,1)) {
Lines 2207-2219 AP_DECLARE(void) ap_send_interim_response(request_ Link Here
2207
        }
2208
        }
2208
    }
2209
    }
2209
2210
2210
    status_line = apr_pstrcat(r->pool, AP_SERVER_PROTOCOL, " ", r->status_line, CRLF, NULL);
2211
    status_line = r->status_line;
2211
    ap_xlate_proto_to_ascii(status_line, strlen(status_line));
2212
    if (status_line == NULL) {
2213
        status_line = ap_get_status_line_ex(r->pool, r->status);
2214
    }
2215
    response_line = apr_pstrcat(r->pool,
2216
                                AP_SERVER_PROTOCOL " ", status_line, CRLF,
2217
                                NULL);
2218
    ap_xlate_proto_to_ascii(response_line, strlen(response_line));
2212
2219
2213
    x.f = r->connection->output_filters;
2220
    x.f = r->connection->output_filters;
2214
    x.bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
2221
    x.bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
2215
2222
2216
    ap_fputs(x.f, x.bb, status_line);
2223
    ap_fputs(x.f, x.bb, response_line);
2217
    if (send_headers) {
2224
    if (send_headers) {
2218
        apr_table_do(send_header, &x, r->headers_out, NULL);
2225
        apr_table_do(send_header, &x, r->headers_out, NULL);
2219
        apr_table_clear(r->headers_out);
2226
        apr_table_clear(r->headers_out);

Return to bug 63855