Skip to content

Commit 28108f8

Browse files
committed
Add the location to all responses returned
1 parent 87aabe1 commit 28108f8

File tree

4 files changed

+47
-22
lines changed

4 files changed

+47
-22
lines changed

lib/httpoison.ex

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
defmodule HTTPoison.Response do
2-
defstruct status_code: nil, body: nil, headers: []
3-
@type t :: %__MODULE__{status_code: integer, body: binary, headers: list}
2+
defstruct status_code: nil, body: nil, headers: [], location: nil
3+
@type t :: %__MODULE__{status_code: integer, body: binary, headers: list, location: binary | nil}
44
end
55

66
defmodule HTTPoison.AsyncResponse do
@@ -65,4 +65,3 @@ defmodule HTTPoison do
6565

6666
use HTTPoison.Base
6767
end
68-

lib/httpoison/base.ex

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -394,24 +394,26 @@ defmodule HTTPoison.Base do
394394

395395
case :hackney.request(method, request_url, request_headers,
396396
request_body, hn_options) do
397-
{:ok, status_code, headers, _client} when status_code in [204, 304] ->
398-
response(process_status_code, process_headers, process_response_body, status_code, headers, "")
399-
{:ok, status_code, headers} -> response(process_status_code, process_headers, process_response_body, status_code, headers, "")
397+
{:ok, status_code, headers, client} when status_code in [204, 304] ->
398+
response(process_status_code, process_headers, process_response_body, status_code, headers, "", :hackney.location(client))
399+
{:ok, status_code, headers} -> response(process_status_code, process_headers, process_response_body, status_code, headers, "", nil)
400400
{:ok, status_code, headers, client} ->
401+
location = :hackney.location(client) # FIXME The current version of Hackney (0.8) requires that we read the location before the body.
401402
case :hackney.body(client) do
402-
{:ok, body} -> response(process_status_code, process_headers, process_response_body, status_code, headers, body)
403+
{:ok, body} -> response(process_status_code, process_headers, process_response_body, status_code, headers, body, location)
403404
{:error, reason} -> {:error, %Error{reason: reason} }
404405
end
405406
{:ok, id} -> { :ok, %HTTPoison.AsyncResponse{ id: id } }
406407
{:error, reason} -> {:error, %Error{reason: reason}}
407408
end
408409
end
409410

410-
defp response(process_status_code, process_headers, process_response_body, status_code, headers, body) do
411+
defp response(process_status_code, process_headers, process_response_body, status_code, headers, body, location) do
411412
{:ok, %Response {
412413
status_code: process_status_code.(status_code),
413414
headers: process_headers.(headers),
414-
body: process_response_body.(body)
415+
body: process_response_body.(body),
416+
location: location
415417
} }
416418
end
417419
end

test/httpoison_base_test.exs

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,13 @@ defmodule HTTPoisonBaseTest do
3232
expect(:hackney, :request, [{[:post, "http://localhost", {:req_headers, []}, {:req_body, "body"}, []],
3333
{:ok, 200, "headers", :client}}])
3434
expect(:hackney, :body, 1, {:ok, "response"})
35+
expect(:hackney, :location, 1, "location")
3536

3637
assert Example.post!("localhost", "body") ==
3738
%HTTPoison.Response{ status_code: {:code, 200},
3839
headers: {:headers, "headers"},
39-
body: {:resp_body, "response"} }
40+
body: {:resp_body, "response"},
41+
location: "location" }
4042

4143
assert validate :hackney
4244
end
@@ -45,11 +47,13 @@ defmodule HTTPoisonBaseTest do
4547
expect(:hackney, :request, [{[:post, "http://localhost", {:req_headers, []}, {:req_body, "body"}, []],
4648
{:ok, 200, "headers", :client}}])
4749
expect(:hackney, :body, 1, {:ok, "response"})
50+
expect(:hackney, :location, 1, "location")
4851

4952
assert ExampleDefp.post!("localhost", "body") ==
5053
%HTTPoison.Response{ status_code: {:code, 200},
5154
headers: {:headers, "headers"},
52-
body: {:resp_body, "response"} }
55+
body: {:resp_body, "response"},
56+
location: "location" }
5357

5458
assert validate :hackney
5559
end
@@ -71,11 +75,13 @@ defmodule HTTPoisonBaseTest do
7175
expect(:hackney, :request, [{[:post, "http://localhost", [], "body", [connect_timeout: 12345]],
7276
{:ok, 200, "headers", :client}}])
7377
expect(:hackney, :body, 1, {:ok, "response"})
78+
expect(:hackney, :location, 1, "location")
7479

7580
assert HTTPoison.post!("localhost", "body", [], timeout: 12345) ==
7681
%HTTPoison.Response{ status_code: 200,
7782
headers: "headers",
78-
body: "response" }
83+
body: "response",
84+
location: "location" }
7985

8086
assert validate :hackney
8187
end
@@ -84,11 +90,13 @@ defmodule HTTPoisonBaseTest do
8490
expect(:hackney, :request, [{[:post, "http://localhost", [], "body", [recv_timeout: 12345]],
8591
{:ok, 200, "headers", :client}}])
8692
expect(:hackney, :body, 1, {:ok, "response"})
93+
expect(:hackney, :location, 1, "location")
8794

8895
assert HTTPoison.post!("localhost", "body", [], recv_timeout: 12345) ==
8996
%HTTPoison.Response{ status_code: 200,
9097
headers: "headers",
91-
body: "response" }
98+
body: "response",
99+
location: "location" }
92100

