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

Fixes #4421 - HttpClient support for PROXY protocol. #4424

Merged
merged 3 commits into from
Dec 17, 2019

Conversation

sbordet
Copy link
Contributor

@sbordet sbordet commented Dec 15, 2019

Implemented support for the PROXY protocol in HttpClient.

Introduced Request.tag(Object) to tag requests that belong
to the same group (e.g. a client address) so that they can
generate a different destination.

The tag object may implement ClientConnectionFactory.Decorator
so that it can decorate the HttpDestination ClientConnectionFactory
and therefore work both with and without forward proxy configuration.

Signed-off-by: Simone Bordet simone.bordet@gmail.com

Implemented support for the PROXY protocol in HttpClient.

Introduced Request.tag(Object) to tag requests that belong
to the same group (e.g. a client address) so that they can
generate a different destination.

The tag object may implement ClientConnectionFactory.Decorator
so that it can decorate the HttpDestination ClientConnectionFactory
and therefore work both with and without forward proxy configuration.

Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
Copy link
Contributor

@gregw gregw left a comment

Choose a reason for hiding this comment

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

Don't like this at all!

The Tag mechanism appears loosely typed but will fail with a class cast exception if a tag of some random type is assigned.

The Info classes are poorly named and appear to have duplicate information in them (the server IP/port). It is not clear in their usage that they are describing a proxy tunnel.

I think the language of the API needs to be strongly typed and explicitly about Proxy, Tunnel, Connection, ForwardFor or something better than Tag and Info, which could be anything.

Does this need to be linked somehow with setting the Forwarded headers?

If this design is indeed the only viable solution, then it needs a lot more explanation what the Info and Tag are communicating and how they should be used.

@@ -48,6 +60,11 @@ public Address getAddress()
return address;
}

public Object getTag()
Copy link
Contributor

Choose a reason for hiding this comment

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

Is javadoc needed here to indicate that this is the same tag from the associated request?

int serverPort = connector.getLocalPort();

int clientPort = ThreadLocalRandom.current().nextInt(1024, 65536);
V1.Info info = new V1.Info("TCP4", "127.0.0.1", clientPort, "127.0.0.1", serverPort);
Copy link
Contributor

Choose a reason for hiding this comment

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

This example makes no sense to me? The user should not be dealing with IP addresses and ports like this. It is not entirely clean which client this is talking about - specifically it looks like I need to know my own client port before it has even been allocated (which it is not as I guess it is the port that we are forwarding??).
Why must the user specify information that is in the request anyway, such as the server and serverPort? Does it have to be server IP or can it be server name? What about servers with multiple IPs and DNS balancing?

@gregw
Copy link
Contributor

gregw commented Dec 15, 2019

@sbordet please remember to link #4421 in the PR description!

Updates after review.
Renamed Info -> Tag.
Added convenience constructors to class Tag.
Added test and server support for PROXY V1 UNKNOWN.

Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
@sbordet sbordet requested a review from gregw December 16, 2019 16:46
@joakime
Copy link
Contributor

joakime commented Dec 16, 2019

Don't like this at all!

The Tag mechanism appears loosely typed but will fail with a class cast exception if a tag of some random type is assigned.

Personally, I like the tag.

It's intentionally loosely typed, and can apply to anything related to destination resolution.
Even things that have nothing to do with proxies.

I could use it to tag requests with a common object that my application knows and uses.

I could use the tag to section off destinations by something arbitrary (like load clients and a minimum physical connections config).

Just because the tag can also apply to a proxy is a curiosity and isn't in conflict with the tag idea.
The information contained in the tag can be extended, to cover all these bases.
And the tag can also be used to satisfy highly custom connection ideas that even fall outside of the proxy concepts.

@gregw
Copy link
Contributor

gregw commented Dec 16, 2019

@joakime during the review, the name 'Tag' grew on me, specially with Info renamed to Tag so it is clear that it a class that can be used to tag requests and/or origins for proxy protocol.

Copy link
Contributor

@gregw gregw left a comment

Choose a reason for hiding this comment

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

It needs a little bit more javadoc in places.... and perhaps a null check for strange endpoints... but LGTM and can be merged.

this(null, 0);
}

public Tag(String srcIP, int srcPort)
Copy link
Contributor

Choose a reason for hiding this comment

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

probably should javadoc these constructors to say that null values mean that the proxy protocol will take the value from the EndPoint when then tag is applied to a specific connection (and not defaulted at construction).

Copy link
Contributor

Choose a reason for hiding this comment

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

Ditto v1

{
try
{
InetSocketAddress localAddress = endPoint.getLocalAddress();
Copy link
Contributor

Choose a reason for hiding this comment

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

Do all our endpoints return non null InetAddresses? What if this is applied to a UDP endpoint?

Updates after review.
Improved javadocs.

Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
@sbordet sbordet merged commit 129a51c into jetty-9.4.x Dec 17, 2019
@sbordet sbordet deleted the jetty-9.4.x-4421-httpclient_proxy_protocol branch December 17, 2019 09:36
@sbordet sbordet restored the jetty-9.4.x-4421-httpclient_proxy_protocol branch December 17, 2019 21:53
@sbordet sbordet deleted the jetty-9.4.x-4421-httpclient_proxy_protocol branch December 17, 2019 21:54
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.

3 participants