Implementation of the HTTP Response
body as a buffer which implements the IO writer protocol (for buffering the response payload), the IO reader protocol (for consuming the response payload), and can be iterated over (via each
, which yields the payload in chunks).
Methods
Public Class
Public Instance
Public Instance Aliases
to_str | -> | to_s |
Attributes
Public Class methods
initialized with the corresponding HTTPX::Response
response
and HTTPX::Options
options
.
# File lib/httpx/response/body.rb 15 def initialize(response, options) 16 @response = response 17 @headers = response.headers 18 @options = options 19 @window_size = options.window_size 20 @encodings = [] 21 @length = 0 22 @buffer = nil 23 @reader = nil 24 @state = :idle 25 26 # initialize response encoding 27 @encoding = if (enc = response.content_type.charset) 28 begin 29 Encoding.find(enc) 30 rescue ArgumentError 31 Encoding::BINARY 32 end 33 else 34 Encoding::BINARY 35 end 36 37 initialize_inflaters 38 end
Public Instance methods
# File lib/httpx/response/body.rb 150 def ==(other) 151 object_id == other.object_id || begin 152 if other.respond_to?(:read) 153 _with_same_buffer_pos { FileUtils.compare_stream(@buffer, other) } 154 else 155 to_s == other.to_s 156 end 157 end 158 end
size of the decoded response payload. May differ from “content-length” header if response was encoded over-the-wire.
# File lib/httpx/response/body.rb 82 def bytesize 83 @length 84 end
closes/cleans the buffer, resets everything
# File lib/httpx/response/body.rb 141 def close 142 if @buffer 143 @buffer.close 144 @buffer = nil 145 end 146 @length = 0 147 transition(:closed) 148 end
# File lib/httpx/response/body.rb 46 def closed? 47 @state == :closed 48 end
copies the payload to dest
.
body.copy_to("path/to/file") body.copy_to(Pathname.new("path/to/file")) body.copy_to(File.new("path/to/file"))
# File lib/httpx/response/body.rb 128 def copy_to(dest) 129 return unless @buffer 130 131 rewind 132 133 if dest.respond_to?(:path) && @buffer.respond_to?(:path) 134 FileUtils.mv(@buffer.path, dest.path) 135 else 136 ::IO.copy_stream(@buffer, dest) 137 end 138 end
yields the payload in chunks.
# File lib/httpx/response/body.rb 87 def each 88 return enum_for(__method__) unless block_given? 89 90 begin 91 if @buffer 92 rewind 93 while (chunk = @buffer.read(@window_size)) 94 yield(chunk.force_encoding(@encoding)) 95 end 96 end 97 ensure 98 close 99 end 100 end
whether the payload is empty.
# File lib/httpx/response/body.rb 119 def empty? 120 @length.zero? 121 end
returns the declared filename in the “contennt-disposition” header, when present.
# File lib/httpx/response/body.rb 103 def filename 104 return unless @headers.key?("content-disposition") 105 106 Utils.get_filename(@headers["content-disposition"]) 107 end
# File lib/httpx/response/body.rb 40 def initialize_dup(other) 41 super 42 43 @buffer = other.instance_variable_get(:@buffer).dup 44 end
:nocov:
# File lib/httpx/response/body.rb 161 def inspect 162 "#<HTTPX::Response::Body:#{object_id} " \ 163 "@state=#{@state} " \ 164 "@length=#{@length}>" 165 end
reads a chunk from the payload (implementation of the IO reader protocol).
# File lib/httpx/response/body.rb 69 def read(*args) 70 return unless @buffer 71 72 unless @reader 73 rewind 74 @reader = @buffer 75 end 76 77 @reader.read(*args) 78 end
rewinds the response payload buffer.
# File lib/httpx/response/body.rb 169 def rewind 170 return unless @buffer 171 172 # in case there's some reading going on 173 @reader = nil 174 175 @buffer.rewind 176 end
returns the full response payload as a string.
# File lib/httpx/response/body.rb 110 def to_s 111 return "".b unless @buffer 112 113 @buffer.to_s 114 end
write the response payload chunk
into the buffer. Inflates the chunk when required and supported.
# File lib/httpx/response/body.rb 52 def write(chunk) 53 return if @state == :closed 54 55 return 0 if chunk.empty? 56 57 chunk = decode_chunk(chunk) 58 59 size = chunk.bytesize 60 @length += size 61 transition(:open) 62 @buffer.write(chunk) 63 64 @response.emit(:chunk_received, chunk) 65 size 66 end