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

Added support for proxy protocol v2. #2912

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

apollo13
Copy link
Contributor

@apollo13 apollo13 commented Jan 2, 2023

This PR adds support for proxy protocol v2 (v1 keeps working as well): https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt

Additionally I did rewrite the BytesIO usage to bytearray, the code becomes simpler imo because we can just keep a buffer around and resize it as needed.

gunicorn/http/message.py Outdated Show resolved Hide resolved
@apollo13
Copy link
Contributor Author

apollo13 commented Jan 27, 2023 via email

@frittentheke
Copy link

Very cool to have this feature!

"""\
Detect, check and parse proxy protocol.

:raises: ForbiddenProxyRequest, InvalidProxyLine.
:return: True for proxy protocol line else False
"""
if not self.cfg.proxy_protocol:
return False
return
Copy link
Collaborator

Choose a reason for hiding this comment

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

A docstring above still says "... else False".

And why did you decide change False to None?

Copy link
Owner

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is no longer needed. Previously the code checked the return value based on this and then changed behavior. Now the proxy protocol parsing is fully "transparent" and leaves the streams in a usable state for follow up. Will adjust the comment in a follow up commit.

if ver_cmd & 0xF == 0x00:
return # LOCAL command, do not change source addr

if fam == 0x11: # TCPv4
Copy link
Collaborator

Choose a reason for hiding this comment

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

How about to make constants with meaningful names for 0x11 and so on instead comments? Or enum.IntFlag?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds like a plan, will see what I can come up with.

s_addr, d_addr, s_port, d_port = struct.unpack(fmt, body)
except struct.error as e:
raise InvalidProxyHeader("cannot unpack %r: %s" % (body, e))
s_addr = str(ip_class(s_addr))
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why is it needed? - converting str -> ipaddress -> str. Why just not use str representation as is?

If it is needed for validation then where is the error handling?

Copy link
Owner

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

s_addr is never really a string but either an 4-byte integer (ipv4 case) or a 16-byte integer (ipv6 case). Those are "narrow" binary representations of the addresses and not directly usable. So this code is turning the address into something human readable.

As for validation errors: How much do we want to trust the trusted proxies to send the correct data? :D

@benoitc benoitc added this to the 21.0 milestone May 11, 2023
@apollo13
Copy link
Contributor Author

Hi @sirkonst and @benoitc -- sorry for the late reply; I have lost track here. I'll update and address the comments today. In the meantime it would be great if you could review #2913, due to the bugs in Unreader (at least if I understood the purpose of it correctly) I was not able to utilize it in this PR properly.

@apollo13
Copy link
Contributor Author

I think I have addressed all comments, as far as I can see the linting errors are coming from other files. Let me know what you think.

@tilgovi tilgovi modified the milestones: 21.0, 22.0 Dec 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants