Skip to content

Feature response headers - #3172

Open
Gulianrdgd wants to merge 10 commits into
fosrl:devfrom
Gulianrdgd:feature-response-headers
Open

Feature response headers#3172
Gulianrdgd wants to merge 10 commits into
fosrl:devfrom
Gulianrdgd:feature-response-headers

Conversation

@Gulianrdgd

Copy link
Copy Markdown

Community Contribution License Agreement

By creating this pull request, I grant the project maintainers an unlimited,
perpetual license to use, modify, and redistribute these contributions under any terms they
choose, including both the AGPLv3 and the Fossorial Commercial license terms. I
represent that I have the right to grant this license for all contributed content.

Description

Closes #2789 and feature request: #1939

Pangolin previously only supported injecting custom headers into requests forwarded to downstream targets (customRequestHeaders). This PR adds responseHeaders and renames the existing headers field to requestHeaders throughout the stack for clarity. This was already possible in Treafik, so it was simply adding responseHeaders to the code where (request) headers appeared.

The blueprint code is also updated to still be backwards compatible. headers in pangolin.yml works as alias for requestHeaders. Both requestHeaders and responseHeaders are now accepted and if both headers and requestHeaders are specified, they are merged.

I also let Claude do the translations, I am unsure if they are correct. But the languages I speak are good.

I created a PR before, without reading the CONTRIBUTING.md (very sorry about that). In that PR wrote some migrations, so when you need to make them you can copy them. There are also some remarks from copilot which I fixed. #3171

How to test?

  • Set request and response headers on a resource via the UI, save, and confirm the Traefik dynamic config reflects both customRequestHeaders and customResponseHeaders
  • curl -v through Traefik confirms response headers appear on the HTTP response and request headers arrive at the upstream target
  • Existing resources with headers set in a blueprint continue to work after migration

Copilot AI review requested due to automatic review settings May 27, 2026 18:42
@Gulianrdgd

Copy link
Copy Markdown
Author

Any changes I need to make?

@AstralDestiny

AstralDestiny commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

If it was me I'd see if you could define it to be a entry for shared policies or so, So you can apply it more universal across all resources.. but that's just me. Alongside the induvial entries. They're just a bit backlogged right now 🙂

@Root-Core

Root-Core commented Jun 29, 2026

Copy link
Copy Markdown

LGTM. Should the checks distinguish between header types for more accurate error messages?


This is not about your PR, but a general observation:

I'm not sure the checks work as intended. I can "set" everything with Pangolin 1.19.4.
It says the settings were saved successfully, but on reload it will be reset.

Shouldn't this result in an error message and not fail silently on the backend, discarding the users changes?
@oschwartz10612 @miloschwartz

Maybe the client side validation should be improved nonetheless.


@AstralDestiny I would keep the scope of this PR to the current implementation and your request to another, as it also applies to the already existing implementation of headers. You might want to open a discussion about that.

@oschwartz10612

Copy link
Copy Markdown
Member

We are not ignoring this! I appreciate your contribution! We will review around the prep for the next release.

@oschwartz10612

Copy link
Copy Markdown
Member

@Root-Core what checks are failing? Would you be able to give an example so we can look into resolving that?

@Root-Core

Copy link
Copy Markdown

@oschwartz10612
If I set the headers property (or a single entry) to something invalid via the UI (eg. just test), there is no error message / validation hint. It even tells me, the settings were successful updated.

I linked you the corresponding server side code below, but it is not the cause of this issue.

.refine(
(data) => {
if (data.headers) {
// HTTP header names must be valid token characters (RFC 7230)
const validHeaderName = /^[a-zA-Z0-9!#$%&'*+\-.^_`|~]+$/;
return data.headers.every((h) => validHeaderName.test(h.name));
}
return true;
},
{
error: "Header names may only contain valid HTTP token characters (letters, digits, and !#$%&'*+-.^_`|~)."
}
)
.refine(
(data) => {
if (data.headers) {
// HTTP header values must be visible ASCII or horizontal whitespace, no control chars (RFC 7230)
const validHeaderValue = /^[\t\x20-\x7E]*$/;
return data.headers.every((h) =>
validHeaderValue.test(h.value)
);
}
return true;
},
{
error: "Header values may only contain printable ASCII characters and horizontal whitespace."
}
)
.refine(
(data) => {
if (data.headers) {
// Reject Traefik template syntax {{word}} in names or values
const templatePattern = /\{\{[^}]+\}\}/;
return data.headers.every(
(h) =>
!templatePattern.test(h.name) &&
!templatePattern.test(h.value)
);
}
return true;
},
{
error: "Header names and values must not contain template expressions such as {{value}}."
}
);

I investigated it a bit and the POST to the API does not contain the modified headers. It contains the previous known good settings. So my first impression was false, it is never validated server side.

I assume there is some client side validation - which skips the invalid setting, but it does not show any error / hint and sends the old settings. I think this is not correctly handled in HeadersInput.tsx, but I have not investigated further.

@Gulianrdgd

Copy link
Copy Markdown
Author

We are not ignoring this! I appreciate your contribution! We will review around the prep for the next release.

@oschwartz10612 Great! should I resolve the merge conflicts before that?

@oschwartz10612

oschwartz10612 commented Jul 1, 2026 via email

Copy link
Copy Markdown
Member

…ders

# Conflicts:
#	server/db/pg/schema/schema.ts
#	server/lib/blueprints/proxyResources.ts
#	server/routers/resource/getResource.ts
#	src/app/[orgId]/settings/resources/proxy/[niceId]/proxy/page.tsx
#	src/components/HealthCheckCredenza.tsx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants