AP_DECLARE(apr_status_t) ap_rgetline_core(char **s, apr_size_t n,
                                          apr_size_t *read, request_rec *r,
                                          int fold, apr_bucket_brigade *bb)
{
    apr_status_t rv;
    apr_bucket *e;
    apr_size_t bytes_handled = 0, current_alloc = 0;
    char *pos, *last_char = *s;
    int do_alloc = (*s == NULL), saw_eos = 0;
    if (last_char)
        *last_char = '\0';
    for (;;) {
        apr_brigade_cleanup(bb);
        rv = ap_get_brigade(r->proto_input_filters, bb, AP_MODE_GETLINE,
                            APR_BLOCK_READ, 0);
        if (rv != APR_SUCCESS) {
            return rv;
        }
        if (APR_BRIGADE_EMPTY(bb)) {
            return APR_EGENERAL;
        }
        for (e = APR_BRIGADE_FIRST(bb);
             e != APR_BRIGADE_SENTINEL(bb);
             e = APR_BUCKET_NEXT(e))
        {
            const char *str;
            apr_size_t len;
            if (APR_BUCKET_IS_EOS(e)) {
                saw_eos = 1;
                break;
            }
            rv = apr_bucket_read(e, &str, &len, APR_BLOCK_READ);
            if (rv != APR_SUCCESS) {
                return rv;
            }
            if (len == 0) {
                continue;
            }
            if (n < bytes_handled + len) {
                *read = bytes_handled;
                if (*s) {
                    if (bytes_handled > 0) {
                        (*s)[bytes_handled-1] = '\0';
                    }
                    else {
                        (*s)[0] = '\0';
                    }
                }
                return APR_ENOSPC;
            }
            if (do_alloc) {
                if (!*s) {
                    current_alloc = len;
                    *s = apr_palloc(r->pool, current_alloc);
                }
                else if (bytes_handled + len > current_alloc) {
                    apr_size_t new_size = current_alloc * 2;
                    char *new_buffer;
                    if (bytes_handled + len > new_size) {
                        new_size = (bytes_handled + len) * 2;
                    }
                    new_buffer = apr_palloc(r->pool, new_size);
                    memcpy(new_buffer, *s, bytes_handled);
                    current_alloc = new_size;
                    *s = new_buffer;
                }
            }
            pos = *s + bytes_handled;
            memcpy(pos, str, len);
            last_char = pos + len - 1;
            bytes_handled += len;
        }
        if (last_char && (*last_char == APR_ASCII_LF)) {
            break;
        }
    }
    if (last_char > *s && last_char[-1] == APR_ASCII_CR) {
        last_char--;
    }
    *last_char = '\0';
    bytes_handled = last_char - *s;
    if (fold && bytes_handled && !saw_eos) {
        for (;;) {
            const char *str;
            apr_size_t len;
            char c;
            apr_brigade_cleanup(bb);
            rv = ap_get_brigade(r->proto_input_filters, bb, AP_MODE_SPECULATIVE,
                                APR_BLOCK_READ, 1);
            if (rv != APR_SUCCESS) {
                return rv;
            }
            if (APR_BRIGADE_EMPTY(bb)) {
                break;
            }
            e = APR_BRIGADE_FIRST(bb);
            if (APR_BUCKET_IS_EOS(e)) {
                break;
            }
            rv = apr_bucket_read(e, &str, &len, APR_BLOCK_READ);
            if (rv != APR_SUCCESS) {
                apr_brigade_cleanup(bb);
                return rv;
            }
            c = *str;
            if (c == APR_ASCII_BLANK || c == APR_ASCII_TAB) {
                if (bytes_handled >= n) {
                    *read = n;
                    (*s)[n-1] = '\0';
                    return APR_ENOSPC;
                }
                else {
                    apr_size_t next_size, next_len;
                    char *tmp;
                    if (do_alloc) {
                        tmp = NULL;
                    }
                    else {
                        tmp = last_char;
                    }
                    next_size = n - bytes_handled;
                    rv = ap_rgetline_core(&tmp, next_size,
                                          &next_len, r, 0, bb);
                    if (rv != APR_SUCCESS) {
                        return rv;
                    }
                    if (do_alloc && next_len > 0) {
                        char *new_buffer;
                        apr_size_t new_size = bytes_handled + next_len + 1;
                        new_buffer = apr_palloc(r->pool, new_size);
                        memcpy(new_buffer, *s, bytes_handled);
                        memcpy(new_buffer + bytes_handled, tmp, next_len + 1);
                        *s = new_buffer;
                    }
                    last_char += next_len;
                    bytes_handled += next_len;
                }
            }
            else {
                break;
            }
        }
    }
    *read = bytes_handled;
    if (strlen(*s) < bytes_handled) {
        return APR_EINVAL;
    }
    return APR_SUCCESS;
}
['static apr_status_t read_chunked_trailers(http_ctx_t *ctx, ap_filter_t *f,\n                                          apr_bucket_brigade *b, int merge)\n{\n    int rv;\n    apr_bucket *e;\n    request_rec *r = f->r;\n    apr_table_t *saved_headers_in = r->headers_in;\n    int saved_status = r->status;\n    r->status = HTTP_OK;\n    r->headers_in = r->trailers_in;\n    apr_table_clear(r->headers_in);\n    ap_get_mime_headers(r);\n    if(r->status == HTTP_OK) {\n        r->status = saved_status;\n        e = apr_bucket_eos_create(f->c->bucket_alloc);\n        APR_BRIGADE_INSERT_TAIL(b, e);\n        ctx->eos_sent = 1;\n        rv = APR_SUCCESS;\n    }\n    else {\n        const char *error_notes = apr_table_get(r->notes,\n                                                "error-notes");\n        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02656)\n                      "Error while reading HTTP trailer: %i%s%s",\n                      r->status, error_notes ? ": " : "",\n                      error_notes ? error_notes : "");\n        rv = APR_EINVAL;\n    }\n    if(!merge) {\n        r->headers_in = saved_headers_in;\n    }\n    else {\n        r->headers_in = apr_table_overlay(r->pool, saved_headers_in,\n                r->trailers_in);\n    }\n    return rv;\n}', 'AP_DECLARE(void) ap_get_mime_headers(request_rec *r)\n{\n    apr_bucket_brigade *tmp_bb;\n    tmp_bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);\n    ap_get_mime_headers_core(r, tmp_bb);\n    apr_brigade_destroy(tmp_bb);\n}', 'AP_DECLARE(void) ap_get_mime_headers_core(request_rec *r, apr_bucket_brigade *bb)\n{\n    char *last_field = NULL;\n    apr_size_t last_len = 0;\n    apr_size_t alloc_len = 0;\n    char *field;\n    char *value;\n    apr_size_t len;\n    int fields_read = 0;\n    char *tmp_field;\n    core_server_config *conf = ap_get_core_module_config(r->server->module_config);\n    int strict = (conf->http_conformance != AP_HTTP_CONFORMANCE_UNSAFE);\n    while(1) {\n        apr_status_t rv;\n        field = NULL;\n        rv = ap_rgetline(&field, r->server->limit_req_fieldsize + 2,\n                         &len, r, 0, bb);\n        if (rv != APR_SUCCESS) {\n            if (APR_STATUS_IS_TIMEUP(rv)) {\n                r->status = HTTP_REQUEST_TIME_OUT;\n            }\n            else {\n                r->status = HTTP_BAD_REQUEST;\n            }\n            if (rv == APR_ENOSPC) {\n                apr_table_setn(r->notes, "error-notes",\n                               "Size of a request header field "\n                               "exceeds server limit.");\n                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00561)\n                              "Request header exceeds LimitRequestFieldSize%s"\n                              "%.*s",\n                              (field && *field) ? ": " : "",\n                              (field) ? field_name_len(field) : 0,\n                              (field) ? field : "");\n            }\n            return;\n        }\n        while (len > 1 && (field[len-1] == \'\\t\' || field[len-1] == \' \')) {\n            field[--len] = \'\\0\';\n        }\n        if (*field == \'\\t\' || *field == \' \') {\n            apr_size_t fold_len;\n            if (last_field == NULL) {\n                r->status = HTTP_BAD_REQUEST;\n                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03442)\n                              "Line folding encountered before first"\n                              " header line");\n                return;\n            }\n            if (field[1] == \'\\0\') {\n                r->status = HTTP_BAD_REQUEST;\n                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03443)\n                              "Empty folded line encountered");\n                return;\n            }\n            while (field[1] == \'\\t\' || field[1] == \' \') {\n                ++field; --len;\n            }\n            fold_len = last_len + len + 1;\n            if (fold_len >= (apr_size_t)(r->server->limit_req_fieldsize)) {\n                r->status = HTTP_BAD_REQUEST;\n                apr_table_setn(r->notes, "error-notes",\n                               "Size of a request header field "\n                               "exceeds server limit.");\n                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00562)\n                              "Request header exceeds LimitRequestFieldSize "\n                              "after folding: %.*s",\n                              field_name_len(last_field), last_field);\n                return;\n            }\n            if (fold_len > alloc_len) {\n                char *fold_buf;\n                alloc_len += alloc_len;\n                if (fold_len > alloc_len) {\n                    alloc_len = fold_len;\n                }\n                fold_buf = (char *)apr_palloc(r->pool, alloc_len);\n                memcpy(fold_buf, last_field, last_len);\n                last_field = fold_buf;\n            }\n            memcpy(last_field + last_len, field, len +1);\n            last_field[last_len] = \' \';\n            last_len += len;\n            continue;\n        }\n        else if (last_field != NULL) {\n            if (r->server->limit_req_fields\n                    && (++fields_read > r->server->limit_req_fields)) {\n                r->status = HTTP_BAD_REQUEST;\n                apr_table_setn(r->notes, "error-notes",\n                               "The number of request header fields "\n                               "exceeds this server\'s limit.");\n                ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00563)\n                              "Number of request headers exceeds "\n                              "LimitRequestFields");\n                return;\n            }\n            if (!strict)\n            {\n                if (!(value = strchr(last_field, \':\'))) {\n                    r->status = HTTP_BAD_REQUEST;\n                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00564)\n                                  "Request header field is missing \':\' "\n                                  "separator: %.*s", (int)LOG_NAME_MAX_LEN,\n                                  last_field);\n                    return;\n                }\n                tmp_field = value - (value > last_field ? 1 : 0);\n                *value++ = \'\\0\';\n                if (strpbrk(last_field, "\\t\\n\\v\\f\\r ")) {\n                    r->status = HTTP_BAD_REQUEST;\n                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03452)\n                                  "Request header field name presented"\n                                  " invalid whitespace");\n                    return;\n                }\n                while (*value == \' \' || *value == \'\\t\') {\n                     ++value;\n                }\n                if (strpbrk(value, "\\n\\v\\f\\r")) {\n                    r->status = HTTP_BAD_REQUEST;\n                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03451)\n                                  "Request header field value presented"\n                                  " bad whitespace");\n                    return;\n                }\n                if (tmp_field == last_field) {\n                    r->status = HTTP_BAD_REQUEST;\n                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03453)\n                                  "Request header field name was empty");\n                    return;\n                }\n            }\n            else\n            {\n                value = (char *)ap_scan_http_token(last_field);\n                if ((value == last_field) || *value != \':\') {\n                    r->status = HTTP_BAD_REQUEST;\n                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02426)\n                                  "Request header field name is malformed: "\n                                  "%.*s", (int)LOG_NAME_MAX_LEN, last_field);\n                    return;\n                }\n                *value++ = \'\\0\';\n                while (*value == \' \' || *value == \'\\t\') {\n                    ++value;\n                }\n                tmp_field = (char *)ap_scan_http_field_content(value);\n                if (*tmp_field != \'\\0\') {\n                    r->status = HTTP_BAD_REQUEST;\n                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02427)\n                                  "Request header value is malformed: "\n                                  "%.*s", (int)LOG_NAME_MAX_LEN, value);\n                    return;\n                }\n            }\n            apr_table_addn(r->headers_in, last_field, value);\n        }\n        if (len == 0) {\n            break;\n        }\n        alloc_len = 0;\n        last_field = field;\n        last_len = len;\n    }\n    apr_table_compress(r->headers_in, APR_OVERLAP_TABLES_MERGE);\n    apr_table_do(table_do_fn_check_lengths, r, r->headers_in, NULL);\n}', "AP_DECLARE(apr_status_t) ap_rgetline_core(char **s, apr_size_t n,\n                                          apr_size_t *read, request_rec *r,\n                                          int fold, apr_bucket_brigade *bb)\n{\n    apr_status_t rv;\n    apr_bucket *e;\n    apr_size_t bytes_handled = 0, current_alloc = 0;\n    char *pos, *last_char = *s;\n    int do_alloc = (*s == NULL), saw_eos = 0;\n    if (last_char)\n        *last_char = '\\0';\n    for (;;) {\n        apr_brigade_cleanup(bb);\n        rv = ap_get_brigade(r->proto_input_filters, bb, AP_MODE_GETLINE,\n                            APR_BLOCK_READ, 0);\n        if (rv != APR_SUCCESS) {\n            return rv;\n        }\n        if (APR_BRIGADE_EMPTY(bb)) {\n            return APR_EGENERAL;\n        }\n        for (e = APR_BRIGADE_FIRST(bb);\n             e != APR_BRIGADE_SENTINEL(bb);\n             e = APR_BUCKET_NEXT(e))\n        {\n            const char *str;\n            apr_size_t len;\n            if (APR_BUCKET_IS_EOS(e)) {\n                saw_eos = 1;\n                break;\n            }\n            rv = apr_bucket_read(e, &str, &len, APR_BLOCK_READ);\n            if (rv != APR_SUCCESS) {\n                return rv;\n            }\n            if (len == 0) {\n                continue;\n            }\n            if (n < bytes_handled + len) {\n                *read = bytes_handled;\n                if (*s) {\n                    if (bytes_handled > 0) {\n                        (*s)[bytes_handled-1] = '\\0';\n                    }\n                    else {\n                        (*s)[0] = '\\0';\n                    }\n                }\n                return APR_ENOSPC;\n            }\n            if (do_alloc) {\n                if (!*s) {\n                    current_alloc = len;\n                    *s = apr_palloc(r->pool, current_alloc);\n                }\n                else if (bytes_handled + len > current_alloc) {\n                    apr_size_t new_size = current_alloc * 2;\n                    char *new_buffer;\n                    if (bytes_handled + len > new_size) {\n                        new_size = (bytes_handled + len) * 2;\n                    }\n                    new_buffer = apr_palloc(r->pool, new_size);\n                    memcpy(new_buffer, *s, bytes_handled);\n                    current_alloc = new_size;\n                    *s = new_buffer;\n                }\n            }\n            pos = *s + bytes_handled;\n            memcpy(pos, str, len);\n            last_char = pos + len - 1;\n            bytes_handled += len;\n        }\n        if (last_char && (*last_char == APR_ASCII_LF)) {\n            break;\n        }\n    }\n    if (last_char > *s && last_char[-1] == APR_ASCII_CR) {\n        last_char--;\n    }\n    *last_char = '\\0';\n    bytes_handled = last_char - *s;\n    if (fold && bytes_handled && !saw_eos) {\n        for (;;) {\n            const char *str;\n            apr_size_t len;\n            char c;\n            apr_brigade_cleanup(bb);\n            rv = ap_get_brigade(r->proto_input_filters, bb, AP_MODE_SPECULATIVE,\n                                APR_BLOCK_READ, 1);\n            if (rv != APR_SUCCESS) {\n                return rv;\n            }\n            if (APR_BRIGADE_EMPTY(bb)) {\n                break;\n            }\n            e = APR_BRIGADE_FIRST(bb);\n            if (APR_BUCKET_IS_EOS(e)) {\n                break;\n            }\n            rv = apr_bucket_read(e, &str, &len, APR_BLOCK_READ);\n            if (rv != APR_SUCCESS) {\n                apr_brigade_cleanup(bb);\n                return rv;\n            }\n            c = *str;\n            if (c == APR_ASCII_BLANK || c == APR_ASCII_TAB) {\n                if (bytes_handled >= n) {\n                    *read = n;\n                    (*s)[n-1] = '\\0';\n                    return APR_ENOSPC;\n                }\n                else {\n                    apr_size_t next_size, next_len;\n                    char *tmp;\n                    if (do_alloc) {\n                        tmp = NULL;\n                    }\n                    else {\n                        tmp = last_char;\n                    }\n                    next_size = n - bytes_handled;\n                    rv = ap_rgetline_core(&tmp, next_size,\n                                          &next_len, r, 0, bb);\n                    if (rv != APR_SUCCESS) {\n                        return rv;\n                    }\n                    if (do_alloc && next_len > 0) {\n                        char *new_buffer;\n                        apr_size_t new_size = bytes_handled + next_len + 1;\n                        new_buffer = apr_palloc(r->pool, new_size);\n                        memcpy(new_buffer, *s, bytes_handled);\n                        memcpy(new_buffer + bytes_handled, tmp, next_len + 1);\n                        *s = new_buffer;\n                    }\n                    last_char += next_len;\n                    bytes_handled += next_len;\n                }\n            }\n            else {\n                break;\n            }\n        }\n    }\n    *read = bytes_handled;\n    if (strlen(*s) < bytes_handled) {\n        return APR_EINVAL;\n    }\n    return APR_SUCCESS;\n}"]