-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Inconsistent default port number in HttpURI and HostPort #11488
Comments
Personally, I prefer a default value of
if the port number is |
@cowwoc the HttpURI class has undergone some changes in Jetty 12.0.7, esp around port numbers. You can test 12.0.7 right now by using the maven repository URL https://oss.sonatype.org/content/groups/jetty-with-staging/ Also, be careful of the multi-parameter URI constructors. Eg:
The host, path, query, and fragment parameters can all experience this encoding step. |
@joakime Interesting. Take a look at https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/net/URI.html#identities-heading So you're right that the constructors encode the parameters, but it turns out that the getters (e.g. So long as |
Nope, as the
|
This doesn't happen with the single constructor version, (or
Note that per the URI spec, the path |
It doesn't sound like we're talking about the same thing exactly. I agree that If you use the URI constructor that accepts multiple components as input, and then read them out using the individual getters, you should get back your original values. I believe the problem only occurs if you push in multiple components then try to pull out a full string, or vice-versa. So long as your in and out operations are consistent you should be okay. That's why I said that if |
Yes, but the flaw is that things like It should never decode a reserved character - https://datatracker.ietf.org/doc/html/rfc3986#section-2.2 If you use the multi-arg URI constructor, and have very precise pct-encoding requirements, such as needing to use
But what if what you want to have encoded is a reserved character?
No, we cannot do that with the multi-arg constructor. Note that URI is also braindead when it comes to UTF-8.
There's no way in the URI class to obtain the properly encoded path segment with UTF-8 encoding. Unlike other auto-encoding characters.
Spring has this bug btw, as it relies on the multi-arg constructor. It's not possible to send, using the spring Http client, the path If you want to see how messy things can get, check out the https://github.com/jetty/jetty.project/blob/jetty-12.0.x/jetty-ee10/jetty-ee10-servlet/src/test/resources/jar-resource-odd.jar
While these are difficult to exist on all filesystems, they are perfectly valid names for resources from a jar/zip/war, and can be accessed via Jetty (even have properly encoded directory listings produced) Anyway, this is a long side conversation now. 😄 Have you tested 12.0.7 changes? |
:) Sorry, I was tied up with frontend bugs today. I'll take a look later on this week. Regarding the URI discussion, it sounds like you are saying that the only safe constructor to use is Honestly, I think that we need a UriBuilder-style API with a clean room implementation. In an ideal world, we'd have a framework-independent implementation that Jetty and others could just link against. Baring that, you could just add your own version inside Jetty. Using |
The discussion seems to have strayed from the original topic: do we need to change Jetty's default port number to |
I would still recommend it for consistency. I'd there any downside to it? The URI class uses -1 and everywhere else in Jetty's code port 0 means "any available port". The reason we strayed into the URI conversation was that the original use-case that promoting this issue was the ability to build a new URI based on an existing HttpURI. Unless you plan to remove all getter methods and force users to use toURI() then I'd argue HttpURI must behave likes a URI itself. I still haven't had a chance to try out version 12.0.7 but I'll try to get around to it later on today. |
I reviewed the latest version jetty.project/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpURI.java Line 862 in efafbed
Shouldn't this set the port to |
Hey guys, I think version 12.0.7 is broken. When a client requests:
I invoke
This is because You might want to consider releasing a hot-patch to fix this because this is a pretty common operation. |
I tracked the problem down to the I suggest changing jetty.project/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/HttpURI.java Line 554 in efafbed
to as well as fixing #11488 (comment) And it wouldn't hurt to add a unit test to cover some of these use-cases... |
@joakime any update on fixing this bug? |
@sbordet Do you guys plan to fix this bug before releasing version 12.0.8? |
+ Changing unset port in HttpURI to -1 (from 0) + Changing unset port in HostPort to -1 (from 0)
Only tuning in here late in the conversation. Given that a) there is inconsistent usage of -1 and 0; b) neither -1 nor 0 are valid ports; then we should be strict in what we generate and lenient in what we accept. I.e. passing in a port <=0 should mean the same thing. We should never ever generate a URI with "host:0" as the authority (can we fix that at least for 12.0.8?) |
@cowwoc I believe we have already fixed the ":0" port issue in #11468 that was in 12.0.7??? So I cannot reproduce what you report in #11488 (comment) I just wrote/ran the test: @Test
public void testDefaultPort()
{
HttpURI uri = HttpURI.from("http://host/path/info;param?query=value#fragment");
assertThat(uri.getScheme(), is("http"));
assertThat(uri.getUser(), nullValue());
assertThat(uri.getHost(), is("host"));
assertThat(uri.getPort(), is(-1));
assertThat(uri.getPath(), is("/path/info;param"));
assertThat(uri.getCanonicalPath(), is("/path/info"));
assertThat(uri.getParam(), is("param"));
assertThat(uri.getQuery(), is("query=value"));
assertThat(uri.getFragment(), is("fragment"));
assertThat(uri.getAuthority(), is("host"));
assertThat(uri.toURI().toASCIIString(), is("http://host/path/info;param?query=value#fragment"));
} which passes fine. I also note that our asString code says: if (normalizedPort > 0)
out.append(':').append(normalizedPort); and we never call the URI constructor that takes components anymore (as it just re-assembles them and parses the string anyway). So I cannot reproduce. If we did produce a URI like So please check if you can reproduce in 12.0.7 ASAP, as we are closing the door on 12.0.8 very soon. |
@gregw I'll get back to you with a testcase later on today. |
@gregw It turns out that
Consequently, when user code invokes Is this sufficient information to reproduce the problem? I'd make the following changes:
|
Is it safe to assume that this fix will be included in version 12.0.9, which is due out in ~1 month from now? |
Yes, barring anything that would cause us to revert it, this is going to be in 12.0.9 |
Perfect, thank you! |
Jetty version(s)
12.0.6
Jetty Environment
core
Description
HttpURI.Immutable(String) uses a default port number of
-1
butHostPort
uses a default value of0
. This means that anyone who wants to parse URIs coming from Jetty needs to handle both possible values.Expected behavior: use a consistent default across all classes in Jetty.
Related issue/comment: #7269 (comment)
The text was updated successfully, but these errors were encountered: