-
Notifications
You must be signed in to change notification settings - Fork 335
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
Behaviour of Url::join #333
Comments
From the example code in the documentation, it looks like it appends a path segment as you expected. extern crate url;
use url::Url;
fn main() {
let url = Url::parse("https://example.net/foo/").unwrap();
let url = url.join("bar").unwrap();
assert_eq!(url.as_str(), "https://example.net/foo/bar");
} Could you share the input you were using and the output you were expecting? |
f the joined path does not start with a slash, it replaces the last path segment which works fine if the url ends with a slash, but works unexpectedly (at least for me) when it does not. If the joined path does start with a slash, it replaces the entire path, regardless of whether the url ends with one. let u = url::Url::parse("http://domain.com/a/b").unwrap();
let u2 = u.join("c").unwrap();
println!("{}", u2);
let u3 = u.join("d/e").unwrap();
println!("{}", u3);
let u3 = u.join("/f").unwrap();
println!("{}", u3); Output:
|
As a comparison, this is the behaviour when joining with Joining a path starting with a slash also replaces the whole path, but otherwise it appends a path segment and does not replace the last one. let p = PathBuf::from("/a/b");
let p2 = p.join("c");
println!("{}", p2.to_str().unwrap());
let p3 = p.join("d/e");
println!("{}", p3.to_str().unwrap());
let p4 = p.join("/f");
println!("{}", p4.to_str().unwrap());
|
Makes sense. I agree that is confusing. |
I'd also expect Path in std behaves this way as well, though. |
Evidently, for both Given this similar behavior of |
For what it’s worth For example, Given backward-compatibility constraints, either or both of these are acceptable:
Changing the behavior of |
Yeah I agree, hence my What would be a good name for a new method?
|
Note that If you only want to manipulate the path without touching other components, |
Nobody suggested a better alternative name, so I'm closing this. |
My suggestion would be renaming But ,due to the popularity of |
Looks like Node.js' url module calls this "resolve". At the very least, the documentation on |
I do think resolve is a better description of what it does than join. It is possible to rename as resolve and make join a deprecated alias to it. You just can't remove the alias anytime soon |
"Resolve" in the node.js thing is a legacy API, the actual API is just the URL constructor with 2 arguments. I still think join is a better name for this. |
This just bit me too. The behavior makes no sense compared to every other url library I've used. Also the lack of use of enums compared to the weird "can be a base boolean" seems an oversight given Rust powerful type system. Enum Url{ This api feels rough in places. |
If you intend to keep the name the same, I suggest adding an example to the doc-string explaining the use case of when the joining path (new/path to be appended) is preceded with a slash (it completely replaces the existing path). Theres an example of when the existing path lacks a trailing-slash, but non for the case I proposed (as far as I can see). |
I also think there should be an |
What would To append path segments one at a time (before any query of fragment without affecting them) there’s |
@SimonSapin that's up to the caller surely. If it contains bad URI symbols it shouldnt be the problem of the library but rather bad usage. |
Just adding my two cent comment here to give the discussion more relevance again. I agree with everyone here stating that the interface name
I would vote for the long term deprecation solution @tmccombs suggested. In the meantime it would be nice to add a new utility function which wraps the behavior of url.path_segments_mut()?.push(segment) which comes closest to what Just to provide some further ideas, here is another alternative name for the |
This issue has been closed for 4 years. There is no plan of renaming the method. That said: I did not make up the name https://docs.python.org/3/library/urllib.parse.html#urllib.parse.urljoin
https://docs.python.org/3/library/os.path.html#os.path.join
https://doc.rust-lang.org/std/path/struct.Path.html#method.join
(following that link)
|
Thanks for searching that up! These are actually good reasons for why the name is what it is. I must admit that I was wrong and I'm sorry for the inconvenience of bringing up that long closed issue. |
this function is an alternative to `Url::join` which addresses issues discussed in servo#333, mainly that `Url::join` is sensitive to trailing slashes is in the `Url`, and if the trailing slash is missing, may remove segments from the base url and replace them with segments from the joined `Url`. There are good reasons for `Url::join` to behave that way, because that is was is specified in the `Url` standard. However it's still inconvenient because it often leads to situations where, a service takes some base-url for some API as a config parameter, uses `Url::join` to append various routes to it and make requests, and if a trailing `/` is omitted in a config file, you don't figure it out until deploying and looking at logs and seeing nonsense requests failing. In many situations in web development these trailing `/` are not significant so this is easy to forget and can become just an annoying papercut. One suggestion in servo#333 was to add an alternative utility function that isn't sensitive to the trailing `/`'s in this way. This commit adds such a utility function with tests.
Url::join
has a very confusing name.I would expect it to append a path segment.
Instead, it replaces the whole base path, which is quite awkward.
If you want to actually join, you have to:
Personally I think join should append a new segment, but changing this might be too late...
If so, the time is now, before a 1.0.
Otherwise, I would suggest adding a new method, something like
add_segment
.The text was updated successfully, but these errors were encountered: