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_class.new(@options.headers) 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 155 def authority 156 @uri.authority 157 end
consumes and returns the next available chunk of request body that can be sent
# File lib/httpx/request.rb 185 def drain_body 186 return nil if @body.nil? 187 188 @drainer ||= @body.each 189 chunk = @drainer.next.dup 190 191 emit(:body_chunk, chunk) 192 chunk 193 rescue StopIteration 194 nil 195 rescue StandardError => e 196 @drain_error = e 197 nil 198 end
whether the request supports the 100-continue handshake and already processed the 100 response.
# File lib/httpx/request.rb 246 def expects? 247 @headers["expect"] == "100-continue" && @informational_status == 100 && !@response 248 end
:nocov:
# File lib/httpx/request.rb 201 def inspect 202 "#<HTTPX::Request:#{object_id} " \ 203 "#{@verb} " \ 204 "#{uri} " \ 205 "@headers=#{@headers} " \ 206 "@body=#{@body}>" 207 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 163 def origin 164 @uri.origin 165 end
returnns the URI path of the request uri
.
# File lib/httpx/request.rb 143 def path 144 path = uri.path.dup 145 path = +"" if path.nil? 146 path << "/" if path.empty? 147 path << "?#{query}" unless query.empty? 148 path 149 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 173 def query 174 return @query if defined?(@query) 175 176 query = [] 177 if (q = @options.params) 178 query << Transcoder::Form.encode(q) 179 end 180 query << @uri.query if @uri.query 181 @query = query.join("&") 182 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 if response.status >= 103 131 # 103 Early Hints advertises resources in document to browsers. 132 # not very relevant for an HTTP client, discard. 133 return 134 end 135 end 136 137 @response = response 138 139 emit(:response_started, response) 140 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 211 def transition(nextstate) 212 case nextstate 213 when :idle 214 @body.rewind 215 @response = nil 216 @drainer = nil 217 when :headers 218 return unless @state == :idle 219 when :body 220 return unless @state == :headers || 221 @state == :expect 222 223 if @headers.key?("expect") 224 if @informational_status && @informational_status == 100 225 # check for 100 Continue response, and deallocate the var 226 # if @informational_status == 100 227 # @response = nil 228 # end 229 else 230 return if @state == :expect # do not re-set it 231 232 nextstate = :expect 233 end 234 end 235 when :trailers 236 return unless @state == :body 237 when :done 238 return if @state == :expect 239 end 240 @state = nextstate 241 emit(@state, self) 242 nil 243 end
the write timeout defied for this requet.
# File lib/httpx/request.rb 81 def write_timeout 82 @options.timeout[:write_timeout] 83 end