Class: Protocol::HTTP::Request

Inherits:
Object
  • Object
show all
Includes:
Body::Reader
Defined in:
lib/protocol/http/request.rb

Overview

Represents an HTTP request which can be used both server and client-side.

~~~ ruby require ‘protocol/http’

# Long form: Protocol::HTTP::Request.new(“http”, “example.com”, “GET”, “/index.html”, “HTTP/1.1”, Protocol::HTTP::Headers[[“accept”, “text/html”]])

# Short form: Protocol::HTTP::Request[“GET”, “/index.html”, => “text/html”] ~~~

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Body::Reader

#body?, #buffered!, #close, #discard, #each, #finish, #read, #save

Constructor Details

#initialize(scheme = nil, authority = nil, method = nil, path = nil, version = nil, headers = Headers.new, body = nil, protocol = nil, interim_response = nil) ⇒ Request

Initialize the request.



39
40
41
42
43
44
45
46
47
48
49
# File 'lib/protocol/http/request.rb', line 39

def initialize(scheme = nil, authority = nil, method = nil, path = nil, version = nil, headers = Headers.new, body = nil, protocol = nil, interim_response = nil)
  @scheme = scheme
  @authority = authority
  @method = method
  @path = path
  @version = version
  @headers = headers
  @body = body
  @protocol = protocol
  @interim_response = interim_response
end

Instance Attribute Details

#a callback which is called when an interim response is received.(callbackwhichiscalled) ⇒ Object (readonly)



76
# File 'lib/protocol/http/request.rb', line 76

attr_accessor :interim_response

#authorityObject

Returns the value of attribute authority.



55
56
57
# File 'lib/protocol/http/request.rb', line 55

def authority
  @authority
end

#bodyObject

Returns the value of attribute body.



70
71
72
# File 'lib/protocol/http/request.rb', line 70

def body
  @body
end

#headersObject

Returns the value of attribute headers.



67
68
69
# File 'lib/protocol/http/request.rb', line 67

def headers
  @headers
end

#interim_responseObject

Returns the value of attribute interim_response.



76
77
78
# File 'lib/protocol/http/request.rb', line 76

def interim_response
  @interim_response
end

#methodObject

Returns the value of attribute method.



58
59
60
# File 'lib/protocol/http/request.rb', line 58

def method
  @method
end

#pathObject

Returns the value of attribute path.



61
62
63
# File 'lib/protocol/http/request.rb', line 61

def path
  @path
end

#protocolObject

Returns the value of attribute protocol.



73
74
75
# File 'lib/protocol/http/request.rb', line 73

def protocol
  @protocol
end

#schemeObject

Returns the value of attribute scheme.



52
53
54
# File 'lib/protocol/http/request.rb', line 52

def scheme
  @scheme
end

#the request authority, usually a hostname and port number, e.g. `"example.com:80"`.(requestauthority, usuallyahostname) ⇒ Object (readonly)



55
# File 'lib/protocol/http/request.rb', line 55

attr_accessor :authority

#the request headers, usually containing metadata associated with the request such as the `"user-agent"`, `"accept"` (content type), `"accept-language"`, etc.(requestheaders, usuallycontainingmetadataassociatedwiththerequestsuchasthe`"user-agent"`, `"accept"`(content type), `"accept-language"`, etc.) ⇒ Object (readonly)



67
# File 'lib/protocol/http/request.rb', line 67

attr_accessor :headers

#the request method, usually one of `"GET"`, `"HEAD"`, `"POST"`, `"PUT"`, `"DELETE"`, `"CONNECT"` or `"OPTIONS"`, etc.(requestmethod, usuallyoneof`"GET"`, `"HEAD"`, `"POST"`, `"PUT"`, `"DELETE"`, `"CONNECT"`) ⇒ Object (readonly)



58
# File 'lib/protocol/http/request.rb', line 58

attr_accessor :method

#the request path, usually a path and query string, e.g. `"/index.html"`, `"/search?q=hello"`, however it can be any [valid request target](https://www.rfc-editor.org/rfc/rfc9110#target.resource).(requestpath, usuallyapath) ⇒ Object (readonly)



61
# File 'lib/protocol/http/request.rb', line 61

attr_accessor :path

