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

(-)docs/manual/mod/mod_proxy.xml (+7 lines)
Lines 1121-1126 Link Here
1121
        to override the <directive>ProxyIOBufferSize</directive> for a specific worker.
1121
        to override the <directive>ProxyIOBufferSize</directive> for a specific worker.
1122
        This must be at least 512 or set to 0 for the system default of 8192.
1122
        This must be at least 512 or set to 0 for the system default of 8192.
1123
    </td></tr>
1123
    </td></tr>
1124
    <tr><td>responsefieldsize</td>
1125
        <td>8192</td>
1126
        <td>Adjust the size of the proxy response field buffer. The buffer size
1127
            should be at least the size of the largest expected header size from
1128
            a proxied response. Setting the value to 0 will use the system
1129
            default of 8192 bytes.
1130
    </td></tr>
1124
    <tr><td>keepalive</td>
1131
    <tr><td>keepalive</td>
1125
        <td>Off</td>
1132
        <td>Off</td>
1126
        <td><p>This parameter should be used when you have a firewall between your
1133
        <td><p>This parameter should be used when you have a firewall between your
(-)modules/proxy/mod_proxy.c (+8 lines)
Lines 328-333 Link Here
328
                                (int)sizeof(worker->s->upgrade));
328
                                (int)sizeof(worker->s->upgrade));
329
        }
329
        }
330
    }
330
    }
331
    else if (!strcasecmp(key, "responsefieldsize")) {
332
        long s = atol(val);
333
        if (s < 0) {
334
            return "ResponseFieldSize must be greater than 0 bytes, or 0 for system default.";
335
        }
336
        worker->s->response_field_size = (s ? s : HUGE_STRING_LEN);
337
        worker->s->response_field_size_set = 1;
338
    }
331
    else {
339
    else {
332
        if (set_worker_hc_param_f) {
340
        if (set_worker_hc_param_f) {
333
            return set_worker_hc_param_f(p, s, worker, key, val, NULL);
341
            return set_worker_hc_param_f(p, s, worker, key, val, NULL);
(-)modules/proxy/mod_proxy.h (+2 lines)
Lines 455-460 Link Here
455
    char      secret[PROXY_WORKER_MAX_SECRET_SIZE]; /* authentication secret (e.g. AJP13) */
455
    char      secret[PROXY_WORKER_MAX_SECRET_SIZE]; /* authentication secret (e.g. AJP13) */
456
    char      upgrade[PROXY_WORKER_MAX_SCHEME_SIZE];/* upgrade protocol used by mod_proxy_wstunnel */
456
    char      upgrade[PROXY_WORKER_MAX_SCHEME_SIZE];/* upgrade protocol used by mod_proxy_wstunnel */
457
    char      hostname_ex[PROXY_RFC1035_HOSTNAME_SIZE];  /* RFC1035 compliant version of the remote backend address */
457
    char      hostname_ex[PROXY_RFC1035_HOSTNAME_SIZE];  /* RFC1035 compliant version of the remote backend address */
458
    apr_size_t   response_field_size; /* Size of proxy response buffer in bytes. */
459
    unsigned int response_field_size_set:1;
458
} proxy_worker_shared;
460
} proxy_worker_shared;
459
461
460
#define ALIGNED_PROXY_WORKER_SHARED_SIZE (APR_ALIGN_DEFAULT(sizeof(proxy_worker_shared)))
462
#define ALIGNED_PROXY_WORKER_SHARED_SIZE (APR_ALIGN_DEFAULT(sizeof(proxy_worker_shared)))
(-)modules/proxy/mod_proxy_http.c (-8 / +52 lines)
Lines 28-33 Link Here
28
                                          request_rec *r,
28
                                          request_rec *r,
29
                                          proxy_conn_rec *backend);
29
                                          proxy_conn_rec *backend);
30
30
31
static apr_status_t ap_proxygetline(apr_bucket_brigade *bb,
32
                                    char *s,
33
                                    int n,
34
                                    request_rec *r,
35
                                    int fold,
36
                                    int *writen);
