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.
Methods
Public Class
Public Instance
Included modules
Classes and Modules
Constants
USER_AGENT | = | "httpx.rb/#{VERSION}" |
default value used for “user-agent” header, when not overridden. |
Attributes
body | [R] |
an |
drain_error | [R] |
Exception raised during enumerable body writes. |
headers | [R] |
an |
options | [R] |
an |
peer_address | [RW] |
The IP address from the peer server. |
persistent | [W] | |
response | [R] |
the corresponding |
state | [R] |
a symbol describing which frame is currently being flushed. |
uri | [R] |
the absolute URI object for this request. |
verb | [R] |
the upcased string HTTP verb for this request. |
Public Class methods
initializes the instance with the given verb
, an absolute or relative uri
, and the request options.
# File lib/httpx/request.rb 51 def initialize(verb, uri, options = {}) 52 @verb = verb.to_s.upcase 53 @options = Options.new(options) 54 @uri = Utils.to_uri(uri) 55 if @uri.relative? 56 origin = @options.origin 57 raise(Error, "invalid URI: #{@uri}") unless origin 58 59 base_path = @options.base_path 60 61 @uri = origin.merge("#{base_path}#{@uri}") 62 end 63 64 @headers = @options.headers.dup 65 @headers["user-agent"] ||= USER_AGENT 66 @headers["accept"] ||= "*/*" 67 68 @body = @options.request_body_class.new(@headers, @options) 69 @state = :idle 70 @response = nil 71 @peer_address = nil 72 @persistent = @options.persistent 73 end
Public Instance methods
returs the URI authority of the request.
session.build_request("GET", "https://google.com/query").authority #=> "google.com" session.build_request("GET", "http://internal:3182/a").authority #=> "internal:3182"
# File lib/httpx/request.rb 153 def authority 154 @uri.authority 155 end
consumes and returns the next available chunk of request body that can be sent
# File lib/httpx/request.rb 183 def drain_body 184 return nil if @body.nil? 185 186 @drainer ||= @body.each 187 chunk = @drainer.next.dup 188 189 emit(:body_chunk, chunk) 190 chunk 191 rescue StopIteration 192 nil 193 rescue StandardError => e 194 @drain_error = e 195 nil 196 end
whether the request supports the 100-continue handshake and already processed the 100 response.
# File lib/httpx/request.rb 244 def expects? 245 @headers["expect"] == "100-continue" && @informational_status == 100 && !@response 246 end
:nocov:
# File lib/httpx/request.rb 199 def inspect 200 "#<HTTPX::Request:#{object_id} " \ 201 "#{@verb} " \ 202 "#{uri} " \ 203 "@headers=#{@headers} " \ 204 "@body=#{@body}>" 205 end
returns :r
or :w
, depending on whether the request is waiting for a response or flushing.
# File lib/httpx/request.rb 103 def interests 104 return :r if @state == :done || @state == :expect 105 106 :w 107 end
# File lib/httpx/request.rb 109 def merge_headers(h) 110 @headers = @headers.merge(h) 111 end
returs the URI origin of the request.
session.build_request("GET", "https://google.com/query").authority #=> "https://google.com" session.build_request("GET", "http://internal:3182/a").authority #=> "http://internal:3182"
# File lib/httpx/request.rb 161 def origin 162 @uri.origin 163 end
returnns the URI path of the request uri
.
# File lib/httpx/request.rb 141 def path 142 path = uri.path.dup 143 path = +"" if path.nil? 144 path << "/" if path.empty? 145 path << "?#{query}" unless query.empty? 146 path 147 end
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"
# File lib/httpx/request.rb 171 def query 172 return @query if defined?(@query) 173 174 query = [] 175 if (q = @options.params) 176 query << Transcoder::Form.encode(q) 177 end 178 query << @uri.query if @uri.query 179 @query = query.join("&") 180 end
the read timeout defied for this requet.
# File lib/httpx/request.rb 76 def read_timeout 77 @options.timeout[:read_timeout] 78 end
the request timeout defied for this requet.
# File lib/httpx/request.rb 86 def request_timeout 87 @options.timeout[:request_timeout] 88 end
sets the response
on this request.
# File lib/httpx/request.rb 119 def response=(response) 120 return unless response 121 122 if response.is_a?(Response) && response.status < 200 123 # deal with informational responses 124 125 if response.status == 100 && @headers.key?("expect") 126 @informational_status = response.status 127 return 128 end 129 130 # 103 Early Hints advertises resources in document to browsers. 131 # not very relevant for an HTTP client, discard. 132 return if response.status >= 103 133 end 134 135 @response = response 136 137 emit(:response_started, response) 138 end
the URI scheme of the request uri
.
# File lib/httpx/request.rb 114 def scheme 115 @uri.scheme 116 end
# File lib/httpx/request.rb 98 def trailers 99 @trailers ||= @options.headers_class.new 100 end
# File lib/httpx/request.rb 94 def trailers? 95 defined?(@trailers) 96 end
moves on to the nextstate
of the request state machine (when all preconditions are met)
# File lib/httpx/request.rb 209 def transition(nextstate) 210 case nextstate 211 when :idle 212 @body.rewind 213 @response = nil 214 @drainer = nil 215 when :headers 216 return unless @state == :idle 217 when :body 218 return unless @state == :headers || 219 @state == :expect 220 221 if @headers.key?("expect") 222 if @informational_status && @informational_status == 100 223 # check for 100 Continue response, and deallocate the var 224 # if @informational_status == 100 225 # @response = nil 226 # end 227 else 228 return if @state == :expect # do not re-set it 229 230 nextstate = :expect 231 end 232 end 233 when :trailers 234 return unless @state == :body 235 when :done 236 return if @state == :expect 237 end 238 @state = nextstate 239 emit(@state, self) 240 nil 241 end
the write timeout defied for this requet.
# File lib/httpx/request.rb 81 def write_timeout 82 @options.timeout[:write_timeout] 83 end