Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Case-sensitive issue in header_down of reverse proxy #4330

Closed
nnnlog opened this issue Sep 4, 2021 · 2 comments
Closed

Case-sensitive issue in header_down of reverse proxy #4330

nnnlog opened this issue Sep 4, 2021 · 2 comments
Labels
bug 🐞 Something isn't working good first issue 🐤 Good for newcomers
Milestone

Comments

@nnnlog
Copy link

nnnlog commented Sep 4, 2021

Three or four parameters of header_down use Regex, and one does simply overwriting.
Caddy did not simply make a case-sensitive distinction of the header key value when it overwrites it, but I experienced a case-sensitive distinction of the header key value when I used Regex.
I think it is not intended.

Reproduction of issue.

example.com {
        reverse_proxy {
                to http://127.0.0.1:8000
                header_down Location (http://)(.*) https://$2
        }
}

The above setting replaces the Location header's value with https if the value starts with http. It worked only when it was a Location, not location.

example.com {
        reverse_proxy {
                to http://127.0.0.1:8000
                header_down Location https://example.com
        }
}

In comparison, the task of simply changing to https://example.com worked when the header was named location.

Version

v2.4.5

@francislavoie
Copy link
Member

Ah, yeah I see the problem. We're using a map[string][]Replacement for the replacements, where string is the header field name in the case that was configured. I think we need to call http.CanonicalHeaderKey() on fieldName in the code here, and/or probably use hdr.Get() and hdr.Set() instead or directly accessing the header map:

// replace
for fieldName, replacements := range ops.Replace {
fieldName = repl.ReplaceAll(fieldName, "")
// all fields...
if fieldName == "*" {
for _, r := range replacements {
search := repl.ReplaceAll(r.Search, "")
replace := repl.ReplaceAll(r.Replace, "")
for fieldName, vals := range hdr {
for i := range vals {
if r.re != nil {
hdr[fieldName][i] = r.re.ReplaceAllString(hdr[fieldName][i], replace)
} else {
hdr[fieldName][i] = strings.ReplaceAll(hdr[fieldName][i], search, replace)
}
}
}
}
continue
}
// ...or only with the named field
for _, r := range replacements {
search := repl.ReplaceAll(r.Search, "")
replace := repl.ReplaceAll(r.Replace, "")
for i := range hdr[fieldName] {
if r.re != nil {
hdr[fieldName][i] = r.re.ReplaceAllString(hdr[fieldName][i], replace)
} else {
hdr[fieldName][i] = strings.ReplaceAll(hdr[fieldName][i], search, replace)
}
}
}
}

@francislavoie francislavoie added bug 🐞 Something isn't working good first issue 🐤 Good for newcomers labels Sep 4, 2021
@francislavoie francislavoie added this to the v2.5.0 milestone Sep 4, 2021
@caddyserver caddyserver deleted a comment Sep 12, 2021
@mholt mholt modified the milestones: v2.5.0, v2.4.6 Sep 13, 2021
@mholt mholt closed this as completed in a437206 Sep 13, 2021
@mholt
Copy link
Member

mholt commented Sep 13, 2021

Thanks for the report! And thanks Francis for investigating.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐞 Something isn't working good first issue 🐤 Good for newcomers
Projects
None yet
Development

No branches or pull requests

3 participants