Skip to content

Commit

Permalink
Add a linter for rack.early_hints
Browse files Browse the repository at this point in the history
  • Loading branch information
byroot committed Jul 20, 2020
1 parent 649c72b commit a8de1fe
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 0 deletions.
10 changes: 10 additions & 0 deletions SPEC.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ There are the following restrictions:
* There must be a valid input stream in <tt>rack.input</tt>.
* There must be a valid error stream in <tt>rack.errors</tt>.
* There may be a valid hijack stream in <tt>rack.hijack_io</tt>
* There may be a valid early hints callback in <tt>rack.early_hints</tt>
* The <tt>REQUEST_METHOD</tt> must be a valid token.
* The <tt>SCRIPT_NAME</tt>, if non-empty, must start with <tt>/</tt>
* The <tt>PATH_INFO</tt>, if non-empty, must start with <tt>/</tt>
Expand Down Expand Up @@ -244,6 +245,15 @@ if the request env has <tt>rack.hijack?</tt> <tt>true</tt>.
* Middleware may wrap the IO object for the response pattern.
* Middleware should not wrap the IO object for the request pattern. The
request pattern is intended to provide the hijacker with "raw tcp".
=== Early Hints

The application or any middleware may call the <tt>rack.early_hints</tt>
with pairs of headers that will be sent as a 103 Early Hints provisional
response.

If rack.early_hints is present it must respond to #call.
The headers must respond to #each_pair
The headers keys and values must respond to #to_s
== The Response
=== The Status
This is an HTTP status. It must be an Integer greater than or equal to
Expand Down
1 change: 1 addition & 0 deletions lib/rack.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ module Rack
RACK_HIJACK = 'rack.hijack'
RACK_IS_HIJACK = 'rack.hijack?'
RACK_HIJACK_IO = 'rack.hijack_io'
RACK_EARLY_HINTS = 'rack.early_hints'
RACK_RECURSIVE_INCLUDE = 'rack.recursive.include'
RACK_MULTIPART_BUFFER_SIZE = 'rack.multipart.buffer_size'
RACK_MULTIPART_TEMPFILE_FACTORY = 'rack.multipart.tempfile_factory'
Expand Down
25 changes: 25 additions & 0 deletions lib/rack/lint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,8 @@ def check_env(env)
check_error env[RACK_ERRORS]
## * There may be a valid hijack stream in <tt>rack.hijack_io</tt>
check_hijack env
## * There may be a valid early hints callback in <tt>rack.early_hints</tt>
check_early_hints env

## * The <tt>REQUEST_METHOD</tt> must be a valid token.
assert("REQUEST_METHOD unknown: #{env[REQUEST_METHOD]}") {
Expand Down Expand Up @@ -655,6 +657,29 @@ def check_hijack_response(headers, env)
## * Middleware should not wrap the IO object for the request pattern. The
## request pattern is intended to provide the hijacker with "raw tcp".

## === Early Hints
##
## The application or any middleware may call the <tt>rack.early_hints</tt>
## with pairs of headers that will be sent as a 103 Early Hints provisional
## response.
def check_early_hints(env)
if env[RACK_EARLY_HINTS]
##
## If rack.early_hints is present it must respond to #call.
assert("rack.early_hints must respond to call") { env[RACK_EARLY_HINTS].respond_to?(:call) }
original_callback = env[RACK_EARLY_HINTS]
env[RACK_EARLY_HINTS] = lambda do |headers|
## The headers must respond to #each_pair
assert("rack.early_hints headers must respond to each_pair") { headers.respond_to?(:each_pair) }
headers.each_pair do |key, value|
## The headers keys and values must respond to #to_s
assert("rack.early_hints headers keys must respond to to_s") { key.respond_to?(:to_s) }
assert("rack.early_hints headers values must respond to to_s") { value.respond_to?(:to_s) }
end
end
end
end

## == The Response

## === The Status
Expand Down

0 comments on commit a8de1fe

Please sign in to comment.