Class: Stipa::Request
- Inherits:
-
Object
- Object
- Stipa::Request
- Defined in:
- lib/stipa/request.rb
Overview
Parses a raw HTTP/1.1 header block (already read by Connection) and reads the body from the socket using Content-Length.
Design notes:
- Headers are stored with lower-cased keys for O(1) case-insensitive
lookup (RFC 7230 ยง3.2: header names are case-insensitive).
- Body is read with IO.select + read_nonblock rather than SO_RCVTIMEO
because SO_RCVTIMEO behaves inconsistently across Ruby versions and
platforms. IO.select releases the GVL while waiting.
- `id` and `params` are writable: RequestId middleware sets `id`,
the router sets `params` after matching.
- We reject header folding (obsolete since RFC 7230) with a 400.
- Chunked Transfer-Encoding is not supported in this version.
Constant Summary collapse
- MAX_HEADER_SIZE =
8 KB โ slow-loris defence
8 * 1024
- MAX_BODY_SIZE =
1 MB default; configurable per-server
1 * 1024 * 1024
- VALID_METHODS =
%w[GET POST PUT PATCH DELETE HEAD OPTIONS TRACE CONNECT].freeze
Instance Attribute Summary collapse
-
#body ⇒ Object
readonly
Returns the value of attribute body.
-
#bytes_in ⇒ Object
readonly
Returns the value of attribute bytes_in.
-
#headers ⇒ Object
readonly
Returns the value of attribute headers.
-
#http_version ⇒ Object
readonly
Returns the value of attribute http_version.
-
#id ⇒ Object
Returns the value of attribute id.
-
#method ⇒ Object
Returns the value of attribute method.
-
#params ⇒ Object
Returns the value of attribute params.
-
#path ⇒ Object
readonly
Returns the value of attribute path.
-
#query_string ⇒ Object
readonly
Returns the value of attribute query_string.
Class Method Summary collapse
-
.parse(raw_headers, socket:, peer:, body_timeout:, socket_buffer: '', config: {}) ⇒ Object
Factory โ called by Connection after reading the header block.
Instance Method Summary collapse
- #[](name) ⇒ Object
-
#initialize(raw_headers, socket:, peer:, body_timeout:, socket_buffer: '', config: {}) ⇒ Request
constructor
A new instance of Request.
Constructor Details
#initialize(raw_headers, socket:, peer:, body_timeout:, socket_buffer: '', config: {}) ⇒ Request
Returns a new instance of Request.
45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/stipa/request.rb', line 45 def initialize(raw_headers, socket:, peer:, body_timeout:, socket_buffer: '', config: {}) @socket = socket @peer = peer @body_timeout = body_timeout @socket_buffer = socket_buffer.b # binary copy of pre-read body bytes @max_body = config.fetch(:max_body_size, MAX_BODY_SIZE) @bytes_in = raw_headers.bytesize @id = nil # set by RequestId middleware @params = {} # set by App#dispatch after route match parse_headers(raw_headers) read_body end |
Instance Attribute Details
#body ⇒ Object (readonly)
Returns the value of attribute body.
27 28 29 |
# File 'lib/stipa/request.rb', line 27 def body @body end |
#bytes_in ⇒ Object (readonly)
Returns the value of attribute bytes_in.
27 28 29 |
# File 'lib/stipa/request.rb', line 27 def bytes_in @bytes_in end |
#headers ⇒ Object (readonly)
Returns the value of attribute headers.
27 28 29 |
# File 'lib/stipa/request.rb', line 27 def headers @headers end |
#http_version ⇒ Object (readonly)
Returns the value of attribute http_version.
27 28 29 |
# File 'lib/stipa/request.rb', line 27 def http_version @http_version end |
#id ⇒ Object
Returns the value of attribute id.
26 27 28 |
# File 'lib/stipa/request.rb', line 26 def id @id end |
#method ⇒ Object
Returns the value of attribute method.
26 27 28 |
# File 'lib/stipa/request.rb', line 26 def method @method end |
#params ⇒ Object
Returns the value of attribute params.
26 27 28 |
# File 'lib/stipa/request.rb', line 26 def params @params end |
#path ⇒ Object (readonly)
Returns the value of attribute path.
27 28 29 |
# File 'lib/stipa/request.rb', line 27 def path @path end |
#query_string ⇒ Object (readonly)
Returns the value of attribute query_string.
27 28 29 |
# File 'lib/stipa/request.rb', line 27 def query_string @query_string end |
Class Method Details
.parse(raw_headers, socket:, peer:, body_timeout:, socket_buffer: '', config: {}) ⇒ Object
Factory โ called by Connection after reading the header block.
39 40 41 42 43 |
# File 'lib/stipa/request.rb', line 39 def self.parse(raw_headers, socket:, peer:, body_timeout:, socket_buffer: '', config: {}) new(raw_headers, socket:, peer:, body_timeout:, socket_buffer:, config:) end |