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.
Preface
This PR was developed with Claude Code (claude-opus-4-6). I identified the bug, traced the root cause through the code, and directed the fix. Claude wrote the patch. I reviewed and validated all changes.
Description
When Newt terminates TLS on incoming connections, X-Forwarded-Proto is always set to http in requests forwarded to downstream targets. Backend applications that rely on this header to construct callback URLs (OIDC redirect URIs, CSRF origin checks, etc.) generate incorrect http:// URLs.
HandleConn wraps *tls.Conn inside httpConnCtx, which embeds net.Conn. Go's http.Server detects TLS by type-asserting the accepted connection to *tls.Conn, but this assertion fails against the wrapper type. http.Request.TLS is always nil, so httputil.ProxyRequest.SetXForwarded() always writes X-Forwarded-Proto: http.
The fix reuses the isTLS flag already stored on the request context by ConnContext (the same flag used for the HTTP-to-HTTPS redirect in handleRequest). After SetXForwarded(), if isTLS is true, override X-Forwarded-Proto to https.
How to test?
Configure a resource with ssl: true (HTTPS termination) proxying to an HTTP backend that echoes or logs X-Forwarded-Proto.
Before fix: header is http. After fix: header is https.
Verify plain HTTP connections (port 80, no TLS) still produce X-Forwarded-Proto: http.
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.
## 📋 Pull Request Information
**Original PR:** https://github.com/fosrl/newt/pull/353
**Author:** [@rinseaid](https://github.com/rinseaid)
**Created:** 5/14/2026
**Status:** ✅ Merged
**Merged:** 5/14/2026
**Merged by:** [@oschwartz10612](https://github.com/oschwartz10612)
**Base:** `main` ← **Head:** `fix/x-forwarded-proto-tls`
---
### 📝 Commits (3)
- [`817824b`](https://github.com/fosrl/newt/commit/817824bd6fee04b188e6c657de39e17b4d06f19f) Fix X-Forwarded-Proto always set to "http" for TLS connections
- [`b6e2d61`](https://github.com/fosrl/newt/commit/b6e2d61a18a8d85f4e7f56bc56cdc44d94ada062) Add workflow to build patched image to ghcr.io/rinseaid/newt:patched
- [`55ca18a`](https://github.com/fosrl/newt/commit/55ca18a1dbc4443c005031c4645d63794fb5e092) Delete .github/workflows/build-patched.yml
### 📊 Changes
**1 file changed** (+7 additions, -0 deletions)
<details>
<summary>View changed files</summary>
📝 `netstack2/http_handler.go` (+7 -0)
</details>
### 📄 Description
## 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.
### Preface
This PR was developed with Claude Code (claude-opus-4-6). I identified the bug, traced the root cause through the code, and directed the fix. Claude wrote the patch. I reviewed and validated all changes.
## Description
When Newt terminates TLS on incoming connections, `X-Forwarded-Proto` is always set to `http` in requests forwarded to downstream targets. Backend applications that rely on this header to construct callback URLs (OIDC redirect URIs, CSRF origin checks, etc.) generate incorrect `http://` URLs.
`HandleConn` wraps `*tls.Conn` inside `httpConnCtx`, which embeds `net.Conn`. Go's `http.Server` detects TLS by type-asserting the accepted connection to `*tls.Conn`, but this assertion fails against the wrapper type. `http.Request.TLS` is always nil, so `httputil.ProxyRequest.SetXForwarded()` always writes `X-Forwarded-Proto: http`.
The fix reuses the `isTLS` flag already stored on the request context by `ConnContext` (the same flag used for the HTTP-to-HTTPS redirect in `handleRequest`). After `SetXForwarded()`, if `isTLS` is true, override `X-Forwarded-Proto` to `https`.
## How to test?
- Configure a resource with `ssl: true` (HTTPS termination) proxying to an HTTP backend that echoes or logs `X-Forwarded-Proto`.
- Before fix: header is `http`. After fix: header is `https`.
- Verify plain HTTP connections (port 80, no TLS) still produce `X-Forwarded-Proto: http`.
- Verify OIDC flows behind Newt generate `https://` callback URLs.
---
<sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
📋 Pull Request Information
Original PR: https://github.com/fosrl/newt/pull/353
Author: @rinseaid
Created: 5/14/2026
Status: ✅ Merged
Merged: 5/14/2026
Merged by: @oschwartz10612
Base:
main← Head:fix/x-forwarded-proto-tls📝 Commits (3)
817824bFix X-Forwarded-Proto always set to "http" for TLS connectionsb6e2d61Add workflow to build patched image to ghcr.io/rinseaid/newt:patched55ca18aDelete .github/workflows/build-patched.yml📊 Changes
1 file changed (+7 additions, -0 deletions)
View changed files
📝
netstack2/http_handler.go(+7 -0)📄 Description
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.
Preface
This PR was developed with Claude Code (claude-opus-4-6). I identified the bug, traced the root cause through the code, and directed the fix. Claude wrote the patch. I reviewed and validated all changes.
Description
When Newt terminates TLS on incoming connections,
X-Forwarded-Protois always set tohttpin requests forwarded to downstream targets. Backend applications that rely on this header to construct callback URLs (OIDC redirect URIs, CSRF origin checks, etc.) generate incorrecthttp://URLs.HandleConnwraps*tls.ConninsidehttpConnCtx, which embedsnet.Conn. Go'shttp.Serverdetects TLS by type-asserting the accepted connection to*tls.Conn, but this assertion fails against the wrapper type.http.Request.TLSis always nil, sohttputil.ProxyRequest.SetXForwarded()always writesX-Forwarded-Proto: http.The fix reuses the
isTLSflag already stored on the request context byConnContext(the same flag used for the HTTP-to-HTTPS redirect inhandleRequest). AfterSetXForwarded(), ifisTLSis true, overrideX-Forwarded-Prototohttps.How to test?
ssl: true(HTTPS termination) proxying to an HTTP backend that echoes or logsX-Forwarded-Proto.http. After fix: header ishttps.X-Forwarded-Proto: http.https://callback URLs.🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.