Skip to content

Commit

Permalink
Fix resolution of relative container URL redirects
Browse files Browse the repository at this point in the history
  • Loading branch information
pilaf committed Jan 5, 2024
1 parent 0fbcab9 commit b6ba0cd
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 6 deletions.
6 changes: 5 additions & 1 deletion lib/fmrest/v1/container_fields.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,11 @@ def fetch_container_data(container_field_url, base_connection = nil)
raise FmRest::ContainerFieldError, "Container field's initial request didn't return a session cookie, the URL may be stale (try downloading it again immediately after retrieving the record)"
end

url = URI(e.io.meta["location"])
url = if e.io.meta["location"].match(/\Ahttps?:/)
URI(e.io.meta["location"])
else
URI.join("#{url.scheme}://#{url.host}:#{url.port}", e.io.meta["location"])
end

# Now request the URL again with the proper session cookie using
# OpenURI, which wraps the response in an IO object which also responds
Expand Down
19 changes: 14 additions & 5 deletions spec/core/v1/container_fields_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
let(:extendee) { Object.new.tap { |obj| obj.extend(described_class) } }

describe "#fetch_container_data" do
let(:container_url) { "https://foo.bar/qux" }
let(:container_url) { "https://foo.bar:4444/qux" }

context "when given an invalid URL" do
it { expect { extendee.fetch_container_data("boo boo") }.to raise_error(FmRest::ContainerFieldError, /Invalid container field URL/) }
Expand All @@ -27,16 +27,25 @@
context "when the given URL is a redirect" do
context "but doesn't return a Set-Cookie header" do
it "raises an FmRest::ContainerFieldError" do
stub_request(:get, container_url).to_return(status: 302, headers: { "Location" => container_url })
stub_request(:get, container_url).to_return(status: 302, headers: { "Location" => "/irrelevant" })

expect { extendee.fetch_container_data(container_url) }.to raise_error(FmRest::ContainerFieldError, /session cookie/)
end
end

context "and returns a Set-Cookie header" do
context "when it responds with a Set-Cookie and an absolute Location header" do
it "returns an IO object with the container field contents" do
stub_request(:get, container_url).to_return(status: 302, headers: { "Location" => container_url, "Set-Cookie" => "secret cookie" })
stub_request(:get, container_url).with(headers: { "Cookie" => "secret cookie" }).to_return(body: "hi there")
stub_request(:get, container_url).to_return(status: 302, headers: { "Location" => "https://foo.bar:4444/absolute", "Set-Cookie" => "secret cookie" })
stub_request(:get, "https://foo.bar:4444/absolute").with(headers: { "Cookie" => "secret cookie" }).to_return(body: "hi there")

expect(extendee.fetch_container_data(container_url).read).to eq("hi there")
end
end

context "when it responds with a Set-Cookie and a relative Location header" do
it "returns an IO object with the container field contents" do
stub_request(:get, container_url).to_return(status: 302, headers: { "Location" => "/relative", "Set-Cookie" => "secret cookie" })
stub_request(:get, "https://foo.bar:4444/relative").with(headers: { "Cookie" => "secret cookie" }).to_return(body: "hi there")

expect(extendee.fetch_container_data(container_url).read).to eq("hi there")
end
Expand Down

0 comments on commit b6ba0cd

Please sign in to comment.