class HTTPX::Request::Body

  1. lib/httpx/request/body.rb
Superclass: SimpleDelegator

Implementation of the HTTP Request body as a delegator which iterates (responds to each) payload chunks.

Attributes

options [RW]

Public Class methods

initialize_body(params)
[show source]
    # File lib/httpx/request/body.rb
128 def initialize_body(params)
129   if (body = params.delete(:body))
130     # @type var body: bodyIO
131     Transcoder::Body.encode(body)
132   elsif (form = params.delete(:form))
133     if Transcoder::Multipart.multipart?(form)
134       # @type var form: Transcoder::Multipart::multipart_input
135       Transcoder::Multipart.encode(form)
136     else
137       # @type var form: Transcoder::urlencoded_input
138       Transcoder::Form.encode(form)
139     end
140   elsif (json = params.delete(:json))
141     # @type var body: _ToJson
142     Transcoder::JSON.encode(json)
143   end
144 end
initialize_deflater_body(body, encoding)

returns the body wrapped with the correct deflater accordinng to the given encodisng.

[show source]
    # File lib/httpx/request/body.rb
147 def initialize_deflater_body(body, encoding)
148   case encoding
149   when "gzip"
150     Transcoder::GZIP.encode(body)
151   when "deflate"
152     Transcoder::Deflate.encode(body)
153   when "identity"
154     body
155   else
156     body
157   end
158 end
new(h, options, body: nil, **params)
[show source]
   # File lib/httpx/request/body.rb
 7 def new(h, options, body: nil, **params)
 8   case body
 9   when self
10     # request derives its options from body
11     body.options = options.merge(params)
12     body
13   when nil
14     super(h, options, **params)
15   else
16     super
17   end
18 end
new(h, options, **params)

inits the instance with the request headers, options and params, which contain the payload definition. it wraps the given body with the appropriate encoder on initialization.

..., json: { foo: "bar" }) #=> json encoder
..., form: { foo: "bar" }) #=> form urlencoded encoder
..., form: { foo: Pathname.open("path/to/file") }) #=> multipart urlencoded encoder
..., form: { foo: File.open("path/to/file") }) #=> multipart urlencoded encoder
..., form: { body: "bla") }) #=> raw data encoder
[show source]
   # File lib/httpx/request/body.rb
31 def initialize(h, options, **params)
32   @headers = h
33   @body = self.class.initialize_body(params)
34   @options = options.merge(params)
35 
36   if @body
37     if @options.compress_request_body && @headers.key?("content-encoding")
38 
39       @headers.get("content-encoding").each do |encoding|
40         @body = self.class.initialize_deflater_body(@body, encoding)
41       end
42     end
43 
44     @headers["content-type"] ||= @body.content_type
45     @headers["content-length"] = @body.bytesize unless unbounded_body?
46   end
47 
48   super(@body)
49 end

Public Instance methods

bytesize()

returns the +@body+ payload size in bytes.

[show source]
   # File lib/httpx/request/body.rb
90 def bytesize
91   return 0 if @body.nil?
92 
93   @body.bytesize
94 end
chunk!()

sets the chunked transfer encoding header.

[show source]
    # File lib/httpx/request/body.rb
116 def chunk!
117   @headers.add("transfer-encoding", "chunked")
118 end
chunked?()

returns whether the chunked transfer encoding header is set.

[show source]
    # File lib/httpx/request/body.rb
111 def chunked?
112   @headers["transfer-encoding"] == "chunked"
113 end
close()
[show source]
   # File lib/httpx/request/body.rb
70 def close
71   @body.close if @body.respond_to?(:close)
72 end
each(&block)

consumes and yields the request payload in chunks.

[show source]
   # File lib/httpx/request/body.rb
52 def each(&block)
53   return enum_for(__method__) unless block
54   return if @body.nil?
55 
56   body = stream(@body)
57   if body.respond_to?(:read)
58     while (chunk = body.read(16_384))
59       block.call(chunk)
60     end
61     # TODO: use copy_stream once bug is resolved: https://bugs.ruby-lang.org/issues/21131
62     # IO.copy_stream(body, ProcIO.new(block))
63   elsif body.respond_to?(:each)
64     body.each(&block)
65   else
66     block[body.to_s]
67   end
68 end
empty?()

return true if the body has been fully drained (or does nnot exist).

[show source]
   # File lib/httpx/request/body.rb
82 def empty?
83   return true if @body.nil?
84   return false if chunked?
85 
86   @body.bytesize.zero?
87 end
inspect()

simplecov:disable

[show source]
    # File lib/httpx/request/body.rb
121 def inspect
122   "#<#{self.class}:#{object_id} " \
123     "#{unbounded_body? ? "stream" : "@bytesize=#{bytesize}"}>"
124 end
rewind()

if the +@body+ is rewindable, it rewinnds it.

[show source]
   # File lib/httpx/request/body.rb
75 def rewind
76   return if empty?
77 
78   @body.rewind if @body.respond_to?(:rewind)
79 end
stream(body)

sets the body to yield using chunked trannsfer encoding format.

[show source]
    # File lib/httpx/request/body.rb
 97 def stream(body)
 98   return body unless chunked?
 99 
100   Transcoder::Chunker.encode(body.enum_for(:each))
101 end
unbounded_body?()

returns whether the body yields infinitely.

[show source]
    # File lib/httpx/request/body.rb
104 def unbounded_body?
105   return @unbounded_body if defined?(@unbounded_body)
106 
107   @unbounded_body = !@body.nil? && (chunked? || @body.bytesize == Float::INFINITY)
108 end