class HTTP::Request
Constants
- METHODS
- PORTS
Default ports of supported schemes
- SCHEMES
Allowed schemes
- USER_AGENT
Default User-Agent header value
Attributes
Scheme is normalized to be a lowercase symbol e.g. :http, :https
“Request URI” as per RFC 2616 www.w3.org/Protocols/rfc2616/rfc2616-sec5.html
Method is given as a lowercase symbol e.g. :get, :post
Public Class Methods
@option opts [String] :version @option opts [#to_s] :verb HTTP
request method @option opts [#call] :uri_normalizer (HTTP::URI::NORMALIZER) @option opts [HTTP::URI, to_s] :uri @option opts [Hash] :headers @option opts [Hash] :proxy @option opts [String, Enumerable, IO, nil] :body
# File lib/http/request.rb, line 86 def initialize(opts) @verb = opts.fetch(:verb).to_s.downcase.to_sym @uri_normalizer = opts[:uri_normalizer] || HTTP::URI::NORMALIZER @uri = @uri_normalizer.call(opts.fetch(:uri)) @scheme = @uri.scheme.to_s.downcase.to_sym if @uri.scheme raise(UnsupportedMethodError, "unknown method: #{verb}") unless METHODS.include?(@verb) raise(UnsupportedSchemeError, "unknown scheme: #{scheme}") unless SCHEMES.include?(@scheme) @proxy = opts[:proxy] || {} @version = opts[:version] || "1.1" @headers = prepare_headers(opts[:headers]) @body = prepare_body(opts[:body]) end
Public Instance Methods
Setup tunnel through proxy for SSL request
# File lib/http/request.rb, line 164 def connect_using_proxy(socket) Request::Writer.new(socket, nil, proxy_connect_headers, proxy_connect_header).connect_through_proxy end
Compute HTTP
request header for direct or proxy request
# File lib/http/request.rb, line 169 def headline request_uri = if using_proxy? && !uri.https? uri.omit(:fragment) else uri.request_uri end "#{verb.to_s.upcase} #{request_uri} HTTP/#{version}" end
# File lib/http/request.rb, line 148 def include_proxy_headers headers.merge!(proxy[:proxy_headers]) if proxy.key?(:proxy_headers) include_proxy_authorization_header if using_authenticated_proxy? end
Human-readable representation of base request info.
@example
req.inspect # => #<HTTP::Request/1.1 GET https://example.com>
@return [String]
# File lib/http/request.rb, line 215 def inspect "#<#{self.class}/#{@version} #{verb.to_s.upcase} #{uri}>" end
Compute HTTP
request header SSL proxy connection
# File lib/http/request.rb, line 181 def proxy_connect_header "CONNECT #{host}:#{port} HTTP/#{version}" end
Headers
to send with proxy connect request
# File lib/http/request.rb, line 186 def proxy_connect_headers connect_headers = HTTP::Headers.coerce( Headers::HOST => headers[Headers::HOST], Headers::USER_AGENT => headers[Headers::USER_AGENT] ) connect_headers[Headers::PROXY_AUTHORIZATION] = proxy_authorization_header if using_authenticated_proxy? connect_headers.merge!(proxy[:proxy_headers]) if proxy.key?(:proxy_headers) connect_headers end
Returns new Request
with updated uri
# File lib/http/request.rb, line 103 def redirect(uri, verb = @verb) headers = self.headers.dup headers.delete(Headers::HOST) new_body = body.source if verb == :get # request bodies should not always be resubmitted when following a redirect # some servers will close the connection after receiving the request headers # which may cause Errno::ECONNRESET: Connection reset by peer # see https://github.com/httprb/http/issues/649 # new_body = Request::Body.new(nil) new_body = nil # the CONTENT_TYPE header causes problems if set on a get request w/ an empty body # the server might assume that there should be content if it is set to multipart # rack raises EmptyContentError if this happens headers.delete(Headers::CONTENT_TYPE) end self.class.new( :verb => verb, :uri => @uri.join(uri), :headers => headers, :proxy => proxy, :body => new_body, :version => version, :uri_normalizer => uri_normalizer ) end
Host for tcp socket
# File lib/http/request.rb, line 198 def socket_host using_proxy? ? proxy[:proxy_address] : host end
Port for tcp socket
# File lib/http/request.rb, line 203 def socket_port using_proxy? ? proxy[:proxy_port] : port end
Stream the request to a socket
# File lib/http/request.rb, line 133 def stream(socket) include_proxy_headers if using_proxy? && !@uri.https? Request::Writer.new(socket, body, headers, headline).stream end
Is this request using an authenticated proxy?
# File lib/http/request.rb, line 144 def using_authenticated_proxy? proxy && proxy.keys.size >= 4 end
Is this request using a proxy?
# File lib/http/request.rb, line 139 def using_proxy? proxy && proxy.keys.size >= 2 end
Private Instance Methods
@return [String] Default host (with port if needed) header value.
# File lib/http/request.rb, line 232 def default_host_header_value PORTS[@scheme] == port ? host : "#{host}:#{port}" end
@!attribute [r] port
@return [Fixnum]
# File lib/http/request.rb, line 227 def port @uri.port || @uri.default_port end
# File lib/http/request.rb, line 236 def prepare_body(body) body.is_a?(Request::Body) ? body : Request::Body.new(body) end
# File lib/http/request.rb, line 240 def prepare_headers(headers) headers = HTTP::Headers.coerce(headers || {}) headers[Headers::HOST] ||= default_host_header_value headers[Headers::USER_AGENT] ||= USER_AGENT headers end