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

Support multiple proxy servers in Forwarded header parsing #782

Merged
merged 5 commits into from
Jan 17, 2025

Conversation

lukasbindreiter
Copy link
Contributor

@lukasbindreiter lukasbindreiter commented Jan 16, 2025

Related Issue(s):
(none, since I directly created the Pull request for the fix)

Description:
According to the Forwarded HTTP header spec, multiple proxy servers can add values to the Forwarded header by creating a comma separated list:

If there are multiple proxy servers between the client and server, they may each specify their own forwarding information. This can be done by adding a new Forwarded header to the end of the header block, or by appending the information to the end of the last Forwarded header in a comma-separated list.

The existing ProxyHeaderMiddleware however doesn't account for this, and instead raises a ValueError in such cases, because it only splits the string on ; but not on , before that.

Therefore, a valid Forwarded header of b"proto=https;host=test:1234,proto=https;host=second-server:1111" produces a: ValueError: too many values to unpack (expected 2) because it essentially runs:

part = "host=test:1234,proto=https"  # because it doesn't split on `,` first
key, value = part.split("=")  # ValueError: too many values to unpack (expected 2)

I've encountered this when deploying our STAC API server on GCP Cloud run, behind a GCP Load balancer.
GCP doesn't even actually set the host but the middleware in place still causes all requests to fail with a ValueError.

(The header on GCP that we receive is b'for="85.193.181.55";proto=https,for="85.193.181.55";proto=https')

PR Checklist:

  • pre-commit hooks pass locally
  • Tests pass (run make test)
  • Documentation has been updated to reflect changes, if applicable, and docs build successfully (run make docs)
  • Changes are added to the CHANGELOG.

@vincentsarago
Copy link
Member

@lukasbindreiter hope you don't mind, I've pushed some change directly in your branch

Let me know how it looks for you and then I could merge and release this tomorrow

@lukasbindreiter
Copy link
Contributor Author

@lukasbindreiter hope you don't mind, I've pushed some change directly in your branch

Let me know how it looks for you and then I could merge and release this tomorrow

@vincentsarago
Awesome, thanks a lot!

I've made some small changes to it:

  • use compiled regexes
  • avoid groupdict and instead call group directly to avoid unnecessary dict creations

(worth it I think in this case, its an easy optimization thats twice as fast)
image

@lukasbindreiter
Copy link
Contributor Author

lukasbindreiter commented Jan 17, 2025

@vincentsarago everything looks ready from my side - would be awesome if you could take another look, and then merge it if everything is fine. Thanks a lot!

(I also just rebased it, there was a conflicting changelog entry already upstream)

@vincentsarago vincentsarago self-requested a review January 17, 2025 16:37
Copy link
Member

@vincentsarago vincentsarago left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great @lukasbindreiter 🙏

I'll merge this to main and maybe backport it to a 3.0.6 release if you absolutely need this in a 3.0.* version (next version in main has breaking change and will be released in a 3.1 or 4.0)

@vincentsarago vincentsarago merged commit 2a72400 into stac-utils:main Jan 17, 2025
8 checks passed
@lukasbindreiter
Copy link
Contributor Author

lukasbindreiter commented Jan 17, 2025

Awesome, thanks a lot! 🙏

It's fine if its in 3.1 or 4.0 - I already have the fixed version of the middleware inplace locally in my project and can just use that until this is released.

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.

2 participants