-
-
Notifications
You must be signed in to change notification settings - Fork 47
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
web-server/dispatch should facilitate handling trailing "/"s on URLs #59
Comments
I think the right thing to do is for you not use the result of |
That is what I am doing now. I think for some reason I had originally thought that function on the right-hand side of a As I've started diving into the weeds, I think I agree that I'm still working on this for my own application: writing this issue revealed ways my URL handling still wasn't working as expected even after my first attempt at a work-around. My current plan is to:
|
Related to my proposed web-server/web-server-lib/web-server/dispatchers/filesystem-map.rkt Lines 25 to 28 in 894613d
As illustrated in the program below, I'm not sure if this code should treat I guess I would have expected |
(Apparently I neglected to paste the example above ...) #lang racket
(require net/url-string
rackunit)
(define (path-element->url elem)
(url "https" #f "example.com" #f #t
(list (path/param "a" null)
(path/param elem null)
(path/param "b" null))
null #f))
(for ([pr '(["" . "https://example.com/a//b"]
["." . "https://example.com/a/%2e/b"]
[same . "https://example.com/a/./b"]
[".." . "https://example.com/a/%2e%2e/b"]
[up . "https://example.com/a/../b"])])
(match-define (cons elem rendered) pr)
(check-equal? (url->string (path-element->url elem))
rendered))
(check-equal? (url->path (path-element->url ""))
(url->path (path-element->url 'same)))
(for ([special '("." "..")])
(check-exn #rx"bytes->path-element.*names a special element"
(λ () (url->path (path-element->url special))))) |
I fixed this by adding an extra |
A note in the documentation on |
Just a quick note to say, that in many situations it is simpler to redirect to the canonical url. With these dispatch rules
Any requests to If the blog contains references to stylesheets using relative urls then the canonical url works best. |
I recently discovered that
dispatch-rules
and related forms make it hard to handle trailing/
s on URLs sensibly.The URL
https://example.com/foo/
(with a trailing/
) is treated differently thanhttps://example.com/foo
(without a trailing/
). Strictly speaking, this is correct: those are two distinct URLs, and in principle one could serve completely unrelated content at each. In practice, though, users don't expect such URLs to be distinct. Serving different non-error content at one than the other is a terrible idea, and even returning a successful response from one variant but, e.g., a 404 error from the other (as my sight was doing) is likely to cause confusion. I expect most programs will want to either redirect the less-preferred variant to the canonical variant or simply treat both variants as equivalent.Unfortunately,
web-server/dispatch
doesn't provide a great way to implement such behavior. Here's an example in code of the current state of affairs:This illustrates a few things:
/
and has a single, empty path element (""
).()
is allowed as a pattern, but (due to the above) will never match anything. I think it might be better to make this a syntax error (or a warning that will become an error in a future release)./
adds an empty path element (""
) to the end of the URL.cleanse-path
-like case for multiple adjacent/
separators.I have changed my application to handle trailing
/
separators by usingdispatch-rules+applies
instead ofdispatch-rules
(which involved removing myelse
clause) and, if the original request does not satisfy the predicate fromdispatch-rules+applies
but a version with a normalized path would, responding with a redirect to the normalized path.I think it would be better to extend
web-server/dispatch
to support this sort of thing, but I'm not sure yet what the best way would be to do so. A few things I've been thinking about so far:dispatch-rules
patterns doesn't have a notion of "splicing" patterns: each string literal orbidi-match-expander
use applies to a single path element.301 Moved Permanently
has issues for methods other thanGET
andHEAD
and308 Permanent Redirect
doesn't have a straightforward fallback for older browsers. I would want to do a301 Moved Permanently
forGET
andHEAD
requests and307 Temporary Redirect
for other methods, which RFC 7231 suggests is reasonable. The higher-level question is the trade-off between a simple API that "does the right thing" and configurability./
support where a similar ability to handle variants on canonical URLs would be nice: for example, case-insensitivity. I can imagine possible extensions to thedispatch-rules
API to add a general concept of non-canonical URLs, and it is appealing from one perspective to avoid making trailing/
support a baked-in special feature. On the other hand, though, there seems a risk of getting beyond the scope of this library.The text was updated successfully, but these errors were encountered: