Skip to content

Commit 86f4f83

Browse files
lint.rb consistency improvements as suggested by Claude.
1 parent 9a79ed3 commit 86f4f83

File tree

2 files changed

+26
-22
lines changed

2 files changed

+26
-22
lines changed

SPEC.rdoc

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ The remainder of the request URL's "path", designating the virtual "location" of
3434

3535
The <tt>PATH_INFO</tt>, if provided, must be a valid request target or an empty string, as defined by {RFC9110}[https://datatracker.ietf.org/doc/html/rfc9110#target.resource].
3636
* Only <tt>OPTIONS</tt> requests may have <tt>PATH_INFO</tt> set to <tt>*</tt> (asterisk-form).
37-
* Only <tt>CONNECT</tt> requests may have <tt>PATH_INFO</tt> set to an authority (authority-form). Note that in HTTP/2+, the authority-form is not a valid request target.
37+
* Only <tt>CONNECT</tt> requests may have <tt>PATH_INFO</tt> set to an authority (authority-form). Note that in <tt>HTTP/2+</tt>, the authority-form is not a valid request target.
3838
* <tt>CONNECT</tt> and <tt>OPTIONS</tt> requests must not have <tt>PATH_INFO</tt> set to a URI (absolute-form).
3939
* Otherwise, <tt>PATH_INFO</tt> must start with a <tt>/</tt> and must not include a fragment part starting with <tt>#</tt> (origin-form).
4040

@@ -88,7 +88,7 @@ The URL scheme, which must be one of <tt>http</tt>, <tt>https</tt>, <tt>ws</tt>
8888

8989
==== <tt>rack.protocol</tt>
9090

91-
An optional +Array+ of +String+ values, containing the protocols advertised by the client in the <tt>upgrade</tt> header (HTTP/1) or the <tt>:protocol</tt> pseudo-header (HTTP/2+).
91+
An optional +Array+ of +String+ values, containing the protocols advertised by the client in the <tt>upgrade</tt> header (<tt>HTTP/1</tt>) or the <tt>:protocol</tt> pseudo-header (<tt>HTTP/2+</tt>).
9292

9393
==== <tt>rack.session</tt>
9494

@@ -167,13 +167,13 @@ The error stream must respond to +puts+, +write+ and +flush+:
167167

168168
The hijacking interfaces provides a means for an application to take control of the HTTP connection. There are two distinct hijack interfaces: full hijacking where the application takes over the raw connection, and partial hijacking where the application takes over just the response body stream. In both cases, the application is responsible for closing the hijacked stream.
169169

170-
Full hijacking only works with HTTP/1. Partial hijacking is functionally equivalent to streaming bodies, and is still optionally supported for backwards compatibility with older Rack versions.
170+
Full hijacking only works with <tt>HTTP/1</tt>. Partial hijacking is functionally equivalent to streaming bodies, and is still optionally supported for backwards compatibility with older Rack versions.
171171

172172
==== Full Hijack
173173

174-
Full hijack is used to completely take over an HTTP/1 connection. It occurs before any headers are written and causes the server to ignore any response generated by the application. It is intended to be used when applications need access to the raw HTTP/1 connection.
174+
Full hijack is used to completely take over an <tt>HTTP/1</tt> connection. It occurs before any headers are written and causes the server to ignore any response generated by the application. It is intended to be used when applications need access to the raw <tt>HTTP/1</tt> connection.
175175

176-
If <tt>rack.hijack</tt> is present in +env+, it must respond to +call+ and return an +IO+ instance which can be used to read and write to the underlying connection using HTTP/1 semantics and formatting.
176+
If <tt>rack.hijack</tt> is present in +env+, it must respond to +call+ and return an +IO+ instance which can be used to read and write to the underlying connection using <tt>HTTP/1</tt> semantics and formatting.
177177

178178
==== Partial Hijack
179179

@@ -205,23 +205,23 @@ This is an HTTP status. It must be an Integer greater than or equal to 100.
205205
The headers must be a unfrozen +Hash+. The header keys must be +String+ objects. Special headers starting <tt>rack.</tt> are for communicating with the server, and must not be sent back to the client.
206206

207207
* The headers must not contain a <tt>"status"</tt> key.
208-
* Header keys must conform to RFC7230 token specification, i.e. cannot contain non-printable ASCII, DQUOTE or <tt>(),/:;<=>?@[\]{}</tt>.
208+
* Header keys must conform to {RFC7230}[https://tools.ietf.org/html/rfc7230] token specification, i.e. cannot contain non-printable ASCII, DQUOTE or <tt>(),/:;<=>?@[\]{}</tt>.
209209
* Header keys must not contain uppercase ASCII characters (A-Z).
210210
* Header values must be either a +String+ value, or an +Array+ of +String+ values, such that each +String+ value must not contain characters with an ASCII ordinal below 040 (32).
211211

212212
==== The <tt>content-type</tt> Header
213213

214-
There must not be a <tt>content-type</tt> header key when the status is 1xx, 204, or 304.
214+
There must not be a <tt>content-type</tt> header key when the status is <tt>1xx</tt>, <tt>204</tt>, or <tt>304</tt>.
215215

216216
==== The <tt>content-length</tt> Header
217217

218-
There must not be a <tt>content-length</tt> header key when the status is 1xx, 204, or 304.
218+
There must not be a <tt>content-length</tt> header key when the status is <tt>1xx</tt>, <tt>204</tt>, or <tt>304</tt>.
219219

220220
==== The <tt>rack.protocol</tt> Header
221221

222222
If the <tt>rack.protocol</tt> header is present, it must be a +String+, and must be one of the values from the <tt>rack.protocol</tt> array from the environment.
223223

224-
Setting this value informs the server that it should perform a connection upgrade. In HTTP/1, this is done using the +upgrade+ header. In HTTP/2, this is done by accepting the request.
224+
Setting this value informs the server that it should perform a connection upgrade. In <tt>HTTP/1</tt>, this is done using the +upgrade+ header. In <tt>HTTP/2</tt>, this is done by accepting the request.
225225

226226
=== The Body
227227

@@ -249,7 +249,7 @@ If the Body responds to +to_ary+, it must return an +Array+ whose contents are i
249249

250250
The Streaming Body must respond to +call+. It must only be called once. It must not be called after being closed. It takes a +stream+ argument.
251251

252-
The +stream+ argument must respond to: +read+, +write+, <tt><<</tt>, +flush+, +close+, +close_read+, +close_write+, and +closed?+. The semantics of these +IO+ methods must be a best effort match to those of a normal Ruby +IO+ or +Socket+ object, using standard arguments and raising standard exceptions. Servers may simply pass on real +IO+ objects to the Streaming Body. In some cases (e.g. when using <tt>transfer-encoding</tt> or HTTP/2+), the server may need to provide a wrapper that implements the required methods, in order to provide the correct semantics.
252+
The +stream+ argument must respond to: +read+, +write+, <tt><<</tt>, +flush+, +close+, +close_read+, +close_write+, and +closed?+. The semantics of these +IO+ methods must be a best effort match to those of a normal Ruby +IO+ or +Socket+ object, using standard arguments and raising standard exceptions. Servers may simply pass on real +IO+ objects to the Streaming Body. In some cases (e.g. when using <tt>transfer-encoding</tt> or <tt>HTTP/2+</tt>), the server may need to provide a wrapper that implements the required methods, in order to provide the correct semantics.
253253

254254
== Thanks
255255

lib/rack/lint.rb

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ module Rack
1010
class Lint
1111
# Represents a failure to meet the Rack specification.
1212
class LintError < RuntimeError; end
13-
13+
1414
# Invoke the application, validating the request and response according to the Rack spec.
1515
def call(env = nil)
1616
Wrapper.new(@app, env).response
1717
end
18-
18+
1919
# :stopdoc:
2020

2121
ALLOWED_SCHEMES = %w(https http wss ws).freeze
@@ -55,6 +55,10 @@ def call(env = nil)
5555

5656
# N.B. The empty `##` comments creates paragraphs in the output. A trailing "\" is used to escape the newline character, which combines the comments into a single paragraph.
5757
#
58+
# Formatting conventions for documentation:
59+
# - Use <tt> for: literal values, constants, method signatures, environment keys
60+
# - Use + for: Ruby types, concepts, method names, class references
61+
#
5862
## = Rack Specification
5963
##
6064
## This specification aims to formalize the Rack protocol. You can (and should) use +Rack::Lint+ to enforce it. When you develop middleware, be sure to test with +Rack::Lint+ to catch possible violations of this specification.
@@ -213,7 +217,7 @@ def check_environment(env)
213217
raise LintError, "Only OPTIONS requests may have PATH_INFO set to '*' (asterisk-form)"
214218
end
215219
when REQUEST_PATH_AUTHORITY_FORM
216-
## * Only <tt>CONNECT</tt> requests may have <tt>PATH_INFO</tt> set to an authority (authority-form). Note that in HTTP/2+, the authority-form is not a valid request target.
220+
## * Only <tt>CONNECT</tt> requests may have <tt>PATH_INFO</tt> set to an authority (authority-form). Note that in <tt>HTTP/2+</tt>, the authority-form is not a valid request target.
217221
unless env[REQUEST_METHOD] == CONNECT
218222
raise LintError, "Only CONNECT requests may have PATH_INFO set to an authority (authority-form)"
219223
end
@@ -325,7 +329,7 @@ def check_environment(env)
325329
##
326330
## ==== <tt>rack.protocol</tt>
327331
##
328-
## An optional +Array+ of +String+ values, containing the protocols advertised by the client in the <tt>upgrade</tt> header (HTTP/1) or the <tt>:protocol</tt> pseudo-header (HTTP/2+).
332+
## An optional +Array+ of +String+ values, containing the protocols advertised by the client in the <tt>upgrade</tt> header (<tt>HTTP/1</tt>) or the <tt>:protocol</tt> pseudo-header (<tt>HTTP/2+</tt>).
329333
if protocols = env[RACK_PROTOCOL]
330334
unless protocols.is_a?(Array) && protocols.all?{|protocol| protocol.is_a?(String)}
331335
raise LintError, "rack.protocol must be an Array of Strings"
@@ -610,11 +614,11 @@ def close(*args)
610614
##
611615
## The hijacking interfaces provides a means for an application to take control of the HTTP connection. There are two distinct hijack interfaces: full hijacking where the application takes over the raw connection, and partial hijacking where the application takes over just the response body stream. In both cases, the application is responsible for closing the hijacked stream.
612616
##
613-
## Full hijacking only works with HTTP/1. Partial hijacking is functionally equivalent to streaming bodies, and is still optionally supported for backwards compatibility with older Rack versions.
617+
## Full hijacking only works with <tt>HTTP/1</tt>. Partial hijacking is functionally equivalent to streaming bodies, and is still optionally supported for backwards compatibility with older Rack versions.
614618
##
615619
## ==== Full Hijack
616620
##
617-
## Full hijack is used to completely take over an HTTP/1 connection. It occurs before any headers are written and causes the server to ignore any response generated by the application. It is intended to be used when applications need access to the raw HTTP/1 connection.
621+
## Full hijack is used to completely take over an <tt>HTTP/1</tt> connection. It occurs before any headers are written and causes the server to ignore any response generated by the application. It is intended to be used when applications need access to the raw <tt>HTTP/1</tt> connection.
618622
##
619623
def check_hijack(env)
620624
## If <tt>rack.hijack</tt> is present in +env+, it must respond to +call+ \
@@ -624,7 +628,7 @@ def check_hijack(env)
624628
env[RACK_HIJACK] = proc do
625629
io = original_hijack.call
626630

627-
## and return an +IO+ instance which can be used to read and write to the underlying connection using HTTP/1 semantics and formatting.
631+
## and return an +IO+ instance which can be used to read and write to the underlying connection using <tt>HTTP/1</tt> semantics and formatting.
628632
raise LintError, "rack.hijack must return an IO instance" unless io.is_a?(IO)
629633

630634
io
@@ -724,7 +728,7 @@ def check_headers(headers)
724728
##
725729
## * The headers must not contain a <tt>"status"</tt> key.
726730
raise LintError, "headers must not contain status" if key == "status"
727-
## * Header keys must conform to RFC7230 token specification, i.e. cannot contain non-printable ASCII, DQUOTE or <tt>(),/:;<=>?@[\]{}</tt>.
731+
## * Header keys must conform to {RFC7230}[https://tools.ietf.org/html/rfc7230] token specification, i.e. cannot contain non-printable ASCII, DQUOTE or <tt>(),/:;<=>?@[\]{}</tt>.
728732
raise LintError, "invalid header name: #{key}" if key =~ /[\(\),\/:;<=>\?@\[\\\]{}[:cntrl:]]/
729733
## * Header keys must not contain uppercase ASCII characters (A-Z).
730734
raise LintError, "uppercase character in header name: #{key}" if key =~ /[A-Z]/
@@ -753,7 +757,7 @@ def check_header_value(key, value)
753757
##
754758
def check_content_type_header(status, headers)
755759
headers.each do |key, value|
756-
## There must not be a <tt>content-type</tt> header key when the status is 1xx, 204, or 304.
760+
## There must not be a <tt>content-type</tt> header key when the status is <tt>1xx</tt>, <tt>204</tt>, or <tt>304</tt>.
757761
if key == "content-type"
758762
if Rack::Utils::STATUS_WITH_NO_ENTITY_BODY.key? status.to_i
759763
raise LintError, "content-type header found in #{status} response, not allowed"
@@ -769,7 +773,7 @@ def check_content_type_header(status, headers)
769773
def check_content_length_header(status, headers)
770774
headers.each do |key, value|
771775
if key == 'content-length'
772-
## There must not be a <tt>content-length</tt> header key when the status is 1xx, 204, or 304.
776+
## There must not be a <tt>content-length</tt> header key when the status is <tt>1xx</tt>, <tt>204</tt>, or <tt>304</tt>.
773777
if Rack::Utils::STATUS_WITH_NO_ENTITY_BODY.key? status.to_i
774778
raise LintError, "content-length header found in #{status} response, not allowed"
775779
end
@@ -808,7 +812,7 @@ def check_rack_protocol_header(status, headers)
808812
end
809813
end
810814
##
811-
## Setting this value informs the server that it should perform a connection upgrade. In HTTP/1, this is done using the +upgrade+ header. In HTTP/2, this is done by accepting the request.
815+
## Setting this value informs the server that it should perform a connection upgrade. In <tt>HTTP/1</tt>, this is done using the +upgrade+ header. In <tt>HTTP/2</tt>, this is done by accepting the request.
812816
##
813817
## === The Body
814818
##
@@ -937,7 +941,7 @@ def call(stream)
937941
class StreamWrapper
938942
extend Forwardable
939943

940-
## The semantics of these +IO+ methods must be a best effort match to those of a normal Ruby +IO+ or +Socket+ object, using standard arguments and raising standard exceptions. Servers may simply pass on real +IO+ objects to the Streaming Body. In some cases (e.g. when using <tt>transfer-encoding</tt> or HTTP/2+), the server may need to provide a wrapper that implements the required methods, in order to provide the correct semantics.
944+
## The semantics of these +IO+ methods must be a best effort match to those of a normal Ruby +IO+ or +Socket+ object, using standard arguments and raising standard exceptions. Servers may simply pass on real +IO+ objects to the Streaming Body. In some cases (e.g. when using <tt>transfer-encoding</tt> or <tt>HTTP/2+</tt>), the server may need to provide a wrapper that implements the required methods, in order to provide the correct semantics.
941945
REQUIRED_METHODS = [
942946
:read, :write, :<<, :flush, :close,
943947
:close_read, :close_write, :closed?

0 commit comments

Comments
 (0)