Class: HTTP::Request

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Base64, Proxy
Defined in:
lib/http/request.rb,
lib/http/request/body.rb,
lib/http/request/proxy.rb,
lib/http/request/writer.rb,
lib/http/request/builder.rb

Overview

Represents an HTTP request with verb, URI, headers, and body

Defined Under Namespace

Modules: Proxy Classes: Body, Builder, UnsupportedMethodError, UnsupportedSchemeError, Writer

Constant Summary collapse

USER_AGENT =

Default User-Agent header value

"http.rb/#{HTTP::VERSION}".freeze
METHODS =

Supported HTTP 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

Instance Method Summary collapse

Methods included from Proxy

#connect_using_proxy, #include_proxy_authorization_header, #include_proxy_headers, #proxy_authorization_header, #proxy_connect_header, #proxy_connect_headers

Methods included from Base64

encode64

Constructor Details

#initialize(verb:, uri:, headers: nil, proxy: {}, body: nil, version: "1.1", uri_normalizer: nil) ⇒ HTTP::Request

Create a new HTTP request

Examples:

Request.new(verb: :get, uri: "https://example.com")

Parameters:

  • verb (#to_s)

    HTTP request method

  • uri (HTTP::URI, #to_s)
  • headers (Hash) (defaults to: nil)
  • proxy (Hash) (defaults to: {})
  • body (String, Enumerable, IO, nil) (defaults to: nil)
  • version (String) (defaults to: "1.1")
  • uri_normalizer (#call) (defaults to: nil)


160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/http/request.rb', line 160

def initialize(verb:, uri:, headers: nil, proxy: {}, body: nil, version: "1.1",
               uri_normalizer: nil)
  @uri_normalizer = uri_normalizer || HTTP::URI::NORMALIZER
  @verb = verb.to_s.downcase.to_sym
  parse_uri!(uri)
  validate_method_and_scheme!

  @proxy   = proxy
  @version = version
  @headers = prepare_headers(headers)
  @body    = prepare_body(body)
end

Instance Attribute Details

#bodyHTTP::Request::Body (readonly)

Request body object

Examples:

request.body

Returns:



125
126
127
# File 'lib/http/request.rb', line 125

def body
  @body
end

#headersHTTP::Headers (readonly)

The HTTP headers collection

Examples:

request.headers

Returns:



134
135
136
# File 'lib/http/request.rb', line 134

def headers
  @headers
end

#proxyHash (readonly)

Proxy configuration hash

Examples:

request.proxy

Returns:

  • (Hash)


116
117
118
# File 'lib/http/request.rb', line 116

def proxy
  @proxy
end

#schemeSymbol (readonly)

URI scheme as a lowercase symbol

Examples:

request.scheme # => :https

Returns:

  • (Symbol)


89
90
91
# File 'lib/http/request.rb', line 89

def scheme
  @scheme
end

#uriHTTP::URI (readonly)

Request URI

Examples:

request.uri # => #<HTTP::URI ...>

Returns:



107
108
109
# File 'lib/http/request.rb', line 107

def uri
  @uri
end

#uri_normalizer#call (readonly)

URI normalizer callable

Examples:

request.uri_normalizer

Returns:

  • (#call)


98
99
100
# File 'lib/http/request.rb', line 98

def uri_normalizer
  @uri_normalizer
end

#verbSymbol (readonly)

HTTP method as a lowercase symbol

Examples:

request.verb # => :get

Returns:

  • (Symbol)


80
81
82
# File 'lib/http/request.rb', line 80

def verb
  @verb
end

#versionString (readonly)

HTTP version string

Examples:

request.version # => "1.1"

Returns:

  • (String)


143
144
145
# File 'lib/http/request.rb', line 143

def version
  @version
end

Instance Method Details

#headlineString

Compute HTTP request header for direct or proxy request

Examples:

request.headline

Returns:

  • (String)

Raises:



237
238
239
240
241
242
243
244
245
246
247
248
# File 'lib/http/request.rb', line 237

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

#inspectString

Human-readable representation of base request info

Examples:


req.inspect
# => #<HTTP::Request/1.1 GET https://example.com>

Returns:

  • (String)


281
282
283
# File 'lib/http/request.rb', line 281

def inspect
  format("#<%s/%s %s %s>", self.class, @version, String(verb).upcase, uri)
end

#redirect(uri, verb = @verb) ⇒ HTTP::Request

Returns new Request with updated uri

Examples:

request.redirect("https://example.com/new")

Returns:



180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/http/request.rb', line 180

def redirect(uri, verb = @verb)
  redirect_uri = @uri.join(uri)
  headers = redirect_headers(redirect_uri, verb)
  new_body = verb == :get ? nil : body.source

  self.class.new(
    verb:           verb,
    uri:            redirect_uri,
    headers:        headers,
    proxy:          proxy,
    body:           new_body,
    version:        version,
    uri_normalizer: uri_normalizer
  )
end

#socket_hostString

Host for tcp socket

Examples:

request.socket_host

Returns:

  • (String)


257
258
259
# File 'lib/http/request.rb', line 257

def socket_host
  using_proxy? ? proxy[:proxy_address] : host
end

#socket_portInteger

Port for tcp socket

Examples:

request.socket_port

Returns:

  • (Integer)


268
269
270
# File 'lib/http/request.rb', line 268

def socket_port
  using_proxy? ? proxy[:proxy_port] : port
end

#stream(socket) ⇒ void

This method returns an undefined value.

Stream the request to a socket

Examples:

request.stream(socket)


203
204
205
206
# File 'lib/http/request.rb', line 203

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?

Examples:

request.using_authenticated_proxy?

Returns:

  • (Boolean)


226
227
228
# File 'lib/http/request.rb', line 226

def using_authenticated_proxy?
  proxy && proxy.keys.size >= 4
end

#using_proxy?Boolean

Is this request using a proxy?

Examples:

request.using_proxy?

Returns:

  • (Boolean)


215
216
217
# File 'lib/http/request.rb', line 215

def using_proxy?
  proxy && proxy.keys.size >= 2
end