Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion src/clientlayers/StreamRequest.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module StreamRequest

using ..IOExtras, ..Messages, ..Streams, ..Connections, ..Strings, ..RedirectRequest, ..Exceptions
using ..Messages: isredirect, allow_redirects, redirectlimitreached, header
using CodecZlib, URIs
using SimpleBufferStream: BufferStream
using ConcurrentUtilities: @samethreadpool_spawn
Expand Down Expand Up @@ -143,9 +144,21 @@ function readbody(stream::Stream, res::Response, decompress::Union{Nothing, Bool
end
end

# Check if this redirect response will be followed
# Based on the logic in RedirectRequest.redirectlayer
function willredirect(res::Response)
req = res.request
return (
isredirect(res) &&
allow_redirects(req) &&
!redirectlimitreached(req) &&
header(res, "Location") != ""
)
end

function readbody!(stream::Stream, res::Response, buf_or_stream, lock)
n = 0
if !iserror(res)
if !iserror(res) && !willredirect(res)
if isbytes(res.body)
if length(res.body) > 0
# user-provided buffer to read response body into
Expand Down Expand Up @@ -179,6 +192,7 @@ function readbody!(stream::Stream, res::Response, buf_or_stream, lock)
# read the response body into the request context so that it can be
# read by the user if they want to or set later if
# we end up not retrying/redirecting/etc.
# This handles both error responses and redirect responses that will be followed
Base.@lock lock begin
res.request.context[:response_body] = read(buf_or_stream)
end
Expand Down
67 changes: 67 additions & 0 deletions test/client.jl
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,73 @@ end
@test isok(HTTP.request(read_method, "https://$httpbin/redirect-to?url=http%3A%2F%2Fgoogle.com", socket_type_tls=tls))
end

@testset "Client Redirect Response Stream" begin
# Test that redirect response bodies are not written to response_stream
# (Issue #1165: https://github.com/JuliaWeb/HTTP.jl/issues/1165)
server = nothing
try
server = HTTP.listen!("127.0.0.1", 8123) do http
if http.message.target == "/final"
HTTP.setstatus(http, 200)
HTTP.startwrite(http)
HTTP.write(http, "final_response")
else
HTTP.setstatus(http, 301)
HTTP.setheader(http, "Location" => "/final")
HTTP.startwrite(http)
HTTP.write(http, "redirect_response")
end
return
end

# Test with response_stream - should only contain final response
buffer = IOBuffer()
resp = HTTP.get("http://127.0.0.1:8123"; response_stream=buffer)
result = String(take!(buffer))
@test result == "final_response"
@test resp.status == 200

# Test multiple redirects - should only contain final response
server2 = HTTP.listen!("127.0.0.1", 8124) do http
if http.message.target == "/final"
HTTP.setstatus(http, 200)
HTTP.startwrite(http)
HTTP.write(http, "final")
elseif http.message.target == "/redirect2"
HTTP.setstatus(http, 302)
HTTP.setheader(http, "Location" => "/final")
HTTP.startwrite(http)
HTTP.write(http, "second_redirect")
else
HTTP.setstatus(http, 301)
HTTP.setheader(http, "Location" => "/redirect2")
HTTP.startwrite(http)
HTTP.write(http, "first_redirect")
end
return
end

try
buffer2 = IOBuffer()
HTTP.get("http://127.0.0.1:8124"; response_stream=buffer2)
result2 = String(take!(buffer2))
@test result2 == "final"
finally
close(server2)
end

# Test with redirect=false - should include redirect body
buffer3 = IOBuffer()
resp3 = HTTP.get("http://127.0.0.1:8123"; response_stream=buffer3, redirect=false)
result3 = String(take!(buffer3))
@test result3 == "redirect_response"
@test resp3.status == 301

finally
server !== nothing && close(server)
end
end

@testset "Client Basic Auth" begin
@test isok(HTTP.get("https://user:pwd@$httpbin/basic-auth/user/pwd", socket_type_tls=tls))
@test isok(HTTP.get("https://user:pwd@$httpbin/hidden-basic-auth/user/pwd", socket_type_tls=tls))
Expand Down
Loading