37
31
/*
38
/*
32
 * Canonicalise http-like URLs.
39
 * Canonicalise http-like URLs.
33
 *  scheme is the scheme for the URL
40
 *  scheme is the scheme for the URL
Lines 1096-1101 Link Here
1096
    void *sconf = r->server->module_config;
1103
    void *sconf = r->server->module_config;
1097
    proxy_server_conf *psc;
1104
    proxy_server_conf *psc;
1098
    proxy_dir_conf *dconf;
1105
    proxy_dir_conf *dconf;
1106
    apr_status_t rc;
1107
    apr_bucket_brigade *tmp_bb;
1099
1108
1100
    dconf = ap_get_module_config(r->per_dir_config, &proxy_module);
1109
    dconf = ap_get_module_config(r->per_dir_config, &proxy_module);
1101
    psc = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
1110
    psc = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);
Lines 1110-1116 Link Here
1110
     */
1119
     */
1111
    ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r,
1120
    ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r,
1112
                  "Headers received from backend:");
1121
                  "Headers received from backend:");
1113
    while ((len = ap_getline(buffer, size, rr, 1)) > 0) {
1122
1123
    tmp_bb = apr_brigade_create(r->pool, c->bucket_alloc);
1124
    while (1) {
1125
        rc = ap_proxygetline(tmp_bb, buffer, size, rr, 1, &len);
1126
1127
        if (len <= 0)
1128
            break;
1129
1114
        ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r, "%s", buffer);
1130
        ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r, "%s", buffer);
1115
1131
1116
        if (!(value = strchr(buffer, ':'))) {     /* Find the colon separator */
1132
        if (!(value = strchr(buffer, ':'))) {     /* Find the colon separator */
Lines 1180-1191 Link Here
1180
        process_proxy_header(r, dconf, buffer, value);
1196
        process_proxy_header(r, dconf, buffer, value);
1181
        saw_headers = 1;
1197
        saw_headers = 1;
1182
1198
1183
        /* the header was too long; at the least we should skip extra data */
1199
        /* The header could not fit in the provided buffer. */
1184
        if (len >= size - 1) {
1200
        if (rc == APR_ENOSPC) {
1201
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, rc, r, APLOGNO(03515)
1202
                    "header size is over the limit allowed by ResponseFieldSize (%" APR_SIZE_T_FMT " bytes). "
1203
                    "Bad response header '%s': '%.*s'...",
1204
                    size, buffer, 80, value);
1205
1206
            /* XXX: We overran the limit we passed to ap_rgetline_core, but if the length
1207
             * exceeded the limit by a small amount, it may have already been consumed
1208
             * by apr_brigade_split_line called from the core input filter. If that 
1209
             * happens, this loop will throw away the next full line (header) instead of
1210
             * the remainder of the current long header.
1211
             */
1185
            while ((len = ap_getline(field, MAX_STRING_LEN, rr, 1))
1212
            while ((len = ap_getline(field, MAX_STRING_LEN, rr, 1))
1186
                    >= MAX_STRING_LEN - 1) {
1213
                    >= MAX_STRING_LEN - 1) {
1187
                /* soak up the extra data */
1214
                /* soak up the extra data */
1188
            }
1215
            }
1216
1189
            if (len == 0) /* time to exit the larger loop as well */
1217
            if (len == 0) /* time to exit the larger loop as well */
1190
                break;
1218
                break;
1191
        }
1219
        }
Lines 1246-1252 Link Here
1246
        proxy_server_conf *conf, char *server_portstr)
1274
        proxy_server_conf *conf, char *server_portstr)