#the request protocol, usually empty, but occasionally `"websocket"` or `"webtransport"`. In HTTP/1, it is used to request a connection upgrade, and in HTTP/2 it is used to indicate a specfic protocol for the stream.(requestprotocol, usuallyempty, butoccasionally`"websocket"`) ⇒ Object (readonly)



73
# File 'lib/protocol/http/request.rb', line 73

attr_accessor :protocol

#the request scheme, usually `"http"` or `"https"`.(requestscheme, usually`"http"`) ⇒ Object (readonly)



52
# File 'lib/protocol/http/request.rb', line 52

attr_accessor :scheme

#the request version, usually `"http/1.0"`, `"http/1.1"`, `"h2"`, or `"h3"`.(requestversion, usually`"http/1.0"`, `"http/1.1"`, `"h2"`) ⇒ Object (readonly)



64
# File 'lib/protocol/http/request.rb', line 64

attr_accessor :version

#versionObject

Returns the value of attribute version.



64
65
66
# File 'lib/protocol/http/request.rb', line 64

def version
  @version
end

Class Method Details

.[](method, path, _headers = nil, _body = nil, scheme: nil, authority: nil, headers: _headers, body: _body, protocol: nil, interim_response: nil) ⇒ Object

A short-cut method which exposes the main request variables that you’d typically care about.



127
128
129
130
131
132
# File 'lib/protocol/http/request.rb', line 127

def self.[](method, path, _headers = nil, _body = nil, scheme: nil, authority: nil, headers: _headers, body: _body, protocol: nil, interim_response: nil)
  body = Body::Buffered.wrap(body)
  headers = Headers[headers]
  
  self.new(scheme, authority, method, path, nil, headers, body, protocol, interim_response)
end

Instance Method Details

#as_jsonObject

Convert the request to a hash, suitable for serialization.



142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/protocol/http/request.rb', line 142

def as_json(...)
  {
    scheme: @scheme,
    authority: @authority,
    method: @method,
    path: @path,
    version: @version,
    headers: @headers&.as_json,
    body: @body&.as_json,
    protocol: @protocol
  }
end

#call(connection) ⇒ Object

Send the request to the given connection.



86
87
88
# File 'lib/protocol/http/request.rb', line 86

def call(connection)
  connection.call(self)
end

#connect?Boolean

Whether this is a CONNECT request: typically used to establish a tunnel.



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

def connect?
  @method == Methods::CONNECT
end

#head?Boolean

Whether this is a HEAD request: no body is expected in the response.



112
113
114
# File 'lib/protocol/http/request.rb', line 112

def head?
  @method == Methods::HEAD
end

#idempotent?Boolean

Whether the request can be replayed without side-effects.



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

def idempotent?
  @method != Methods::POST && (@body.nil? || @body.empty?)
end

#on_interim_response(&block) ⇒ Object

Register a callback to be called when an interim response is received.



100
101
102
103
104
105
106
107
108
109
# File 'lib/protocol/http/request.rb', line 100

def on_interim_response(&block)
  if interim_response = @interim_response
    @interim_response = ->(status, headers) do
      block.call(status, headers)
      interim_response.call(status, headers)
    end
  else
    @interim_response = block
  end
end

#peerObject

A request that is generated by a server, may choose to include the peer (address) associated with the request. It should be implemented by a sub-class.



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

def peer
  nil
end

#send_interim_response(status, headers) ⇒ Object

Send an interim response back to the origin of this request, if possible.



91
92
93
# File 'lib/protocol/http/request.rb', line 91

def send_interim_response(status, headers)
  @interim_response&.call(status, headers)
end

#the request body. It should only be read once (it may not be idempotent).=(requestbody.Itshouldonlybereadonce(it may) ⇒ Object



70
# File 'lib/protocol/http/request.rb', line 70

attr_accessor :body

#to_jsonObject

Convert the request to JSON.



158
159
160
# File 'lib/protocol/http/request.rb', line 158

def to_json(...)
  as_json.to_json(...)
end

#to_sObject

Summarize the request as a string.



165
166
167
# File 'lib/protocol/http/request.rb', line 165

def to_s
  "#{@scheme}://#{@authority}: #{@method} #{@path} #{@version}"
end