GithubHelp home page GithubHelp logo

Relative URI resolution about modern-uri HOT 9 CLOSED

mrkkrp avatar mrkkrp commented on June 1, 2024
Relative URI resolution

from modern-uri.

Comments (9)

mrkkrp avatar mrkkrp commented on June 1, 2024

This is a good catch, it lacks that functionality.

would you accept a pull request to do this?

Certainly!

from modern-uri.

mjepronk avatar mjepronk commented on June 1, 2024

OK, I have a question regarding the representation of a parsed URI. It seems that it's impossible right now to tell based on the URI data if a URL ended with a trailing slash or not. For example:

λ> mkURI "/foo/bar"
URI {uriScheme = Nothing, uriAuthority = Left True, uriPath = ["foo","bar"], uriQuery = [], uriFragment = Nothing}
λ> mkURI "/foo/bar/"
URI {uriScheme = Nothing, uriAuthority = Left True, uriPath = ["foo","bar"], uriQuery = [], uriFragment = Nothing}

This is necessary to correctly handle the merge paths operation as defined in section 5.2.3 of RFC 3986.

My suggestion would be to add a trailing empty string to the uriPath list if the path ended with a slash. But of course this may give issues with existing code not expecting it. Or do we need to change the URI data type?

from modern-uri.

mrkkrp avatar mrkkrp commented on June 1, 2024

We must represent /foo/bar/ as a URI with uriPath equal to ["foo","bar",""]. The current behavior is a consequence of my desire to collapse consecutive slashes automatically, I'd still prefer to retain that behavior except in the case when the empty path piece occurs at the end.

The code of interest is this (the filter should not remove empty path piece if it's the last piece in a path):

https://github.com/mrkkrp/modern-uri/blob/master/Text/URI/Parser/Text.hs#L105

Similarly for ByteString:

https://github.com/mrkkrp/modern-uri/blob/master/Text/URI/Parser/ByteString.hs#L152

from modern-uri.

mjepronk avatar mjepronk commented on June 1, 2024

OK, great. I'll make the change.

from modern-uri.

mjepronk avatar mjepronk commented on June 1, 2024

It's weird, when I change filter on line 105 of Text.URI.Parser.Text with my function filterButLast below, I get a parse error on URL's that end with a '/'. Do you have any idea why?

filterButLast :: (a -> Bool) -> [a] -> [a]
filterButLast _ [] = []
filterButLast _ [x] = [x]
filterButLast p (x : xs)
  | p x       = x : filterButLast p xs
  | otherwise = filterButLast p xs

from modern-uri.

mjepronk avatar mjepronk commented on June 1, 2024

Parse error is because mkPathPiece does not accept empty string:

λ> mkPathPiece ""
*** Exception: RTextException PathPiece ""

Should we modify this function?

from modern-uri.

mrkkrp avatar mrkkrp commented on June 1, 2024

OK, sorry, I have advised you wrong.

The mkPathPiece smart constructor imposes the invariant that path pieces cannot be empty, thus we automatically avoid consecutive slashes, the behavior of the parser is just a consequence of this (there is no other way for it to function without breaking the invariant, as you have just discovered).

The presence of the trailing slash is obviously must be encoded in the URI data type. The first things that comes to mind is to add a new field to the record, say, uriPathTrailingSlash :: Bool, but it's not good, because trailing slash only makes sense when the path is not empty, i.e. it contains at least one path piece. Otherwise the trailing slash will be the same as leading slash that determines whether the path is absolute or relative, and that's another story.

So the proper solution is a breaking change in this spirit:

data URI = URI
  { ...
  , uriPath :: Maybe (Bool, NonEmpty PathPiece)
  , ...
  }

Here, Nothing would represent the empty path. When path is not empty we have Just and only in that case we have the chance to specify the Bool which tells us whether we have a trailing slash or not. I think it's best to keep NonEmpty PathPiece in the functorial position (of vanilla covariant functor, Functor), so it's easier to manipulate with fmap, so the Bool should go first in the tuple.

Then, once we have this, we should still provide normalized path (as a [] list) with lenses and a new 0-1 traversal which would allow to manipulate the trailing slash component.

Docs, tests, etc. this would take some time. If you feel like you're up to this refactoring, you're welcome to try. Otherwise, I'm busy with other stuff right now, but I will have the time for this in the beginning of January, so after the refactoring you could return to the URI resolution problem.

What do you think?

from modern-uri.

mjepronk avatar mjepronk commented on June 1, 2024

Thank you for the explanation. I agree with you that this is the best route to take. I'll try to implement this change and see if it works for all cases.

from modern-uri.

mrkkrp avatar mrkkrp commented on June 1, 2024

Resolved in 0214160.

from modern-uri.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.