undici icon indicating copy to clipboard operation
undici copied to clipboard

undici.fetch does not append url fragments (url.hash)

Open jennyEckstein opened this issue 2 years ago • 10 comments

Bug Description

At the moment undici.fetch does not support GET requests with fragments

Reproducible By

See repository to reproduce here

Expected Behavior

undici.fetch should be able to handle fragments in url. Fix: add url.hash here

Logs & Screenshots

See repo ☝️

Environment

macOS Catalina 10.15.7 Node v16.10.0

Additional context

I would be happy to open PR.

jennyEckstein avatar Feb 21 '22 23:02 jennyEckstein

PR welcome

ronag avatar Feb 22 '22 06:02 ronag

I think we have the same problem in all undici api's

ronag avatar Feb 22 '22 06:02 ronag

I thought that the fragment should not be sent to the remote server?

targos avatar Feb 22 '22 06:02 targos

I thought that the fragment should not be sent to the remote server?

I actually don't know. Anyone know what the spec says? What does Chrome do?

ronag avatar Feb 22 '22 07:02 ronag

I thought that the fragment should not be sent to the remote server?

@targos I think you are right, I found this in wiki.

Clients are not supposed to send URI fragments to servers when they retrieve a document, and without help from a local application (see below) fragments do not participate in HTTP redirections.

I am testing another approach I can take. My problem comes down to: I am trying to write unit tests and using MockAgent to intercept requests. It looks like the path must be identical in order for the url to be intercepted. I am not able to set path to /foo and then expect to fetch /foo#bar=baz because the paths don't match.

jennyEckstein avatar Feb 22 '22 16:02 jennyEckstein

Upon further investigation, I can confirm that undici.fetch works correctly. Server receives path with no fragment (as it is supposed to). The issue is strictly related to the use of MockAgent and the way it stores and compares intercepted path here. The values must be strictly equal and do not account for stripping fragments or query strings. This function needs to be modified to behave just like it would with real server.

jennyEckstein avatar Feb 22 '22 19:02 jennyEckstein

I think this interpretation is somewhat dubious. In the Fetch standard, it says it should with a work a URL as per its definition, and its definition includes fragments. So maybe the URI spec is outdated in relation to the Fetch spec? cc @ronag

galvez avatar Feb 25 '22 13:02 galvez

What does Chrome do?

ronag avatar Feb 25 '22 14:02 ronag

Chrome's fetch() doesn't send #hash indeed. I think we can safely close this then.

galvez avatar Feb 25 '22 14:02 galvez

I think a better solution to this problem is to remove the hash from the intercept call, e.g. make behave https://github.com/jennyEckstein/undici.fetch-url-hash/blob/996b50f06ad6a2fc7e2e65f4e4eaaab814914300/index.js#L15 like mockPool.intercept({ method: "GET", path: "/test?foo=bar" or possibly make it throw if there is an hash specified.

mcollina avatar Feb 25 '22 15:02 mcollina