Class: HTTPX::Request
- Inherits:
-
Object
- Object
- HTTPX::Request
- Extended by:
- Forwardable
- Includes:
- Callbacks
- Defined in:
- lib/httpx/request.rb
Overview
Defines how an HTTP request is handled internally, both in terms of making attributes accessible, as well as maintaining the state machine which manages streaming the request onto the wire.
Direct Known Subclasses
Defined Under Namespace
Classes: Body
Constant Summary collapse
- USER_AGENT =
default value used for “user-agent” header, when not overridden.
"httpx.rb/#{VERSION}"
Instance Attribute Summary collapse
-
#body ⇒ Object
readonly
an HTTPX::Request::Body object containing the request body payload (or
nil
, whenn there is none). -
#drain_error ⇒ Object
readonly
Exception raised during enumerable body writes.
-
#headers ⇒ Object
readonly
an HTTPX::Headers object containing the request HTTP headers.
-
#options ⇒ Object
readonly
an HTTPX::Options object containing request options.
-
#peer_address ⇒ Object
The IP address from the peer server.
-
#persistent ⇒ Object
writeonly
Sets the attribute persistent.
-
#response ⇒ Object
the corresponding HTTPX::Response object, when there is one.
-
#state ⇒ Object
readonly
a symbol describing which frame is currently being flushed.
-
#uri ⇒ Object
readonly
the absolute URI object for this request.
-
#verb ⇒ Object
readonly
the upcased string HTTP verb for this request.
Instance Method Summary collapse
-
#authority ⇒ Object
returs the URI authority of the request.
-
#drain_body ⇒ Object
consumes and returns the next available chunk of request body that can be sent.
-
#expects? ⇒ Boolean
whether the request supports the 100-continue handshake and already processed the 100 response.
-
#initialize(verb, uri, options, params = EMPTY_HASH) ⇒ Request
constructor
initializes the instance with the given
verb
(an upppercase String, ex. ‘GEt’), an absolute or relativeuri
(either as String or URI::HTTP object), the requestoptions
(instance of HTTPX::Options) and an optional Hash ofparams
. -
#inspect ⇒ Object
:nocov:.
-
#interests ⇒ Object
returns
:r
or:w
, depending on whether the request is waiting for a response or flushing. - #merge_headers(h) ⇒ Object
-
#origin ⇒ Object
returs the URI origin of the request.
-
#path ⇒ Object
returnns the URI path of the request
uri
. - #persistent? ⇒ Boolean
-
#query ⇒ Object
returs the URI query string of the request (when available).
-
#read_timeout ⇒ Object
the read timeout defied for this requet.
-
#request_timeout ⇒ Object
the request timeout defied for this requet.
-
#scheme ⇒ Object
the URI scheme of the request
uri
. - #trailers ⇒ Object
- #trailers? ⇒ Boolean
-
#transition(nextstate) ⇒ Object
moves on to the
nextstate
of the request state machine (when all preconditions are met). -
#write_timeout ⇒ Object
the write timeout defied for this requet.
Methods included from Callbacks
#callbacks_for?, #emit, #on, #once, #only
Constructor Details
#initialize(verb, uri, options, params = EMPTY_HASH) ⇒ Request
initializes the instance with the given verb
(an upppercase String, ex. ‘GEt’), an absolute or relative uri
(either as String or URI::HTTP object), the request options
(instance of HTTPX::Options) and an optional Hash of params
.
Besides any of the options documented in HTTPX::Options (which would override or merge with what options
sets), it accepts also the following:
- :params
-
hash or array of key-values which will be encoded and set in the query string of request uris.
- :body
-
to be encoded in the request body payload. can be a String, an IO object (i.e. a File), or an Enumerable.
- :form
-
hash of array of key-values which will be form-urlencoded- or multipart-encoded in requests body payload.
- :json
-
hash of array of key-values which will be JSON-encoded in requests body payload.
- :xml
-
Nokogiri XML nodes which will be encoded in requests body payload.
:body, :form, :json and :xml are all mutually exclusive, i.e. only one of them gets picked up.
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/httpx/request.rb', line 63 def initialize(verb, uri, , params = EMPTY_HASH) @verb = verb.to_s.upcase @uri = Utils.to_uri(uri) @headers = .headers.dup merge_headers(params.delete(:headers)) if params.key?(:headers) @headers["user-agent"] ||= USER_AGENT @headers["accept"] ||= "*/*" # forego compression in the Range request case if @headers.key?("range") @headers.delete("accept-encoding") else @headers["accept-encoding"] ||= .supported_compression_formats end @query_params = params.delete(:params) if params.key?(:params) @body = .request_body_class.new(@headers, , **params) @options = @body. if @uri.relative? origin = @options.origin raise(Error, "invalid URI: #{@uri}") unless origin base_path = @options.base_path @uri = origin.merge("#{base_path}#{@uri}") end @state = :idle @response = nil @peer_address = nil @persistent = @options.persistent end |
Instance Attribute Details
#body ⇒ Object (readonly)
an HTTPX::Request::Body object containing the request body payload (or nil
, whenn there is none).
27 28 29 |
# File 'lib/httpx/request.rb', line 27 def body @body end |
#drain_error ⇒ Object (readonly)
Exception raised during enumerable body writes.
39 40 41 |
# File 'lib/httpx/request.rb', line 39 def drain_error @drain_error end |
#headers ⇒ Object (readonly)
an HTTPX::Headers object containing the request HTTP headers.
24 25 26 |
# File 'lib/httpx/request.rb', line 24 def headers @headers end |
#options ⇒ Object (readonly)
an HTTPX::Options object containing request options.
33 34 35 |
# File 'lib/httpx/request.rb', line 33 def @options end |
#peer_address ⇒ Object
The IP address from the peer server.
42 43 44 |
# File 'lib/httpx/request.rb', line 42 def peer_address @peer_address end |
#persistent=(value) ⇒ Object (writeonly)
Sets the attribute persistent
44 45 46 |
# File 'lib/httpx/request.rb', line 44 def persistent=(value) @persistent = value end |
#response ⇒ Object
the corresponding HTTPX::Response object, when there is one.
36 37 38 |
# File 'lib/httpx/request.rb', line 36 def response @response end |
#state ⇒ Object (readonly)
a symbol describing which frame is currently being flushed.
30 31 32 |
# File 'lib/httpx/request.rb', line 30 def state @state end |
#uri ⇒ Object (readonly)
the absolute URI object for this request.
21 22 23 |
# File 'lib/httpx/request.rb', line 21 def uri @uri end |
#verb ⇒ Object (readonly)
the upcased string HTTP verb for this request.
18 19 20 |
# File 'lib/httpx/request.rb', line 18 def verb @verb end |
Instance Method Details
#authority ⇒ Object
returs the URI authority of the request.
session.build_request("GET", "https://google.com/query"). #=> "google.com"
session.build_request("GET", "http://internal:3182/a"). #=> "internal:3182"
179 180 181 |
# File 'lib/httpx/request.rb', line 179 def @uri. end |
#drain_body ⇒ Object
consumes and returns the next available chunk of request body that can be sent
209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
# File 'lib/httpx/request.rb', line 209 def drain_body return nil if @body.nil? @drainer ||= @body.each chunk = @drainer.next.dup emit(:body_chunk, chunk) chunk rescue StopIteration nil rescue StandardError => e @drain_error = e nil end |
#expects? ⇒ Boolean
whether the request supports the 100-continue handshake and already processed the 100 response.
270 271 272 |
# File 'lib/httpx/request.rb', line 270 def expects? @headers["expect"] == "100-continue" && @informational_status == 100 && !@response end |
#inspect ⇒ Object
:nocov:
225 226 227 228 229 230 231 |
# File 'lib/httpx/request.rb', line 225 def inspect "#<HTTPX::Request:#{object_id} " \ "#{@verb} " \ "#{uri} " \ "@headers=#{@headers} " \ "@body=#{@body}>" end |
#interests ⇒ Object
returns :r
or :w
, depending on whether the request is waiting for a response or flushing.
129 130 131 132 133 |
# File 'lib/httpx/request.rb', line 129 def interests return :r if @state == :done || @state == :expect :w end |
#merge_headers(h) ⇒ Object
135 136 137 |
# File 'lib/httpx/request.rb', line 135 def merge_headers(h) @headers = @headers.merge(h) end |
#origin ⇒ Object
returs the URI origin of the request.
session.build_request("GET", "https://google.com/query"). #=> "https://google.com"
session.build_request("GET", "http://internal:3182/a"). #=> "http://internal:3182"
187 188 189 |
# File 'lib/httpx/request.rb', line 187 def origin @uri.origin end |
#path ⇒ Object
returnns the URI path of the request uri
.
167 168 169 170 171 172 173 |
# File 'lib/httpx/request.rb', line 167 def path path = uri.path.dup path = +"" if path.nil? path << "/" if path.empty? path << "?#{query}" unless query.empty? path end |
#persistent? ⇒ Boolean
116 117 118 |
# File 'lib/httpx/request.rb', line 116 def persistent? @persistent end |
#query ⇒ Object
returs the URI query string of the request (when available).
session.build_request("GET", "https://search.com").query #=> ""
session.build_request("GET", "https://search.com?q=a").query #=> "q=a"
session.build_request("GET", "https://search.com", params: { q: "a"}).query #=> "q=a"
session.build_request("GET", "https://search.com?q=a", params: { foo: "bar"}).query #=> "q=a&foo&bar"
197 198 199 200 201 202 203 204 205 206 |
# File 'lib/httpx/request.rb', line 197 def query return @query if defined?(@query) query = [] if (q = @query_params) query << Transcoder::Form.encode(q) end query << @uri.query if @uri.query @query = query.join("&") end |
#read_timeout ⇒ Object
the read timeout defied for this requet.
102 103 104 |
# File 'lib/httpx/request.rb', line 102 def read_timeout @options.timeout[:read_timeout] end |
#request_timeout ⇒ Object
the request timeout defied for this requet.
112 113 114 |
# File 'lib/httpx/request.rb', line 112 def request_timeout @options.timeout[:request_timeout] end |
#scheme ⇒ Object
the URI scheme of the request uri
.
140 141 142 |
# File 'lib/httpx/request.rb', line 140 def scheme @uri.scheme end |
#trailers ⇒ Object
124 125 126 |
# File 'lib/httpx/request.rb', line 124 def trailers @trailers ||= @options.headers_class.new end |
#trailers? ⇒ Boolean
120 121 122 |
# File 'lib/httpx/request.rb', line 120 def trailers? defined?(@trailers) end |
#transition(nextstate) ⇒ Object
moves on to the nextstate
of the request state machine (when all preconditions are met)
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 |
# File 'lib/httpx/request.rb', line 235 def transition(nextstate) case nextstate when :idle @body.rewind @response = nil @drainer = nil when :headers return unless @state == :idle when :body return unless @state == :headers || @state == :expect if @headers.key?("expect") if @informational_status && @informational_status == 100 # check for 100 Continue response, and deallocate the var # if @informational_status == 100 # @response = nil # end else return if @state == :expect # do not re-set it nextstate = :expect end end when :trailers return unless @state == :body when :done return if @state == :expect end @state = nextstate emit(@state, self) nil end |
#write_timeout ⇒ Object
the write timeout defied for this requet.
107 108 109 |
# File 'lib/httpx/request.rb', line 107 def write_timeout @options.timeout[:write_timeout] end |