Skip to content

Commit 43b82b0

Browse files
vtjnashnickrobinson251
authored andcommitted
Update readbytes! to avoid using internal API of IOBuffer less (#1148)
* Update readbytes! to avoid using internal API of IOBuffer less Note that this claims to be supported for all GenericIOBuffer, but Base only defines this function on a normal IOBuffer for which `pointer(data)` is contiguous space * Update Streams.jl * Update Streams.jl * Update Streams.jl * fix some tests relying on implementation details
1 parent 52d2a06 commit 43b82b0

File tree

2 files changed

+15
-17
lines changed

2 files changed

+15
-17
lines changed

src/Streams.jl

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -279,21 +279,15 @@ function Base.unsafe_read(http::Stream, p::Ptr{UInt8}, n::UInt)
279279
nothing
280280
end
281281

282-
@noinline function bufcheck(buf::Base.GenericIOBuffer, n)
283-
requested_buffer_capacity = (buf.append ? buf.size : (buf.ptr - 1)) + n
284-
requested_buffer_capacity > length(buf.data) && throw(ArgumentError("Unable to grow response stream IOBuffer $(length(buf.data)) large enough for response body size: $requested_buffer_capacity"))
285-
end
286-
287282
function Base.readbytes!(http::Stream, buf::Base.GenericIOBuffer, n=bytesavailable(http))
288-
Base.ensureroom(buf, n)
289-
# check if there's enough room in buf to write n bytes
290-
bufcheck(buf, n)
291-
data = buf.data
292-
GC.@preserve data unsafe_read(http, pointer(data, (buf.append ? buf.size + 1 : buf.ptr)), n)
283+
p, nbmax = Base.alloc_request(buf, UInt(n))
284+
nbmax < n && throw(ArgumentError("Unable to grow response stream IOBuffer $nbmax large enough for response body size: $n"))
285+
GC.@preserve buf unsafe_read(http, p, UInt(n))
286+
# TODO: use `Base.notify_filled(buf, Int(n))` here, but only once it is identical to this:
293287
if buf.append
294-
buf.size += n
288+
buf.size += Int(n)
295289
else
296-
buf.ptr += n
290+
buf.ptr += Int(n)
297291
buf.size = max(buf.size, buf.ptr - 1)
298292
end
299293
return n
@@ -327,6 +321,7 @@ function IOExtras.readuntil(http::Stream, f::Function)
327321
update_ntoread(http, length(bytes))
328322
return bytes
329323
catch ex
324+
ex isa EOFError || rethrow()
330325
# if we error, it means we didn't find what we were looking for
331326
# TODO: this seems very sketchy
332327
return UInt8[]

test/client.jl

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ end
140140
# wrapping pre-allocated buffer in IOBuffer will write to buffer directly
141141
io = IOBuffer(body; write=true)
142142
r = HTTP.get("https://$httpbin/bytes/100"; response_stream=io, socket_type_tls=tls)
143-
@test body === r.body.data
143+
@test Base.mightalias(body, r.body.data)
144144

145145
# if provided buffer is too small, we won't grow it for user
146146
body = zeros(UInt8, 10)
@@ -156,27 +156,30 @@ end
156156
# but if you wrap it in a writable IOBuffer, we will grow it
157157
io = IOBuffer(body; write=true)
158158
r = HTTP.get("https://$httpbin/bytes/100"; response_stream=io, socket_type_tls=tls)
159-
# same Array, though it was resized larger
160-
@test body === r.body.data
159+
# might be a new Array, resized larger
160+
body = take!(io)
161161
@test length(body) == 100
162162

163163
# and you can reuse it
164164
seekstart(io)
165165
r = HTTP.get("https://$httpbin/bytes/100"; response_stream=io, socket_type_tls=tls)
166-
# same Array, though it was resized larger
167-
@test body === r.body.data
166+
# `take!` should have given it a new Array
167+
@test !Base.mightalias(body, r.body.data)
168+
body = take!(io)
168169
@test length(body) == 100
169170

170171
# we respect ptr and size
171172
body = zeros(UInt8, 100)
172173
io = IOBuffer(body; write=true, append=true) # size=100, ptr=1
173174
r = HTTP.get("https://$httpbin/bytes/100"; response_stream=io, socket_type_tls=tls)
175+
body = take!(io)
174176
@test length(body) == 200
175177

176178
body = zeros(UInt8, 100)
177179
io = IOBuffer(body, write=true, append=false)
178180
write(io, body) # size=100, ptr=101
179181
r = HTTP.get("https://$httpbin/bytes/100"; response_stream=io, socket_type_tls=tls)
182+
body = take!(io)
180183
@test length(body) == 200
181184

182185
end

0 commit comments

Comments
 (0)