Skip to content

Commit

Permalink
Fix redirection and file path handling for URL with query strings (#111)
Browse files Browse the repository at this point in the history
* Redirect a/b?c=d to a/b/?c=d and not to a/b?c=d/

* Better index.html fallback in get_fs_path

* Add some tests
  • Loading branch information
tkf authored Oct 6, 2020
1 parent 52b4efa commit 6dd3e26
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 3 deletions.
17 changes: 14 additions & 3 deletions src/server.jl
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,15 @@ Return the filesystem path corresponding to a requested path, or an empty
String if the file was not found.
"""
function get_fs_path(req_path::AbstractString)::String
uri = HTTP.URI(req_path)
# first element after the split is **always** "/"
r_parts = HTTP.URIs.unescapeuri.(split(HTTP.URI(req_path).path[2:end], "/"))
r_parts = HTTP.URIs.unescapeuri.(split(uri.path[2:end], "/"))
fs_path = joinpath(r_parts...)
if !isempty(CONTENT_DIR[])
fs_path = joinpath(CONTENT_DIR[], fs_path)
end
# if no file is specified, try to append `index.html` and see
endswith(req_path, "/") && (fs_path = joinpath(fs_path, "index.html"))
endswith(uri.path, "/") && (fs_path = joinpath(fs_path, "index.html"))
# either the result is a valid file path in which case it's returned otherwise ""
if isfile(fs_path) || isdir(fs_path)
return fs_path
Expand All @@ -93,6 +94,16 @@ function get_fs_path(req_path::AbstractString)::String
end
end

"""
append_slash(url::AbstractString) -> url′::AbstractString
Append `/` to the path part of `url`; i.e., transform `a/b` to `a/b/` and `/a/b?c=d` to
`/a/b/?c=d`.
"""
function append_slash(url_str::AbstractString)
uri = HTTP.URI(url_str)
return string(endswith(uri.path, "/") ? uri : merge(uri; path = uri.path * "/"))
end

"""
serve_file(fw, req::HTTP.Request; inject_browser_reload_script::Bool = true)
Expand Down Expand Up @@ -130,7 +141,7 @@ function serve_file(fw, req::HTTP.Request; inject_browser_reload_script::Bool =

# Respond with 301 if the path is a directory
if isdir(fs_path)
return HTTP.Response(301, ["Location" => req.target * "/"])
return HTTP.Response(301, ["Location" => append_slash(req.target)])
end

ext = last(splitext(fs_path))[2:end]
Expand Down
8 changes: 8 additions & 0 deletions test/server.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,15 @@
@test LS.get_fs_path(req) == "test/dummies/index.html"
req = "/test/dummies/r%C3%A9sum%C3%A9/"
@test LS.get_fs_path(req) == "test/dummies/résumé/index.html"
req = "/test/dummies/"
@test LS.get_fs_path(req) == "test/dummies/index.html"
req = "/test/dummies/?query=string"
@test LS.get_fs_path(req) == "test/dummies/index.html"
cd(bk)

@test LS.append_slash("/a/b") == "/a/b/"
@test LS.append_slash("/a/b?c=d") == "/a/b/?c=d"
@test LS.append_slash("/a/b/?c=d") == "/a/b/?c=d"
end

#=
Expand Down

0 comments on commit 6dd3e26

Please sign in to comment.