1247
{
1275
{
1248
    conn_rec *c = r->connection;
1276
    conn_rec *c = r->connection;
1249
    char buffer[HUGE_STRING_LEN];
1277
    char *buffer;
1278
    char fixed_buffer[HUGE_STRING_LEN];
1250
    const char *buf;
1279
    const char *buf;
1251
    char keepchar;
1280
    char keepchar;
1252
    apr_bucket *e;
1281
    apr_bucket *e;
Lines 1255-1260 Link Here
1255
    int len, backasswards;
1284
    int len, backasswards;
1256
    int interim_response = 0; /* non-zero whilst interim 1xx responses
1285
    int interim_response = 0; /* non-zero whilst interim 1xx responses
1257
                               * are being read. */
1286
                               * are being read. */
1287
    apr_size_t response_field_size = 0;
1258
    int pread_len = 0;
1288
    int pread_len = 0;
1259
    apr_table_t *save_table;
1289
    apr_table_t *save_table;
1260
    int backend_broke = 0;
1290
    int backend_broke = 0;
Lines 1279-1284 Link Here
1279
    bb = apr_brigade_create(p, c->bucket_alloc);
1309
    bb = apr_brigade_create(p, c->bucket_alloc);
1280
    pass_bb = apr_brigade_create(p, c->bucket_alloc);
1310
    pass_bb = apr_brigade_create(p, c->bucket_alloc);
1281
1311
1312
    /* Only use dynamically sized buffer if user specifies ResponseFieldSize */
1313
    if(backend->worker->s->response_field_size_set) {
1314
        response_field_size = backend->worker->s->response_field_size;
1315
1316
        if (response_field_size != HUGE_STRING_LEN)
1317
            buffer = apr_pcalloc(p, response_field_size);
1318
        else
1319
            buffer = fixed_buffer;
1320
    }
1321
    else {
1322
        response_field_size = HUGE_STRING_LEN;
1323
        buffer = fixed_buffer;
1324
    }
1325
1282
    /* Setup for 100-Continue timeout if appropriate */
1326
    /* Setup for 100-Continue timeout if appropriate */
1283
    if (do_100_continue) {
1327
    if (do_100_continue) {
1284
        apr_socket_timeout_get(backend->sock, &old_timeout);
1328
        apr_socket_timeout_get(backend->sock, &old_timeout);
Lines 1308-1318 Link Here
1308
1352
1309
        apr_brigade_cleanup(bb);
1353
        apr_brigade_cleanup(bb);
1310
1354
1311
        rc = ap_proxygetline(backend->tmp_bb, buffer, sizeof(buffer),
1355
        rc = ap_proxygetline(backend->tmp_bb, buffer, response_field_size,
1312
                             backend->r, 0, &len);
1356
                             backend->r, 0, &len);
1313
        if (len == 0) {
1357
        if (len == 0) {
1314
            /* handle one potential stray CRLF */
1358
            /* handle one potential stray CRLF */
1315
            rc = ap_proxygetline(backend->tmp_bb, buffer, sizeof(buffer),
1359
            rc = ap_proxygetline(backend->tmp_bb, buffer, response_field_size,
1316
                                 backend->r, 0, &len);
1360
                                 backend->r, 0, &len);
1317
        }
1361
        }
1318
        if (len <= 0) {
1362
        if (len <= 0) {
Lines 1386-1392 Link Here
1386
            /* If not an HTTP/1 message or
1430
            /* If not an HTTP/1 message or
1387
             * if the status line was > 8192 bytes
1431
             * if the status line was > 8192 bytes
1388
             */
1432
             */
1389
            if ((major != 1) || (len >= sizeof(buffer)-1)) {
1433
            if ((major != 1) || (len >= response_field_size - 1)) {
1390
                proxy_run_detach_backend(r, backend);
1434
                proxy_run_detach_backend(r, backend);
1391
                return ap_proxyerror(r, HTTP_BAD_GATEWAY,
1435
                return ap_proxyerror(r, HTTP_BAD_GATEWAY,
1392
                apr_pstrcat(p, "Corrupt status line returned by remote "
1436
                apr_pstrcat(p, "Corrupt status line returned by remote "
Lines 1430-1436 Link Here
1430
                         "Set-Cookie", NULL);
1474
                         "Set-Cookie", NULL);
1431
1475
1432
            /* shove the headers direct into r->headers_out */
1476
            /* shove the headers direct into r->headers_out */
1433
            ap_proxy_read_headers(r, backend->r, buffer, sizeof(buffer), origin,
1477
            ap_proxy_read_headers(r, backend->r, buffer, response_field_size, origin,
1434
                                  &pread_len);
1478
                                  &pread_len);
1435
1479
1436
            if (r->headers_out == NULL) {
1480
            if (r->headers_out == NULL) {

Return to bug 62199