Skip to content

Commit

Permalink
Allow passing pre-allocated buffer for response body
Browse files Browse the repository at this point in the history
This is one piece in some efforts we're going to make to drastically
reduce the # of allocations required for making HTTP requests.

This PR allows the user to pass a pre-allocated `Vector{UInt8}`
via the `response_stream` keyword arg (previously not allowed),
which will then be used directly for writing the response body.
  • Loading branch information
quinnj committed Jan 6, 2023
1 parent 1d843b9 commit 45c684b
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 3 deletions.
3 changes: 1 addition & 2 deletions src/Streams.jl
Original file line number Diff line number Diff line change
Expand Up @@ -288,8 +288,7 @@ function Base.readbytes!(http::Stream, buf::IOBuffer, n=bytesavailable(http))
buf.size += n
end

function Base.read(http::Stream)
buf = PipeBuffer()
function Base.read(http::Stream, buf::IOBuffer=PipeBuffer())
if ntoread(http) == unknown_length
while !eof(http)
readbytes!(http, buf)
Expand Down
22 changes: 21 additions & 1 deletion src/clientlayers/StreamRequest.jl
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,27 @@ end
function readbody!(stream::Stream, res::Response, buf_or_stream)
if !iserror(res)
if isbytes(res.body)
res.body = read(buf_or_stream)
if length(res.body) > 0
# user-provided buffer to read response body into
# specify write=true to make the buffer writable
# but also specify maxsize, which means it won't be grown
# (we don't want to be changing the user's buffer for them)
body = IOBuffer(res.body; write=true, maxsize=length(res.body))
if buf_or_stream isa BufferStream
# if it's a BufferStream, the response body was gzip encoded
# so using the default write is fastest because it utilizes
# readavailable under the hood, for which BufferStream is optimized
write(body, buf_or_stream)
elseif buf_or_stream isa Stream
# for HTTP.Stream, there's already an optimized read method
# that just needs an IOBuffer to write into
res.body = read(buf_or_stream, body)
else
error("unreachable")
end
else
res.body = read(buf_or_stream)
end
else
write(res.body, buf_or_stream)
end
Expand Down

0 comments on commit 45c684b

Please sign in to comment.