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
129 def initialize_body(params)
130   if (body = params.delete(:body))
131     # @type var body: bodyIO
132     Transcoder::Body.encode(body)
133   elsif (form = params.delete(:form))
134     if Transcoder::Multipart.multipart?(form)
135       # @type var form: Transcoder::Multipart::multipart_input
136       Transcoder::Multipart.encode(form)
137     else
138       # @type var form: Transcoder::urlencoded_input
139       Transcoder::Form.encode(form)
140     end
141   elsif (json = params.delete(:json))
142     # @type var body: _ToJson
143     Transcoder::JSON.encode(json)
144   end
145 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
148 def initialize_deflater_body(body, encoding)
149   case encoding
150   when "gzip"
151     Transcoder::GZIP.encode(body)
152   when "deflate"
153     Transcoder::Deflate.encode(body)
154   when "identity"
155     body
156   else
157     body
158   end
159 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   @unbounded_body = nil
36 
37   if @body
38     if @options.compress_request_body && @headers.key?("content-encoding")
39 
40       @headers.get("content-encoding").each do |encoding|
41         @body = self.class.initialize_deflater_body(@body, encoding)
42       end
43     end
44 
45     @headers["content-type"] ||= @body.content_type
46     @headers["content-length"] = @body.bytesize unless unbounded_body?
47   end
48 
49   super(@body)
50 end

Public Instance methods

bytesize()

returns the +@body+ payload size in bytes.

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

sets the chunked transfer encoding header.

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

returns whether the chunked transfer encoding header is set.

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

consumes and yields the request payload in chunks.

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

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

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

simplecov:disable

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

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

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

sets the body to yield using chunked trannsfer encoding format.

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

returns whether the body yields infinitely.

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