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

Include a new, useful URI class #1005

Open
gissuebot opened this issue Oct 31, 2014 · 19 comments
Open

Include a new, useful URI class #1005

gissuebot opened this issue Oct 31, 2014 · 19 comments

Comments

@gissuebot
Copy link

Original issue created by jessewilson@google.com on 2012-05-16 at 07:51 PM


The problem with Java is it lacks a URI class that can manipulate query parameters properly.

@gissuebot
Copy link
Author

Original comment posted by jessewilson@google.com on 2012-05-16 at 07:51 PM


cgdecker: "I have wished that there were a better way of building URIs."

@gissuebot
Copy link
Author

Original comment posted by ullenboom on 2012-05-18 at 02:11 PM


Enterprise developers can use the new Jersey 2.0 API. Take a look at http://jax-rs-spec.java.net/nonav/2.0-SNAPSHOT/apidocs/javax/ws/rs/core/UriBuilder.html. Jersey is the JAX-RS 2.0 RI and JAX-RS will be part of Java EE 7. Then there will be some kind of URI-manipulating API.

@gissuebot
Copy link
Author

Original comment posted by kevinb@google.com on 2012-06-19 at 05:28 PM


We want to do this, but there are numerous challenges.


Status: Accepted
Labels: Type-Addition, Package-Net

@gissuebot gissuebot mentioned this issue Nov 1, 2014
@gissuebot
Copy link
Author

Original comment posted by cpovirk@google.com on 2012-11-07 at 07:42 PM


(No comment entered for this change.)


Blocking: #1191

@gissuebot
Copy link
Author

Original comment posted by amertum on 2013-01-24 at 12:24 PM


Maybe you can provide different tools which integrate easily with different apps.

For example, we need a query param handler to do something like :

QueryParams.from(Map<String, String[]>).get("param").firstOr("defaultValue");
QueryParams.from(Map<String, String[]>).get("param").firstAsIntOr(5);
QueryParams.from(Map<String, String[]>).get("param").allOr("value1", "value2");
QueryParams.from(Map<String, String[]>).get("param").allAsIntOr(1, 2);

@EricEdens
Copy link

I like this idea. Any thoughts on an API?

@swankjesse
Copy link
Contributor

FYI, we're doing this in OkHttp. I'm hoping to get something that solves most HTTP use cases, including IDNs.
square/okhttp#1486

@EricEdens
Copy link

Maybe a good place to start is the target spec. RFCs 2396 and 3986 are good candidates. Android's Uri and Java's URI do 2396. However 3986 is listed as obsoleting 2396.

Whatwg has a spec for URLs, which I think Jesse is targeting in OkHTTP.

Thoughts?

@swankjesse
Copy link
Contributor

The WHATWG spec is the best yet, but it's still not exactly consistent with what the browsers do. And the browsers themselves aren't consistent with each other. I ended up doing a lot of research, including this:
https://docs.google.com/spreadsheets/d/1BgGAhJ5WE3JBsATeudamiBzxmgEhwkfcFqQmPx8qrkc/edit#gid=0

@EricEdens
Copy link

Wow, that spreadsheet is terrifying! Well, given the multitude of specs and inconsistent behavior, maybe it's wise to divide the problem:

  • Allow different types of URIs by creating a base Uri that's intended to be extended.
  • Support additional specs by isolating encoding and decoding into its own class(es).

Here's a 50Kft sketch:

/**
 * Spec independent. Can be extended for other URIs such
 * as URL, MAILTO, or LDAP.
 */
Uri
    String getScheme()
    String getAuthority()
    ...

UriBuilder<T extends Uri>
    T build();
    UriBuilder<T extends Uri> scheme(String scheme)
    UriBuilder<T extends Uri> authority(String authority)
    ...

/**
 * Spec specific.
 */
UriCodec<T extends Uri>
    T decode(String uriString)
    String encode(T uri)

@swankjesse
Copy link
Contributor

Nah, my policy has been to just write one good URL that does what you want. Nobody wants to decide between Firefox parsing mode and Chrome parsing mode, they just want something that's going to work.

For example, today I'm doing the first steps towards IDNA mapping.
square/okhttp#1612

@EricEdens
Copy link

My thought was to choose a spec - let's say 3986 - and implement that for Guava. But factor things such that it'd be easy for clients to extend for other specs and schemes.

@cpovirk
Copy link
Member

cpovirk commented May 25, 2015

(While I'm replying to URL threads....)

I'm pretty confident that the WHATWG spec is the only spec worth following nowadays. (One of the serious problems with common.net.Uri is that it follows RFC 3986.) And while I've only skimmed over OkHttp's HttpUrl, I predict that we're now more likely to migrate Google to it (or to some other WHATWG-based implementation, should one catch on) than to introduce our own open-source URL class. (But to throw some water on that: We're now talking a very, very small chance rather than a very, very, very small chance.)

@swankjesse
Copy link
Contributor

The WHATWG spec is good, but it isn't perfect. There are a few edge cases where it disagrees with what the browsers actually do.

@cpovirk
Copy link
Member

cpovirk commented May 25, 2015

@swankjesse , have you spoken to the people behind the spec? From what I understand, it's still a work in progress. They'd probably be happy to hear about discrepancies, or if they're aware of them, they might be able to tell us why they exist (where there are security reasons, whether browsers have committed to change their behavior, whatever).

@EricEdens
Copy link

@cpovirk , other than following the WHATWG spec, any thoughts on what would make a good URL library? Maybe some tough learnings from the multiple implementations that you already have?

@cpovirk
Copy link
Member

cpovirk commented May 26, 2015

That's the big thing (and the one that makes migrating Google's own code very difficult). Aside from giving general advice like "immutability" and "builders," I glanced over our open issues. They seem to be mostly things that Jesse has covered -- for example, better accessors like pathSegments. Unless we're able to investigate a bunch of time into this (which would happen late this year at best), my plan will be "assume Jesse is right about everything" :) Sorry that I don't have anything more specific for you.

@EricEdens
Copy link

You're right - Jesse is very wise :)

google.common.net has several classes that could be used within a more general URL class (eg HostAndPort). Would you be open to additional sub-URL classes? For example: QueryParams, PathSegments, etc?

QueryParams could be a good start. If there's even a very, very, very small chance, I'd be happy to open an issue to bounce a design and, if it moves forward, write a patch.

@swankjesse
Copy link
Contributor

You're all too kind. @EricEdens please grab OkHttp if that's sufficient for you. If it's too much, extracting HttpUrl into its own standalone thing is also possible. Though I don't think I'll do that, you're welcome to. There's been non-zero demand.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants