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
125 def initialize_body(params)
126   if (body = params.delete(:body))
127     # @type var body: bodyIO
128     Transcoder::Body.encode(body)
129   elsif (form = params.delete(:form))
130     # @type var form: Transcoder::urlencoded_input
131     Transcoder::Form.encode(form)
132   elsif (json = params.delete(:json))
133     # @type var body: _ToJson
134     Transcoder::JSON.encode(json)
135   end
136 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
139 def initialize_deflater_body(body, encoding)
140   case encoding
141   when "gzip"
142     Transcoder::GZIP.encode(body)
143   when "deflate"
144     Transcoder::Deflate.encode(body)
145   when "identity"
146     body
147   else
148     body
149   end
150 end
new(_, options, body: nil, **params)
[show source]
   # File lib/httpx/request/body.rb
 7 def new(_, options, body: nil, **params)
 8   if body.is_a?(self)
 9     # request derives its options from body
10     body.options = options.merge(params)
11     return body
12   end
13 
14   super
15 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
28 def initialize(h, options, **params)
29   @headers = h
30   @body = self.class.initialize_body(params)
31   @options = options.merge(params)
32 
33   if @body
34     if @options.compress_request_body && @headers.key?("content-encoding")
35 
36       @headers.get("content-encoding").each do |encoding|
37         @body = self.class.initialize_deflater_body(@body, encoding)
38       end
39     end
40 
41     @headers["content-type"] ||= @body.content_type
42     @headers["content-length"] = @body.bytesize unless unbounded_body?
43   end
44 
45   super(@body)
46 end

Public Instance methods

bytesize()

returns the +@body+ payload size in bytes.

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

sets the chunked transfer encoding header.

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

returns whether the chunked transfer encoding header is set.

[show source]
    # File lib/httpx/request/body.rb
108 def chunked?
109   @headers["transfer-encoding"] == "chunked"
110 end
close()
[show source]
   # File lib/httpx/request/body.rb
67 def close
68   @body.close if @body.respond_to?(:close)
69 end
each(&block)

consumes and yields the request payload in chunks.

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

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

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

:nocov:

[show source]
    # File lib/httpx/request/body.rb
118 def inspect
119   "#<HTTPX::Request::Body:#{object_id} " \
120     "#{unbounded_body? ? "stream" : "@bytesize=#{bytesize}"}>"
121 end
rewind()

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

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

sets the body to yield using chunked trannsfer encoding format.

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

returns whether the body yields infinitely.

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