Class: HTTP::Request
- Inherits:
-
Object
- Object
- HTTP::Request
- Extended by:
- Forwardable
- Includes:
- Base64, 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}".freeze
- 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
Methods included from Base64
Constructor Details
#initialize(opts) ⇒ Request
Returns a new instance of Request.
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/http/request.rb', line 90 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.
81 82 83 |
# File 'lib/http/request.rb', line 81 def body @body end |
#proxy ⇒ Object (readonly)
Returns the value of attribute proxy.
81 82 83 |
# File 'lib/http/request.rb', line 81 def proxy @proxy end |
#scheme ⇒ Object (readonly)
Scheme is normalized to be a lowercase symbol e.g. :http, :https
74 75 76 |
# File 'lib/http/request.rb', line 74 def scheme @scheme end |
#uri ⇒ Object (readonly)
"Request URI" as per RFC 2616 http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html
80 81 82 |
# File 'lib/http/request.rb', line 80 def uri @uri end |
#uri_normalizer ⇒ Object (readonly)
Returns the value of attribute uri_normalizer.
76 77 78 |
# File 'lib/http/request.rb', line 76 def uri_normalizer @uri_normalizer end |
#verb ⇒ Object (readonly)
Method is given as a lowercase symbol e.g. :get, :post
71 72 73 |
# File 'lib/http/request.rb', line 71 def verb @verb end |
#version ⇒ Object (readonly)
Returns the value of attribute version.
81 82 83 |
# File 'lib/http/request.rb', line 81 def version @version end |
Instance Method Details
#connect_using_proxy(socket) ⇒ Object
Setup tunnel through proxy for SSL request
168 169 170 |
# File 'lib/http/request.rb', line 168 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
173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/http/request.rb', line 173 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
158 159 160 |
# File 'lib/http/request.rb', line 158 def headers[Headers::PROXY_AUTHORIZATION] = end |
#include_proxy_headers ⇒ Object
152 153 154 155 |
# File 'lib/http/request.rb', line 152 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.
221 222 223 |
# File 'lib/http/request.rb', line 221 def inspect "#<#{self.class}/#{@version} #{verb.to_s.upcase} #{uri}>" end |
#proxy_authorization_header ⇒ Object
162 163 164 165 |
# File 'lib/http/request.rb', line 162 def digest = encode64("#{proxy[:proxy_username]}:#{proxy[:proxy_password]}") "Basic #{digest}" end |
#proxy_connect_header ⇒ Object
Compute HTTP request header SSL proxy connection
187 188 189 |
# File 'lib/http/request.rb', line 187 def proxy_connect_header "CONNECT #{host}:#{port} HTTP/#{version}" end |
#proxy_connect_headers ⇒ Object
Headers to send with proxy connect request
192 193 194 195 196 197 198 199 200 201 |
# File 'lib/http/request.rb', line 192 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
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 134 |
# File 'lib/http/request.rb', line 107 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
204 205 206 |
# File 'lib/http/request.rb', line 204 def socket_host using_proxy? ? proxy[:proxy_address] : host end |
#socket_port ⇒ Object
Port for tcp socket
209 210 211 |
# File 'lib/http/request.rb', line 209 def socket_port using_proxy? ? proxy[:proxy_port] : port end |
#stream(socket) ⇒ Object
Stream the request to a socket
137 138 139 140 |
# File 'lib/http/request.rb', line 137 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?
148 149 150 |
# File 'lib/http/request.rb', line 148 def using_authenticated_proxy? proxy && proxy.keys.size >= 4 end |
#using_proxy? ⇒ Boolean
Is this request using a proxy?
143 144 145 |
# File 'lib/http/request.rb', line 143 def using_proxy? proxy && proxy.keys.size >= 2 end |