From 5eb76d181223191015fe41d5956c265001b314fd Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Thu, 26 Nov 2020 20:36:31 -0500 Subject: [PATCH] Fix the `absuri` function to correctly handle relative location paths --- .github/workflows/ci.yml | 3 +++ src/URIs.jl | 17 ++++++++++++++++- test/absuri.jl | 15 +++++++++++++++ test/runtests.jl | 1 + 4 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 test/absuri.jl diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 489ac43..2b8251b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,6 +20,9 @@ jobs: - windows-latest arch: - x64 + exclude: + - os: windows-latest + version: 'nightly' steps: - uses: actions/checkout@v2 - uses: julia-actions/setup-julia@v1 diff --git a/src/URIs.jl b/src/URIs.jl index df4d0da..d7bfc31 100644 --- a/src/URIs.jl +++ b/src/URIs.jl @@ -455,7 +455,22 @@ function absuri(uri::URI, context::URI) @assert !isempty(context.host) @assert isempty(uri.port) - return URI(context; path=uri.path, query=uri.query) + if !(context.scheme in ["http", "https"]) || isempty(uri.path) || uri.path[1] == '/' + path = String(uri.path) + else + # > The "Location" header field is used to identify a newly created resource, or to redirect the recipient to a different location for completion of the request. + # > The field value consists of a single URI-reference. When it has the form of a relative reference ([RFC3986], Section 4.2), the final value is computed by resolving it against the effective request URI ([RFC3986], Section 5). + # Sources: + # 1. https://greenbytes.de/tech/webdav/draft-ietf-httpbis-p2-semantics-17.html#header.location + # 2. https://web.archive.org/web/20200926022629/https://greenbytes.de/tech/webdav/draft-ietf-httpbis-p2-semantics-17.html + # 3. https://www.rfc-editor.org/rfc/rfc3986.html#section-4.2 + # 4. https://web.archive.org/web/20201106144353/https://www.rfc-editor.org/rfc/rfc3986.html#section-4.2 + # 5. https://www.rfc-editor.org/rfc/rfc3986.html#section-5 + # 6. https://web.archive.org/web/20201106144353/https://www.rfc-editor.org/rfc/rfc3986.html#section-5 + path = String(uristring(normpath(joinpath(URI(; path = context.path), "..", String(uri.path))))) + end + + return URI(context; path=path, query=uri.query) end """ diff --git a/test/absuri.jl b/test/absuri.jl new file mode 100644 index 0000000..f7f5b18 --- /dev/null +++ b/test/absuri.jl @@ -0,0 +1,15 @@ +@testset "absuri.jl" begin + cases = [ + ("https://en.wikipedia.org/api/rest_v1/page/summary/Potatoes", "Potato", "https://en.wikipedia.org/api/rest_v1/page/summary/Potato"), + ("https://en.wikipedia.org/api/rest_v1/page/summary/Potatoes", "./Potato", "https://en.wikipedia.org/api/rest_v1/page/summary/Potato"), + ("https://en.wikipedia.org/api/rest_v1/page/summary/Potatoes", "/foo/bar/baz", "https://en.wikipedia.org/foo/bar/baz"), + ("https://en.wikipedia.org/api/rest_v1/page/summary/Potatoes", "https://julialang.org/foo/bar/baz", "https://julialang.org/foo/bar/baz"), + ] + for case in cases + url = case[1] + location = case[2] + actual_output = URIs.absuri(location, url) + expected_output = URIs.URI(case[3]) + @test actual_output == expected_output + end +end diff --git a/test/runtests.jl b/test/runtests.jl index aca9fb8..206640c 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -3,3 +3,4 @@ using Test include("uri.jl") include("url.jl") +include("absuri.jl")