From 8a48266265fec4fdd53f503ee7a94f111227a68e Mon Sep 17 00:00:00 2001 From: quinnj Date: Tue, 29 Aug 2017 21:02:39 -0600 Subject: [PATCH] Ensure we don't try to show an open FIFOBuffer for requests/responses. Fixes #85 --- src/fifobuffer.jl | 10 ++++++++-- src/multipart.jl | 1 + src/parser.jl | 2 +- src/types.jl | 36 ++++++++++++++++++++---------------- 4 files changed, 30 insertions(+), 19 deletions(-) diff --git a/src/fifobuffer.jl b/src/fifobuffer.jl index 694a92c31..013e40a91 100644 --- a/src/fifobuffer.jl +++ b/src/fifobuffer.jl @@ -97,6 +97,7 @@ function Base.seek(f::FIFOBuffer, pos::Tuple{Int64, Int64, Int64}) end Base.eof(f::FIFOBuffer) = f.eof && f.nb == 0 +Base.isopen(f::FIFOBuffer) = !f.eof function Base.close(f::FIFOBuffer) f.eof = true notify(f.cond) @@ -170,7 +171,7 @@ end function Base.read(f::FIFOBuffer, ::Type{Tuple{UInt8,Bool}}) # no data to read if f.nb == 0 - if current_task() == f.task + if current_task() == f.task || f.eof return 0x00, false else # async: block till there's data to read f.eof && return 0x00, false @@ -210,7 +211,12 @@ function Base.write(f::FIFOBuffer, b::UInt8) push!(f.buffer, 0x00) f.len += 1 else - return 0 + if current_task() == f.task || f.eof + return 0 + else # async: block until there's room to write + wait(f.cond) + f.nb == f.len && return 0 + end end end # write our byte diff --git a/src/multipart.jl b/src/multipart.jl index c260afd72..1a88f2894 100644 --- a/src/multipart.jl +++ b/src/multipart.jl @@ -16,6 +16,7 @@ end Form(f::Form) = f Base.eof(f::Form) = f.index > length(f.data) +Base.isopen(f::Form) = false Base.length(f::Form) = sum(x->isa(x, IOStream) ? filesize(x) - position(x) : nb_available(x), f.data) function Base.position(f::Form) index = f.index diff --git a/src/parser.jl b/src/parser.jl index 8cc0c8374..0abe3c03f 100644 --- a/src/parser.jl +++ b/src/parser.jl @@ -1300,7 +1300,7 @@ function parse!(r::Union{Request, Response}, parser, bytes, len=length(bytes); @debug(PARSING_DEBUG, @__LINE__, "exiting maybe unfinished...") @debug(PARSING_DEBUG, @__LINE__, ParsingStateCode(p_state)) b = p_state == start_state || p_state == s_dead - he = b | (p_state >= s_headers_done) + he = b | (p_state >= s_chunk_size_start) m = b | (p_state >= s_body_identity_eof) return errno, he, m, String(bytes[p:end]) diff --git a/src/types.jl b/src/types.jl index 660c85150..245af7e05 100644 --- a/src/types.jl +++ b/src/types.jl @@ -344,26 +344,30 @@ function Base.show(io::IO, r::Union{Request,Response}; opts=RequestOptions()) startline(io, r) headers(io, r) buf = IOBuffer() - body(buf, r, opts) - b = take!(buf) - if length(b) > 2 - contenttype = sniff(b) - if contenttype in DISPLAYABLE_TYPES - if length(b) > 750 - println(io, "\n[$(typeof(r)) body of $(length(b)) bytes]") - println(io, String(b)[1:750]) - println(io, "⋮") + if isopen(r.body) + print(io, "\n[open HTTP.FIFOBuffer with $(length(r.body)) bytes to read") + else + body(buf, r, opts) + b = take!(buf) + if length(b) > 2 + contenttype = sniff(b) + if contenttype in DISPLAYABLE_TYPES + if length(b) > 750 + println(io, "\n[$(typeof(r)) body of $(length(b)) bytes]") + println(io, String(b)[1:750]) + println(io, "⋮") + else + print(io, String(b)) + end else - print(io, String(b)) + contenttype = Base.get(r.headers, "Content-Type", contenttype) + encoding = Base.get(r.headers, "Content-Encoding", "") + encodingtxt = encoding == "" ? "" : " with '$encoding' encoding" + println(io, "\n[$(length(b)) bytes of '$contenttype' data$encodingtxt]") end else - contenttype = Base.get(r.headers, "Content-Type", contenttype) - encoding = Base.get(r.headers, "Content-Encoding", "") - encodingtxt = encoding == "" ? "" : " with '$encoding' encoding" - println(io, "\n[$(length(b)) bytes of '$contenttype' data$encodingtxt]") + print(io, String(b)) end - else - print(io, String(b)) end print(io, "\"\"\"") end