Redirects from php header("Location: ... results in errors

1. Output of caddy version:

v2.6.2 h1:wKoFIxpmOJLGl3QXoo6PNbYvGW4xLEgo32GPBEjWL8o=

2. How I run Caddy:

Docker - image: caddy:2.6.2-alpine

a. System environment:

Latest docker

b. Command:

runs as service

d. My complete Caddy config:

opencart.a.com {
        reverse_proxy {
                header_up host {http.reverse_proxy.upstream.host}
                header_down Location ([^:]+://[^:]+(:[0-9]+)?/) ./
                to opencart:80
        }
}

3. The problem I’m having:

Php is trying to do redirects with the header function:

header(‘Location: ’ . str_replace(array(’&‘, “\n”, “\r”), array(’&', ‘’, ‘’), $url), true, $status);

But, an error message is displayed instead:

Cannot modify header information - headers already sent by

4. Error messages and/or full log output:

*   Trying 2.2.2.2:443...
* TCP_NODELAY set
* Connected to opencart.a.com (2.2.2.2) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=opencart.a.com
*  start date: Nov 14 03:38:53 2022 GMT
*  expire date: Feb 12 03:38:52 2023 GMT
*  subjectAltName: host "opencart.a.com" matched cert's "opencart.a.com"
*  issuer: C=US; O=Let's Encrypt; CN=R3
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x55707aa5f8c0)
> GET / HTTP/2
> Host: opencart.a.com
> user-agent: curl/7.68.0
> accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* Connection state changed (MAX_CONCURRENT_STREAMS == 250)!
< HTTP/2 200
< alt-svc: h3=":443"; ma=2592000
< content-type: text/html; charset=UTF-8
< date: Fri, 18 Nov 2022 07:02:06 GMT
< server: Caddy
< server: Apache/2.4.38 (Debian)
< set-cookie: OCSESSID=e3ff75e60419075e488471398a; path=/
< set-cookie: OCSESSID=a3fda52523ea41f8f036d71acc; path=/
< set-cookie: language=en-gb; expires=Sun, 18-Dec-2022 07:02:06 GMT; Max-Age=2592000; path=/; domain=opencart
< set-cookie: currency=USD; expires=Sun, 18-Dec-2022 07:02:06 GMT; Max-Age=2592000; path=/; domain=opencart
< vary: Accept-Encoding
< x-powered-by: PHP/7.2.34
<
* Connection #0 to host opencart.a.com left intact
<b>Notice</b>: Undefined index: route in <b>/var/www/html/vqmod/vqcache/vq2-catalog_controller_common_header.php</b> on line <b>17</b><b>Notice</b>: Undefined index: route in <b>/var/www/html/vqmod/vqcache/vq2-catalog_controller_common_header.php</b> on line <b>17</b><b>Notice</b>: Undefined index: route in <b>/var/www/html/vqmod/vqcache/vq2-catalog_controller_common_header.php</b> on line <b>17</b><b>Notice</b>: Undefined index: route in <b>/var/www/html/vqmod/vqcache/vq2-catalog_controller_common_header.php</b> on line <b>17</b><b>Notice</b>: Undefined index: route in <b>/var/www/html/vqmod/vqcache/vq2-catalog_controller_common_header.php</b> on line <b>17</b><b>Warning</b>: Cannot modify header information - headers already sent by (output started at /var/www/html/catalog/controller/startup/error.php:34) in <b>/var/www/html/system/library/response.php</b> on line <b>36</b>

5. What I already tried:

tried copy_response and copy_response_headers, but I haven’t seen a clear example of the match variables, so I haven’t been get those to work successfuly

6. Links to relevant resources:

* Connection #0 to host opencart.a.com left intact
<b>Notice</b>: Undefined index: route in <b>/var/www/html/vqmod/vqcache/vq2-catalog_controller_common_header.php</b> on line <b>17</b><b>Notice</b>: Undefined index: route in <b>/var/www/html/vqmod/vqcache/vq2-catalog_controller_common_header.php</b> on line <b>17</b><b>Notice</b>: Undefined index: route in <b>/var/www/html/vqmod/vqcache/vq2-catalog_controller_common_header.php</b> on line <b>17</b><b>Notice</b>: Undefined index: route in <b>/var/www/html/vqmod/vqcache/vq2-catalog_controller_common_header.php</b> on line <b>17</b><b>Notice</b>: Undefined index: route in <b>/var/www/html/vqmod/vqcache/vq2-catalog_controller_common_header.php</b> on line <b>17</b><b>Warning</b>: Cannot modify header information - headers already sent by (output started at /var/www/html/catalog/controller/startup/error.php:34) in <b>/var/www/html/system/library/response.php</b> on line <b>36</b>

This is your error, nothing to do with Caddy.

This error sends output to the browser, then you use the header function, which of course complaints about that output.

2 Likes

I fixed this by putting ob_start at the top of the index.php. It’s just weird that I ran the same site behind an IIS proxy before and didn’t have the same issue. Agreed it was a problem with the code though.