We have an Apache Http Server 2.4.59 running that's started generating errors when one of the response servers from a backend system we don't control exceeds the default 8192 bytes. This was not the case in previous versions of HTTPD as exceeding that limit did not cause an error. Unfortunately, it seems that ResponseFieldSize in our ProxyPassMatch definitions with this format: ProxyPassMatch "^/([^/]+)/?(.+)?$" https://$1-myhost/$2 responsefieldsize=20 keepalive=On disablereuse=On is being ignored. I can configure responsefieldsize correctly for ProxyPass directives but it does not seem to work for ProxyPass. Are we doing anything incorrectly? It seems from the docs it should work as per my example, so not sure if this is a bug or something that needs clarification in docs. It would also be great if you could document any way to configure this responsefieldsize globally.
Sorry, I meant "one of the response headers"
If this ProxyPassMatch is "elected" I don't see why the configured responsefieldsize wouldn't apply. Could it be that another ProxyPass[Match] also matches and takes precedence, or a RewriteRule [P] or anything falling back to the default/implicit proxy worker with the default settings? With "LogLevel trace2" you should have a log line like "found worker <name> for <url>", which <name> do you see?
More in the direction of Yann's thoughts: I think multiple ProxyPass(Match) can share the same target worker including its configuration. You might even find messages in the error log about sharing workers during startup (but I forgot the log level, maybe info). So check in addition to looking for RewriteRules which do proxying, also check for other ProxyPass(Match), which do not necessarily match your request, but use the same target host, scheme and port as the rule which doesn't work correctly for you.
Hi! Actually it is a very simple config where we only have two virtual hosts with a single ProxyPassMatch directive each, both with the responsefieldsize config value, and another proxypassmatch rule that will not match those or does not use the same target, but we've also added responsefieldsize to that one. There are no RewriteRules or similar... is there any debugging info I can use to print the value of ResponseFieldSize when it's loaded? What I did to verify this (since responsefieldsize did not seem to work) was to create a new "localhost" virtual host configuring the responsefieldsize to 20 in a ProxyPass directive, and that caused failures for any backend services I tried. Changing ProxyPass to ProxyPassMatch , requests go through without failures. This is my virtualhost: <VirtualHost *:*> ServerName http://localhost:1080 CustomLog "|/usr/sbin/rotatelogs -l -f /var/log/httpd/localaccess.%Y%m%d0000 86400" combined env=!forwarded CustomLog "|/usr/sbin/rotatelogs -l -f /var/log/httpd/localaccess.%Y%m%d0000 86400" proxy env=forwarded ErrorLog "|/usr/sbin/rotatelogs -l -f /var/log/httpd/localerrors.%Y%m%d0000 86400" #ProxyPassMatch "^/([^/]+)/?(.+)?$" https://$1-HOSTNAME/$2 responsefieldsize=20 keepalive=On disablereuse=On ProxyPass "/prefix/" "https://HOSTNAME/" responsefieldsize=20 keepalive=On disablereuse=On </VirtualHost> With the ProxyPass directive enabled, I get this error for the backend I am testing (It sends a CSP over 20 chars): Wed Jul 31 06:38:46.833680 2024] [proxy_http:warn] [pid 33291:tid 33313] (28)No space left on device: [client ::1:34578] AH10124: header size is over the limit allowed by ResponseFieldSize (20 bytes). Bad response header: 'Date: Wed[...] 31 Jul 2' If I comment the ProxyPass directive and uncomment the ProxyPassMatch one, I do get a successful response from the backend, which shows headers over 20 characters. No error logs about responsefieldsize at all. The only other "ProxyPass" directive I have in my config is: ProxyPass /healthcheck.html ! and a ProxyPassMatch for a different target which also has responsefieldsize=20 way to configure a default responsefieldsize that will apply to any hosts?
Hi, I've looked into this further and I can see that the problem seems to be that Apache expects a line with a 'perfect match' with the target in the ProxyPass* directives ? Let me elaborate. If I add this config: <VirtualHost *:*> ServerName http://localhost:1080 CustomLog "|/usr/sbin/rotatelogs -l -f /var/log/httpd/localaccess.%Y%m%d0000 86400" combined env=!forwarded CustomLog "|/usr/sbin/rotatelogs -l -f /var/log/httpd/localaccess.%Y%m%d0000 86400" proxy env=forwarded ErrorLog "|/usr/sbin/rotatelogs -l -f /var/log/httpd/localerrors.%Y%m%d0000 86400" ProxyPassMatch "^/([^/]+)/?(.+)?$" https://$1-myhostname.com/$2 responsefieldsize=20 keepalive=On disablereuse=On ProxyPass "/application/test/" "https://application-myhostname.com/" responsefieldsize=20 keepalive=On disablereuse=On </VirtualHost> And I try to curl http://localhost:8180/application/healthcheck , then I correctly get an error saying my responsefieldsize is 20 (this is matching the ProxyPassMatch directive and not ProxyPass as I don't have /application/test/ in the path - I can also see a match with the proxy handler i in the tracelogs ) . However, the moment I comment the ProxyPass directive or change this "ProxyPass" directive to not match https://application-myhostname.com/ I don't get an error complaining about the responsefieldsize. An example, with the config above, when I call both /application/assets and /application/healthcheck, I get an error about the responsefieldsize. However, if I change the ProxyPass directive to this: ProxyPass "/application/test/" "https://application-myhostname.com/healthcheck" responsefieldsize=20 keepalive=On disablereuse=On I get the error when calling /application/healthcheck (responsefieldsize is correctly read from ProxyPass directive) , but I don't get an error (responseFieldSize is the default instead of 20) when I call /application/assets . If I change the target url to https://application-myhostname.com/assets , it is the opposite: calls to /application/healthcheck use the default responsefieldsize but calls to /application/assets work as desired. I've also tried creating a ProxyPassMatch directive where the target hostname is "https://application-myhostname.com/$2" (with no ProxyPass at all, just this ProxyPassMatch) , and in that case responsefieldsize is also correctly read from the ProxyPassMatch rule. In our case, we cannot preconfigure all the target hostnames (which are unknown) but rather need to write the hostname based on the request path, using a ProxyPassMatch directive. How can we configur ethe responsefieldsize in this case?
To simplify my report: This rule works as expected, configuring responsefieldsize for requests to /application/: ProxyPassMatch "^/([^/]+)/?(.+)?$" https://application-HOSTNAME/$2 responsefieldsize=20 keepalive=On disablereuse=On This one , where the target hostname is composed with regex, does not work as expected, and responsefieldsize is not respected (although directive itself matches the request and calls are forwarded to the expected backend): ProxyPassMatch "^/([^/]+)/?(.+)?$" https://$1-HOSTNAME/$2 responsefieldsize=20 keepalive=On disablereuse=On I hope that's clear. Hopefully there's a workaround for this like a way to configure responsefieldsize for any targets?
Without a host I guess these will use the "default reverse proxy worker". I wonder if it is possible to use <Proxy "proxy:reverse"> ProxySet responsefieldsize=32768 </Proxy> to configure the default worker? Maybe it's easy for you to try in your env?
It may be "*" rather than proxy:reverse
Hi Eric, Thanks a lot for the quick reply. I've tried to implement this suggested configuration change, but it seems that the server will not start if I add either: <Proxy "proxy:reverse"> ProxySet responsefieldsize=32768 </Proxy> or <Proxy "*"> ProxySet responsefieldsize=32768 </Proxy> I haven't been able to find any error details?
Ah sorry, I always get this error: ProxySet URL must be absolute!: proxy:reverse ProxySet URL must be absolute!: *
Created attachment 39831 [details] Don't enforce min_match for ProxyPassMatch This works for me, could you try it?
Checked in trunk r1919617. Please try this patch for 2.4.x: https://patch-diff.githubusercontent.com/raw/apache/httpd/pull/469.diff
Hi Yann, Thanks a lot for the quick fix! We'll try to have this tested ... What's the expected change in behaviour exactly? Is it that the key/val parameters in the ProxyPassMatch directive will be used? For instance: ProxyPassMatch "^/([^/]+)/?(.+)?$" https://$1-myhost/$2 responsefieldsize=20 keepalive=On Will use "responseFieldSize=20" , "keepalive=on" whenever the ProxyPassMatch rule is applied?
Yes exactly, the proxy worker "https://$1-myhost/$2" defined with this ProxyPassMatch is used/selected hence its parameters apply. Without this patch the request falls back to the default reverse proxy worker mentionned by Eric, which is not configurable, so the defaults apply.
Hi Yann , Sorry but I was allocated to something else and I never had the chance to test this in the 2.4.x branch. Maybe someone else can have it tested? I'm going to be away for a while but my organization will still require this.