* Note: pread_len is the length of the response that we've mistakenly * read (assuming that we don't consider that an error via * ProxyBadHeader StartBody). This depends on buffer actually being * local storage to the calling code in order for pread_len to make * any sense at all, since we depend on buffer still containing * what was read by ap_getline() upon return. */
| 812 | * what was read by ap_getline() upon return. |
| 813 | */ |
| 814 | static apr_status_t ap_proxy_read_headers(request_rec *r, request_rec *rr, |
| 815 | char *buffer, int size, |
| 816 | conn_rec *c, int *pread_len) |
| 817 | { |
| 818 | int len; |
| 819 | char *value, *end; |
| 820 | int saw_headers = 0; |
| 821 | void *sconf = r->server->module_config; |
| 822 | proxy_server_conf *psc; |
| 823 | proxy_dir_conf *dconf; |
| 824 | apr_status_t rc; |
| 825 | apr_bucket_brigade *tmp_bb; |
| 826 | |
| 827 | dconf = ap_get_module_config(r->per_dir_config, &proxy_module); |
| 828 | psc = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module); |
| 829 | |
| 830 | r->headers_out = apr_table_make(r->pool, 20); |
| 831 | r->trailers_out = apr_table_make(r->pool, 5); |
| 832 | *pread_len = 0; |
| 833 | |
| 834 | /* |
| 835 | * Read header lines until we get the empty separator line, a read error, |
| 836 | * the connection closes (EOF), or we timeout. |
| 837 | */ |
| 838 | ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r, |
| 839 | "Headers received from backend:"); |
| 840 | |
| 841 | tmp_bb = apr_brigade_create(r->pool, c->bucket_alloc); |
| 842 | while (1) { |
| 843 | rc = ap_proxygetline(tmp_bb, buffer, size, rr, |
| 844 | AP_GETLINE_FOLD | AP_GETLINE_NOSPC_EOL, &len); |
| 845 | |
| 846 | |
| 847 | if (rc != APR_SUCCESS) { |
| 848 | if (APR_STATUS_IS_ENOSPC(rc)) { |
| 849 | int trunc = (len > 128 ? 128 : len) / 2; |
| 850 | ap_log_rerror(APLOG_MARK, APLOG_WARNING, rc, r, APLOGNO(10124) |
| 851 | "header size is over the limit allowed by " |
| 852 | "ResponseFieldSize (%d bytes). " |
| 853 | "Bad response header: '%.*s[...]%s'", |
| 854 | size, trunc, buffer, buffer + len - trunc); |
| 855 | } |
| 856 | else { |
| 857 | ap_log_rerror(APLOG_MARK, APLOG_WARNING, rc, r, APLOGNO(10404) |
| 858 | "Error reading headers from backend"); |
| 859 | } |
| 860 | r->headers_out = NULL; |
| 861 | return rc; |
| 862 | } |
| 863 | |
| 864 | if (len <= 0) { |
| 865 | break; |
| 866 | } |
| 867 | else { |
| 868 | ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r, "%s", buffer); |
| 869 | } |
| 870 | |
| 871 | if (!(value = strchr(buffer, ':'))) { /* Find the colon separator */ |
no test coverage detected