93101
assert validate :hackney
94102
end
@@ -97,11 +105,13 @@ defmodule HTTPoisonBaseTest do
97105
expect(:hackney, :request, [{[:post, "http://localhost", [], "body", [proxy: "proxy"]],
98106
{:ok, 200, "headers", :client}}])
99107
expect(:hackney, :body, 1, {:ok, "response"})
108+
expect(:hackney, :location, 1, "location")
100109

101110
assert HTTPoison.post!("localhost", "body", [], proxy: "proxy") ==
102111
%HTTPoison.Response{ status_code: 200,
103112
headers: "headers",
104-
body: "response" }
113+
body: "response",
114+
location: "location" }
105115

106116
assert validate :hackney
107117
end
@@ -110,11 +120,13 @@ defmodule HTTPoisonBaseTest do
110120
expect(:hackney, :request, [{[:post, "http://localhost", [], "body", [proxy_auth: {"username", "password"}, proxy: "proxy"]],
111121
{:ok, 200, "headers", :client}}])
112122
expect(:hackney, :body, 1, {:ok, "response"})
123+
expect(:hackney, :location, 1, "location")
113124

114125
assert HTTPoison.post!("localhost", "body", [], [proxy: "proxy", proxy_auth: {"username", "password"}]) ==
115126
%HTTPoison.Response{ status_code: 200,
116127
headers: "headers",
117-
body: "response" }
128+
body: "response",
129+
location: "location" }
118130

119131
assert validate :hackney
120132
end
@@ -123,11 +135,13 @@ defmodule HTTPoisonBaseTest do
123135
expect(:hackney, :request, [{[:post, "http://localhost", [], "body", [ssl_options: [certfile: "certs/client.crt"]]],
124136
{:ok, 200, "headers", :client}}])
125137
expect(:hackney, :body, 1, {:ok, "response"})
138+
expect(:hackney, :location, 1, "location")
126139

127140
assert HTTPoison.post!("localhost", "body", [], ssl: [certfile: "certs/client.crt"]) ==
128141
%HTTPoison.Response{ status_code: 200,
129142
headers: "headers",
130-
body: "response" }
143+
body: "response",
144+
location: "location" }
131145

132146
assert validate :hackney
133147
end
@@ -136,11 +150,13 @@ defmodule HTTPoisonBaseTest do
136150
expect(:hackney, :request, [{[:post, "http://localhost", [], "body", [follow_redirect: true]],
137151
{:ok, 200, "headers", :client}}])
138152
expect(:hackney, :body, 1, {:ok, "response"})
153+
expect(:hackney, :location, 1, "location")
139154

140155
assert HTTPoison.post!("localhost", "body", [], follow_redirect: true) ==
141156
%HTTPoison.Response{ status_code: 200,
142157
headers: "headers",
143-
body: "response" }
158+
body: "response",
159+
location: "location" }
144160

145161
assert validate :hackney
146162
end
@@ -149,11 +165,13 @@ defmodule HTTPoisonBaseTest do
149165
expect(:hackney, :request, [{[:post, "http://localhost", [], "body", [max_redirect: 2]],
150166
{:ok, 200, "headers", :client}}])
151167
expect(:hackney, :body, 1, {:ok, "response"})
168+
expect(:hackney, :location, 1, "location")
152169

153170
assert HTTPoison.post!("localhost", "body", [], max_redirect: 2) ==
154171
%HTTPoison.Response{ status_code: 200,
155172
headers: "headers",
156-
body: "response" }
173+
body: "response",
174+
location: "location" }
157175

158176
assert validate :hackney
159177
end

test/httpoison_test.exs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ defmodule HTTPoisonTest do
1010
test "get" do
1111
assert_response HTTPoison.get("localhost:8080/deny"), fn(response) ->
1212
assert :erlang.size(response.body) == 197
13+
assert response.location == "http://localhost:8080/deny"
1314
end
1415
end
1516

@@ -65,11 +66,15 @@ defmodule HTTPoisonTest do
6566
end
6667

6768
test "option follow redirect absolute url" do
68-
assert_response HTTPoison.get("http://localhost:8080/redirect-to?url=http%3A%2F%2Flocalhost:8080%2Fget", [], [follow_redirect: true])
69+
assert_response HTTPoison.get("http://localhost:8080/redirect-to?url=http%3A%2F%2Flocalhost:8080%2Fget", [], [follow_redirect: true]), fn(response) ->
70+
assert response.location == "http://localhost:8080/get"
71+
end
6972
end
7073

7174
test "option follow redirect relative url" do
72-
assert_response HTTPoison.get("http://localhost:8080/relative-redirect/1", [], [follow_redirect: true])
75+
assert_response HTTPoison.get("http://localhost:8080/relative-redirect/1", [], [follow_redirect: true]), fn(response) ->
76+
assert response.location == "/get"
77+
end
7378
end
7479

7580
test "basic_auth hackney option" do
@@ -102,7 +107,7 @@ defmodule HTTPoisonTest do
102107
test "cached request" do
103108
if_modified = %{"If-Modified-Since" => "Tue, 11 Dec 2012 10:10:24 GMT"}
104109
response = HTTPoison.get!("localhost:8080/cache", if_modified)
105-
assert %HTTPoison.Response{status_code: 304, body: ""} = response
110+
assert %HTTPoison.Response{status_code: 304, body: "", location: "http://localhost:8080/cache"} = response
106111
end
107112

108113
test "send cookies" do
@@ -140,7 +145,8 @@ defmodule HTTPoisonTest do
140145
assert response.status_code == 200
141146
assert is_binary(response.body)
142147

143-
unless function == nil, do: function.(response)
148+
unless response.location == nil, do: assert is_binary(response.location)
149+
unless function == nil, do: function.(response)
144150
end
145151

146152
defp get_header(headers, key) do

0 commit comments

Comments
 (0)