Class: HTTP::Request
- Inherits:
-
Object
- Object
- HTTP::Request
- Extended by:
- Forwardable
- Includes:
- Headers::Mixin
- Defined in:
- lib/http/request.rb,
lib/http/request/body.rb,
lib/http/request/writer.rb
Defined Under Namespace
Classes: Body, UnsupportedMethodError, UnsupportedSchemeError, Writer
Constant Summary collapse
- USER_AGENT =
Default User-Agent header value
"http.rb/#{HTTP::VERSION}"
- METHODS =
[ # RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1 :options, :get, :head, :post, :put, :delete, :trace, :connect, # RFC 2518: HTTP Extensions for Distributed Authoring -- WEBDAV :propfind, :proppatch, :mkcol, :copy, :move, :lock, :unlock, # RFC 3648: WebDAV Ordered Collections Protocol :orderpatch, # RFC 3744: WebDAV Access Control Protocol :acl, # RFC 6352: vCard Extensions to WebDAV -- CardDAV :report, # RFC 5789: PATCH Method for HTTP :patch, # draft-reschke-webdav-search: WebDAV Search :search, # RFC 4791: Calendaring Extensions to WebDAV -- CalDAV :mkcalendar, # Implemented by several caching servers, like Squid, Varnish or Fastly :purge ].freeze
- SCHEMES =
Allowed schemes
%i[http https ws wss].freeze
- PORTS =
Default ports of supported schemes
{ :http => 80, :https => 443, :ws => 80, :wss => 443 }.freeze
Instance Attribute Summary collapse
-
#body ⇒ Object
readonly
Returns the value of attribute body.
-
#proxy ⇒ Object
readonly
Returns the value of attribute proxy.
-
#scheme ⇒ Object
readonly
Scheme is normalized to be a lowercase symbol e.g.
-
#uri ⇒ Object
readonly
"Request URI" as per RFC 2616 http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html.
-
#uri_normalizer ⇒ Object
readonly
Returns the value of attribute uri_normalizer.
-
#verb ⇒ Object
readonly
Method is given as a lowercase symbol e.g.
-
#version ⇒ Object
readonly
Returns the value of attribute version.
Attributes included from Headers::Mixin
Instance Method Summary collapse
-
#connect_using_proxy(socket) ⇒ Object
Setup tunnel through proxy for SSL request.
-
#headline ⇒ Object
Compute HTTP request header for direct or proxy request.
-
#include_proxy_authorization_header ⇒ Object
Compute and add the Proxy-Authorization header.
- #include_proxy_headers ⇒ Object
-
#initialize(opts) ⇒ Request
constructor
A new instance of Request.
-
#inspect ⇒ String
Human-readable representation of base request info.
- #proxy_authorization_header ⇒ Object
-
#proxy_connect_header ⇒ Object
Compute HTTP request header SSL proxy connection.
-
#proxy_connect_headers ⇒ Object
Headers to send with proxy connect request.
-
#redirect(uri, verb = @verb) ⇒ Object
Returns new Request with updated uri.
-
#socket_host ⇒ Object
Host for tcp socket.
-
#socket_port ⇒ Object
Port for tcp socket.
-
#stream(socket) ⇒ Object
Stream the request to a socket.
-
#using_authenticated_proxy? ⇒ Boolean
Is this request using an authenticated proxy?.
-
#using_proxy? ⇒ Boolean
Is this request using a proxy?.
Methods included from Headers::Mixin
Constructor Details
#initialize(opts) ⇒ Request
Returns a new instance of Request.
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/http/request.rb', line 89 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 |
Instance Attribute Details
#body ⇒ Object (readonly)
Returns the value of attribute body.
80 81 82 |
# File 'lib/http/request.rb', line 80 def body @body end |
#proxy ⇒ Object (readonly)
Returns the value of attribute proxy.
80 81 82 |
# File 'lib/http/request.rb', line 80 def proxy @proxy end |
#scheme ⇒ Object (readonly)
Scheme is normalized to be a lowercase symbol e.g. :http, :https
73 74 75 |
# File 'lib/http/request.rb', line 73 def scheme @scheme end |
#uri ⇒ Object (readonly)
"Request URI" as per RFC 2616 http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html
79 80 81 |
# File 'lib/http/request.rb', line 79 def uri @uri end |
#uri_normalizer ⇒ Object (readonly)
Returns the value of attribute uri_normalizer.
75 76 77 |
# File 'lib/http/request.rb', line 75 def uri_normalizer @uri_normalizer end |
#verb ⇒ Object (readonly)
Method is given as a lowercase symbol e.g. :get, :post
70 71 72 |
# File 'lib/http/request.rb', line 70 def verb @verb end |
#version ⇒ Object (readonly)
Returns the value of attribute version.
80 81 82 |
# File 'lib/http/request.rb', line 80 def version @version end |
Instance Method Details
#connect_using_proxy(socket) ⇒ Object
Setup tunnel through proxy for SSL request
167 168 169 |
# File 'lib/http/request.rb', line 167 def connect_using_proxy(socket) Request::Writer.new(socket, nil, proxy_connect_headers, proxy_connect_header).connect_through_proxy end |
#headline ⇒ Object
Compute HTTP request header for direct or proxy request
172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/http/request.rb', line 172 def headline request_uri = if using_proxy? && !uri.https? uri.omit(:fragment) else uri.request_uri end.to_s raise RequestError, "Invalid request URI: #{request_uri.inspect}" if request_uri.match?(/\s/) "#{verb.to_s.upcase} #{request_uri} HTTP/#{version}" end |
#include_proxy_authorization_header ⇒ Object
Compute and add the Proxy-Authorization header
157 158 159 |
# File 'lib/http/request.rb', line 157 def headers[Headers::PROXY_AUTHORIZATION] = end |
#include_proxy_headers ⇒ Object
151 152 153 154 |
# File 'lib/http/request.rb', line 151 def include_proxy_headers headers.merge!(proxy[:proxy_headers]) if proxy.key?(:proxy_headers) if using_authenticated_proxy? end |
#inspect ⇒ String
Human-readable representation of base request info.
220 221 222 |
# File 'lib/http/request.rb', line 220 def inspect "#<#{self.class}/#{@version} #{verb.to_s.upcase} #{uri}>" end |
#proxy_authorization_header ⇒ Object
161 162 163 164 |
# File 'lib/http/request.rb', line 161 def digest = Base64.strict_encode64("#{proxy[:proxy_username]}:#{proxy[:proxy_password]}") "Basic #{digest}" end |
#proxy_connect_header ⇒ Object
Compute HTTP request header SSL proxy connection
186 187 188 |
# File 'lib/http/request.rb', line 186 def proxy_connect_header "CONNECT #{host}:#{port} HTTP/#{version}" end |
#proxy_connect_headers ⇒ Object
Headers to send with proxy connect request
191 192 193 194 195 196 197 198 199 200 |
# File 'lib/http/request.rb', line 191 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] = if using_authenticated_proxy? connect_headers.merge!(proxy[:proxy_headers]) if proxy.key?(:proxy_headers) connect_headers end |
#redirect(uri, verb = @verb) ⇒ Object
Returns new Request with updated uri
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/http/request.rb', line 106 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 |
#socket_host ⇒ Object
Host for tcp socket
203 204 205 |
# File 'lib/http/request.rb', line 203 def socket_host using_proxy? ? proxy[:proxy_address] : host end |
#socket_port ⇒ Object
Port for tcp socket
208 209 210 |
# File 'lib/http/request.rb', line 208 def socket_port using_proxy? ? proxy[:proxy_port] : port end |
#stream(socket) ⇒ Object
Stream the request to a socket
136 137 138 139 |
# File 'lib/http/request.rb', line 136 def stream(socket) include_proxy_headers if using_proxy? && !@uri.https? Request::Writer.new(socket, body, headers, headline).stream end |
#using_authenticated_proxy? ⇒ Boolean
Is this request using an authenticated proxy?
147 148 149 |
# File 'lib/http/request.rb', line 147 def using_authenticated_proxy? proxy && proxy.keys.size >= 4 end |
#using_proxy? ⇒ Boolean
Is this request using a proxy?
142 143 144 |
# File 'lib/http/request.rb', line 142 def using_proxy? proxy && proxy.keys.size >= 2 end |