rack 1.6.11 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rack might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +675 -0
- data/CONTRIBUTING.md +136 -0
- data/{COPYING → MIT-LICENSE} +4 -2
- data/README.rdoc +157 -163
- data/Rakefile +38 -32
- data/{SPEC → SPEC.rdoc} +41 -13
- data/bin/rackup +1 -0
- data/contrib/rack_logo.svg +164 -111
- data/example/lobster.ru +2 -0
- data/example/protectedlobster.rb +4 -2
- data/example/protectedlobster.ru +3 -1
- data/lib/rack/auth/abstract/handler.rb +3 -1
- data/lib/rack/auth/abstract/request.rb +6 -2
- data/lib/rack/auth/basic.rb +7 -4
- data/lib/rack/auth/digest/md5.rb +13 -11
- data/lib/rack/auth/digest/nonce.rb +6 -3
- data/lib/rack/auth/digest/params.rb +5 -4
- data/lib/rack/auth/digest/request.rb +6 -4
- data/lib/rack/body_proxy.rb +21 -15
- data/lib/rack/builder.rb +119 -26
- data/lib/rack/cascade.rb +28 -12
- data/lib/rack/chunked.rb +70 -22
- data/lib/rack/common_logger.rb +80 -0
- data/lib/rack/{conditionalget.rb → conditional_get.rb} +20 -16
- data/lib/rack/config.rb +2 -0
- data/lib/rack/content_length.rb +9 -8
- data/lib/rack/content_type.rb +5 -4
- data/lib/rack/core_ext/regexp.rb +14 -0
- data/lib/rack/deflater.rb +60 -70
- data/lib/rack/directory.rb +117 -85
- data/lib/rack/etag.rb +9 -7
- data/lib/rack/events.rb +153 -0
- data/lib/rack/file.rb +4 -149
- data/lib/rack/files.rb +218 -0
- data/lib/rack/handler/cgi.rb +17 -19
- data/lib/rack/handler/fastcgi.rb +17 -18
- data/lib/rack/handler/lsws.rb +14 -14
- data/lib/rack/handler/scgi.rb +22 -21
- data/lib/rack/handler/thin.rb +20 -11
- data/lib/rack/handler/webrick.rb +39 -32
- data/lib/rack/handler.rb +9 -26
- data/lib/rack/head.rb +16 -18
- data/lib/rack/lint.rb +110 -64
- data/lib/rack/lobster.rb +10 -10
- data/lib/rack/lock.rb +17 -11
- data/lib/rack/logger.rb +4 -2
- data/lib/rack/media_type.rb +43 -0
- data/lib/rack/{methodoverride.rb → method_override.rb} +10 -8
- data/lib/rack/mime.rb +27 -6
- data/lib/rack/mock.rb +124 -65
- data/lib/rack/multipart/generator.rb +20 -16
- data/lib/rack/multipart/parser.rb +273 -162
- data/lib/rack/multipart/uploaded_file.rb +15 -8
- data/lib/rack/multipart.rb +39 -8
- data/lib/rack/{nulllogger.rb → null_logger.rb} +3 -1
- data/lib/rack/query_parser.rb +217 -0
- data/lib/rack/recursive.rb +11 -9
- data/lib/rack/reloader.rb +8 -4
- data/lib/rack/request.rb +543 -305
- data/lib/rack/response.rb +244 -88
- data/lib/rack/rewindable_input.rb +5 -15
- data/lib/rack/runtime.rb +12 -18
- data/lib/rack/sendfile.rb +17 -15
- data/lib/rack/server.rb +125 -47
- data/lib/rack/session/abstract/id.rb +216 -93
- data/lib/rack/session/cookie.rb +47 -31
- data/lib/rack/session/memcache.rb +4 -87
- data/lib/rack/session/pool.rb +26 -17
- data/lib/rack/show_exceptions.rb +390 -0
- data/lib/rack/{showstatus.rb → show_status.rb} +8 -8
- data/lib/rack/static.rb +48 -11
- data/lib/rack/tempfile_reaper.rb +3 -3
- data/lib/rack/urlmap.rb +26 -19
- data/lib/rack/utils.rb +208 -294
- data/lib/rack/version.rb +29 -0
- data/lib/rack.rb +76 -33
- data/rack.gemspec +43 -30
- metadata +62 -183
- data/HISTORY.md +0 -375
- data/KNOWN-ISSUES +0 -44
- data/lib/rack/backports/uri/common_18.rb +0 -56
- data/lib/rack/backports/uri/common_192.rb +0 -52
- data/lib/rack/backports/uri/common_193.rb +0 -29
- data/lib/rack/commonlogger.rb +0 -72
- data/lib/rack/handler/evented_mongrel.rb +0 -8
- data/lib/rack/handler/mongrel.rb +0 -106
- data/lib/rack/handler/swiftiplied_mongrel.rb +0 -8
- data/lib/rack/showexceptions.rb +0 -387
- data/lib/rack/utils/okjson.rb +0 -600
- data/test/builder/anything.rb +0 -5
- data/test/builder/comment.ru +0 -4
- data/test/builder/end.ru +0 -5
- data/test/builder/line.ru +0 -1
- data/test/builder/options.ru +0 -2
- data/test/cgi/assets/folder/test.js +0 -1
- data/test/cgi/assets/fonts/font.eot +0 -1
- data/test/cgi/assets/images/image.png +0 -1
- data/test/cgi/assets/index.html +0 -1
- data/test/cgi/assets/javascripts/app.js +0 -1
- data/test/cgi/assets/stylesheets/app.css +0 -1
- data/test/cgi/lighttpd.conf +0 -26
- data/test/cgi/rackup_stub.rb +0 -6
- data/test/cgi/sample_rackup.ru +0 -5
- data/test/cgi/test +0 -9
- data/test/cgi/test+directory/test+file +0 -1
- data/test/cgi/test.fcgi +0 -8
- data/test/cgi/test.ru +0 -5
- data/test/gemloader.rb +0 -10
- data/test/multipart/bad_robots +0 -259
- data/test/multipart/binary +0 -0
- data/test/multipart/content_type_and_no_filename +0 -6
- data/test/multipart/empty +0 -10
- data/test/multipart/fail_16384_nofile +0 -814
- data/test/multipart/file1.txt +0 -1
- data/test/multipart/filename_and_modification_param +0 -7
- data/test/multipart/filename_and_no_name +0 -6
- data/test/multipart/filename_with_escaped_quotes +0 -6
- data/test/multipart/filename_with_escaped_quotes_and_modification_param +0 -7
- data/test/multipart/filename_with_null_byte +0 -7
- data/test/multipart/filename_with_percent_escaped_quotes +0 -6
- data/test/multipart/filename_with_unescaped_percentages +0 -6
- data/test/multipart/filename_with_unescaped_percentages2 +0 -6
- data/test/multipart/filename_with_unescaped_percentages3 +0 -6
- data/test/multipart/filename_with_unescaped_quotes +0 -6
- data/test/multipart/ie +0 -6
- data/test/multipart/invalid_character +0 -6
- data/test/multipart/mixed_files +0 -21
- data/test/multipart/nested +0 -10
- data/test/multipart/none +0 -9
- data/test/multipart/semicolon +0 -6
- data/test/multipart/text +0 -15
- data/test/multipart/three_files_three_fields +0 -31
- data/test/multipart/webkit +0 -32
- data/test/rackup/config.ru +0 -31
- data/test/registering_handler/rack/handler/registering_myself.rb +0 -8
- data/test/spec_auth_basic.rb +0 -81
- data/test/spec_auth_digest.rb +0 -259
- data/test/spec_body_proxy.rb +0 -85
- data/test/spec_builder.rb +0 -223
- data/test/spec_cascade.rb +0 -61
- data/test/spec_cgi.rb +0 -102
- data/test/spec_chunked.rb +0 -101
- data/test/spec_commonlogger.rb +0 -93
- data/test/spec_conditionalget.rb +0 -102
- data/test/spec_config.rb +0 -22
- data/test/spec_content_length.rb +0 -85
- data/test/spec_content_type.rb +0 -45
- data/test/spec_deflater.rb +0 -339
- data/test/spec_directory.rb +0 -88
- data/test/spec_etag.rb +0 -107
- data/test/spec_fastcgi.rb +0 -107
- data/test/spec_file.rb +0 -221
- data/test/spec_handler.rb +0 -72
- data/test/spec_head.rb +0 -45
- data/test/spec_lint.rb +0 -550
- data/test/spec_lobster.rb +0 -58
- data/test/spec_lock.rb +0 -164
- data/test/spec_logger.rb +0 -23
- data/test/spec_methodoverride.rb +0 -111
- data/test/spec_mime.rb +0 -51
- data/test/spec_mock.rb +0 -297
- data/test/spec_mongrel.rb +0 -182
- data/test/spec_multipart.rb +0 -600
- data/test/spec_nulllogger.rb +0 -20
- data/test/spec_recursive.rb +0 -72
- data/test/spec_request.rb +0 -1232
- data/test/spec_response.rb +0 -407
- data/test/spec_rewindable_input.rb +0 -118
- data/test/spec_runtime.rb +0 -49
- data/test/spec_sendfile.rb +0 -130
- data/test/spec_server.rb +0 -167
- data/test/spec_session_abstract_id.rb +0 -53
- data/test/spec_session_cookie.rb +0 -410
- data/test/spec_session_memcache.rb +0 -321
- data/test/spec_session_pool.rb +0 -209
- data/test/spec_showexceptions.rb +0 -98
- data/test/spec_showstatus.rb +0 -103
- data/test/spec_static.rb +0 -145
- data/test/spec_tempfile_reaper.rb +0 -63
- data/test/spec_thin.rb +0 -91
- data/test/spec_urlmap.rb +0 -236
- data/test/spec_utils.rb +0 -647
- data/test/spec_version.rb +0 -17
- data/test/spec_webrick.rb +0 -184
- data/test/static/another/index.html +0 -1
- data/test/static/index.html +0 -1
- data/test/testrequest.rb +0 -78
- data/test/unregistered_handler/rack/handler/unregistered.rb +0 -7
- data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +0 -7
data/Rakefile
CHANGED
@@ -1,7 +1,10 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
require "rake/testtask"
|
2
5
|
|
3
6
|
desc "Run all the tests"
|
4
|
-
task :
|
7
|
+
task default: :test
|
5
8
|
|
6
9
|
desc "Install gem dependencies"
|
7
10
|
task :deps do
|
@@ -16,9 +19,9 @@ task :deps do
|
|
16
19
|
end
|
17
20
|
|
18
21
|
desc "Make an archive as .tar.gz"
|
19
|
-
task :
|
22
|
+
task dist: %w[chmod changelog spec rdoc] do
|
20
23
|
sh "git archive --format=tar --prefix=#{release}/ HEAD^{tree} >#{release}.tar"
|
21
|
-
sh "pax -waf #{release}.tar -s ':^:#{release}/:' SPEC ChangeLog doc rack.gemspec"
|
24
|
+
sh "pax -waf #{release}.tar -s ':^:#{release}/:' SPEC.rdoc ChangeLog doc rack.gemspec"
|
22
25
|
sh "gzip -f -9 #{release}.tar"
|
23
26
|
end
|
24
27
|
|
@@ -31,12 +34,12 @@ task :officialrelease do
|
|
31
34
|
sh "mv stage/#{release}.tar.gz stage/#{release}.gem ."
|
32
35
|
end
|
33
36
|
|
34
|
-
task :
|
37
|
+
task officialrelease_really: %w[spec dist gem] do
|
35
38
|
sh "shasum #{release}.tar.gz #{release}.gem"
|
36
39
|
end
|
37
40
|
|
38
41
|
def release
|
39
|
-
"rack
|
42
|
+
"rack-" + File.read('lib/rack/version.rb')[/RELEASE += +([\"\'])([\d][\w\.]+)\1/, 2]
|
40
43
|
end
|
41
44
|
|
42
45
|
desc "Make binaries executable"
|
@@ -46,13 +49,13 @@ task :chmod do
|
|
46
49
|
end
|
47
50
|
|
48
51
|
desc "Generate a ChangeLog"
|
49
|
-
task :
|
52
|
+
task changelog: "ChangeLog"
|
50
53
|
|
51
54
|
file '.git/index'
|
52
55
|
file "ChangeLog" => '.git/index' do
|
53
56
|
File.open("ChangeLog", "w") { |out|
|
54
57
|
log = `git log -z`
|
55
|
-
log.force_encoding(Encoding::BINARY)
|
58
|
+
log.force_encoding(Encoding::BINARY)
|
56
59
|
log.split("\0").map { |chunk|
|
57
60
|
author = chunk[/Author: (.*)/, 1].strip
|
58
61
|
date = chunk[/Date: (.*)/, 1].strip
|
@@ -68,56 +71,59 @@ file "ChangeLog" => '.git/index' do
|
|
68
71
|
}
|
69
72
|
end
|
70
73
|
|
71
|
-
file 'lib/rack/lint.rb'
|
72
74
|
desc "Generate Rack Specification"
|
73
|
-
|
74
|
-
|
75
|
+
task spec: "SPEC.rdoc"
|
76
|
+
|
77
|
+
file 'lib/rack/lint.rb'
|
78
|
+
file "SPEC.rdoc" => 'lib/rack/lint.rb' do
|
79
|
+
File.open("SPEC.rdoc", "wb") { |file|
|
75
80
|
IO.foreach("lib/rack/lint.rb") { |line|
|
76
|
-
if line =~
|
81
|
+
if line =~ /^\s*## ?(.*)/
|
77
82
|
file.puts $1
|
78
83
|
end
|
79
84
|
}
|
80
85
|
}
|
81
86
|
end
|
82
87
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
+
Rake::TestTask.new("test:regular") do |t|
|
89
|
+
t.libs << "test"
|
90
|
+
t.test_files = FileList["test/**/*_test.rb", "test/**/spec_*.rb", "test/gemloader.rb"]
|
91
|
+
t.warning = false
|
92
|
+
t.verbose = true
|
93
|
+
end
|
88
94
|
|
89
|
-
|
95
|
+
desc "Run tests with coverage"
|
96
|
+
task "test_cov" do
|
97
|
+
ENV['COVERAGE'] = '1'
|
98
|
+
Rake::Task['test:regular'].invoke
|
90
99
|
end
|
91
100
|
|
92
|
-
desc "Run all the
|
93
|
-
task :
|
101
|
+
desc "Run all the fast + platform agnostic tests"
|
102
|
+
task test: %w[spec test:regular]
|
94
103
|
|
95
|
-
desc "Run all the tests"
|
96
|
-
task :
|
97
|
-
opts = ENV['TEST'] || '-a'
|
98
|
-
specopts = ENV['TESTOPTS'] || '-q'
|
99
|
-
sh "bacon -r./test/gemloader -I./lib:./test -w #{opts} #{specopts}"
|
100
|
-
end
|
104
|
+
desc "Run all the tests we run on CI"
|
105
|
+
task ci: :test
|
101
106
|
|
102
|
-
task :
|
107
|
+
task gem: :spec do
|
103
108
|
sh "gem build rack.gemspec"
|
104
109
|
end
|
105
110
|
|
106
|
-
task :
|
111
|
+
task doc: :rdoc
|
112
|
+
|
107
113
|
desc "Generate RDoc documentation"
|
108
|
-
task :
|
114
|
+
task rdoc: %w[changelog spec] do
|
109
115
|
sh(*%w{rdoc --line-numbers --main README.rdoc
|
110
116
|
--title 'Rack\ Documentation' --charset utf-8 -U -o doc} +
|
111
|
-
%w{README.rdoc KNOWN-ISSUES SPEC ChangeLog} +
|
117
|
+
%w{README.rdoc KNOWN-ISSUES SPEC.rdoc ChangeLog} +
|
112
118
|
`git ls-files lib/\*\*/\*.rb`.strip.split)
|
113
119
|
cp "contrib/rdoc.css", "doc/rdoc.css"
|
114
120
|
end
|
115
121
|
|
116
|
-
task :
|
122
|
+
task pushdoc: :rdoc do
|
117
123
|
sh "rsync -avz doc/ rack.rubyforge.org:/var/www/gforge-projects/rack/doc/"
|
118
124
|
end
|
119
125
|
|
120
|
-
task :
|
126
|
+
task pushsite: :pushdoc do
|
121
127
|
sh "cd site && git gc"
|
122
128
|
sh "rsync -avz site/ rack.rubyforge.org:/var/www/gforge-projects/rack/"
|
123
129
|
sh "cd site && git push"
|
data/{SPEC → SPEC.rdoc}
RENAMED
@@ -1,5 +1,6 @@
|
|
1
1
|
This specification aims to formalize the Rack protocol. You
|
2
2
|
can (and should) use Rack::Lint to enforce it.
|
3
|
+
|
3
4
|
When you develop middleware, be sure to add a Lint before and
|
4
5
|
after to catch all mistakes.
|
5
6
|
= Rack applications
|
@@ -11,9 +12,10 @@ The *status*,
|
|
11
12
|
the *headers*,
|
12
13
|
and the *body*.
|
13
14
|
== The Environment
|
14
|
-
The environment must be an instance of Hash that includes
|
15
|
+
The environment must be an unfrozen instance of Hash that includes
|
15
16
|
CGI-like headers. The application is free to modify the
|
16
17
|
environment.
|
18
|
+
|
17
19
|
The environment is required to include these variables
|
18
20
|
(adopted from PEP333), except when they'd be empty, but see
|
19
21
|
below.
|
@@ -35,22 +37,23 @@ below.
|
|
35
37
|
empty string, if the request URL targets
|
36
38
|
the application root and does not have a
|
37
39
|
trailing slash. This value may be
|
38
|
-
percent-encoded when
|
40
|
+
percent-encoded when originating from
|
39
41
|
a URL.
|
40
42
|
<tt>QUERY_STRING</tt>:: The portion of the request URL that
|
41
43
|
follows the <tt>?</tt>, if any. May be
|
42
44
|
empty, but is always required!
|
43
|
-
<tt>SERVER_NAME</tt
|
44
|
-
When combined with <tt>SCRIPT_NAME</tt> and
|
45
|
+
<tt>SERVER_NAME</tt>:: When combined with <tt>SCRIPT_NAME</tt> and
|
45
46
|
<tt>PATH_INFO</tt>, these variables can be
|
46
47
|
used to complete the URL. Note, however,
|
47
48
|
that <tt>HTTP_HOST</tt>, if present,
|
48
49
|
should be used in preference to
|
49
50
|
<tt>SERVER_NAME</tt> for reconstructing
|
50
51
|
the request URL.
|
51
|
-
<tt>SERVER_NAME</tt>
|
52
|
-
|
53
|
-
|
52
|
+
<tt>SERVER_NAME</tt> can never be an empty
|
53
|
+
string, and so is always required.
|
54
|
+
<tt>SERVER_PORT</tt>:: An optional +Integer+ which is the port the
|
55
|
+
server is running on. Should be specified if
|
56
|
+
the server is running on a non-standard port.
|
54
57
|
<tt>HTTP_</tt> Variables:: Variables corresponding to the
|
55
58
|
client-supplied HTTP request
|
56
59
|
headers (i.e., variables whose
|
@@ -60,9 +63,8 @@ below.
|
|
60
63
|
the presence or absence of the
|
61
64
|
appropriate HTTP header in the
|
62
65
|
request. See
|
63
|
-
|
64
|
-
|
65
|
-
specific behavior.
|
66
|
+
{RFC3875 section 4.1.18}[https://tools.ietf.org/html/rfc3875#section-4.1.18]
|
67
|
+
for specific behavior.
|
66
68
|
In addition to this, the Rack environment must include these
|
67
69
|
Rack-specific variables:
|
68
70
|
<tt>rack.version</tt>:: The Array representing this version of Rack
|
@@ -105,6 +107,7 @@ be implemented by the server.
|
|
105
107
|
fetch(key, default = nil) (aliased as []);
|
106
108
|
delete(key);
|
107
109
|
clear;
|
110
|
+
to_hash (returning unfrozen Hash instance);
|
108
111
|
<tt>rack.logger</tt>:: A common object interface for logging messages.
|
109
112
|
The object must implement:
|
110
113
|
info(message, &block)
|
@@ -119,10 +122,16 @@ environment, too. The keys must contain at least one dot,
|
|
119
122
|
and should be prefixed uniquely. The prefix <tt>rack.</tt>
|
120
123
|
is reserved for use with the Rack core distribution and other
|
121
124
|
accepted specifications and must not be used otherwise.
|
125
|
+
|
126
|
+
The <tt>SERVER_PORT</tt> must be an Integer if set.
|
127
|
+
The <tt>SERVER_NAME</tt> must be a valid authority as defined by RFC7540.
|
128
|
+
The <tt>HTTP_HOST</tt> must be a valid authority as defined by RFC7540.
|
122
129
|
The environment must not contain the keys
|
123
130
|
<tt>HTTP_CONTENT_TYPE</tt> or <tt>HTTP_CONTENT_LENGTH</tt>
|
124
131
|
(use the versions without <tt>HTTP_</tt>).
|
125
132
|
The CGI keys (named without a period) must have String values.
|
133
|
+
If the string values for CGI keys contain non-ASCII characters,
|
134
|
+
they should use ASCII-8BIT encoding.
|
126
135
|
There are the following restrictions:
|
127
136
|
* <tt>rack.version</tt> must be an array of Integers.
|
128
137
|
* <tt>rack.url_scheme</tt> must either be +http+ or +https+.
|
@@ -138,6 +147,7 @@ There are the following restrictions:
|
|
138
147
|
<tt>SCRIPT_NAME</tt> is empty.
|
139
148
|
<tt>SCRIPT_NAME</tt> never should be <tt>/</tt>, but instead be empty.
|
140
149
|
=== The Input Stream
|
150
|
+
|
141
151
|
The input stream is an IO-like object which contains the raw HTTP
|
142
152
|
POST data.
|
143
153
|
When applicable, its external encoding must be "ASCII-8BIT" and it
|
@@ -147,14 +157,19 @@ The input stream must respond to +gets+, +each+, +read+ and +rewind+.
|
|
147
157
|
or +nil+ on EOF.
|
148
158
|
* +read+ behaves like IO#read.
|
149
159
|
Its signature is <tt>read([length, [buffer]])</tt>.
|
160
|
+
|
150
161
|
If given, +length+ must be a non-negative Integer (>= 0) or +nil+,
|
151
162
|
and +buffer+ must be a String and may not be nil.
|
163
|
+
|
152
164
|
If +length+ is given and not nil, then this method reads at most
|
153
165
|
+length+ bytes from the input stream.
|
166
|
+
|
154
167
|
If +length+ is not given or nil, then this method reads
|
155
168
|
all data until EOF.
|
169
|
+
|
156
170
|
When EOF is reached, this method returns nil if +length+ is given
|
157
171
|
and not nil, or "" if +length+ is not given or is nil.
|
172
|
+
|
158
173
|
If +buffer+ is given, then the read data will be placed
|
159
174
|
into +buffer+ instead of a newly created String object.
|
160
175
|
* +each+ must be called without arguments and only yield Strings.
|
@@ -176,16 +191,20 @@ The error stream must respond to +puts+, +write+ and +flush+.
|
|
176
191
|
If rack.hijack? is true then rack.hijack must respond to #call.
|
177
192
|
rack.hijack must return the io that will also be assigned (or is
|
178
193
|
already present, in rack.hijack_io.
|
194
|
+
|
179
195
|
rack.hijack_io must respond to:
|
180
196
|
<tt>read, write, read_nonblock, write_nonblock, flush, close,
|
181
197
|
close_read, close_write, closed?</tt>
|
198
|
+
|
182
199
|
The semantics of these IO methods must be a best effort match to
|
183
200
|
those of a normal ruby IO or Socket object, using standard
|
184
201
|
arguments and raising standard exceptions. Servers are encouraged
|
185
202
|
to simply pass on real IO objects, although it is recognized that
|
186
203
|
this approach is not directly compatible with SPDY and HTTP 2.0.
|
204
|
+
|
187
205
|
IO provided in rack.hijack_io should preference the
|
188
206
|
IO::WaitReadable and IO::WaitWritable APIs wherever supported.
|
207
|
+
|
189
208
|
There is a deliberate lack of full specification around
|
190
209
|
rack.hijack_io, as semantics will change from server to server.
|
191
210
|
Users are encouraged to utilize this API with a knowledge of their
|
@@ -193,7 +212,9 @@ server choice, and servers may extend the functionality of
|
|
193
212
|
hijack_io to provide additional features to users. The purpose of
|
194
213
|
rack.hijack is for Rack to "get out of the way", as such, Rack only
|
195
214
|
provides the minimum of specification and support.
|
215
|
+
|
196
216
|
If rack.hijack? is false, then rack.hijack should not be set.
|
217
|
+
|
197
218
|
If rack.hijack? is false, then rack.hijack_io should not be set.
|
198
219
|
==== Response (after headers)
|
199
220
|
It is also possible to hijack a response after the status and headers
|
@@ -202,6 +223,7 @@ In order to do this, an application may set the special header
|
|
202
223
|
<tt>rack.hijack</tt> to an object that responds to <tt>call</tt>
|
203
224
|
accepting an argument that conforms to the <tt>rack.hijack_io</tt>
|
204
225
|
protocol.
|
226
|
+
|
205
227
|
After the headers have been sent, and this hijack callback has been
|
206
228
|
called, the application is now responsible for the remaining lifecycle
|
207
229
|
of the IO. The application is also responsible for maintaining HTTP
|
@@ -210,8 +232,10 @@ applications will have wanted to specify the header Connection:close in
|
|
210
232
|
HTTP/1.1, and not Connection:keep-alive, as there is no protocol for
|
211
233
|
returning hijacked sockets to the web server. For that purpose, use the
|
212
234
|
body streaming API instead (progressively yielding strings via each).
|
235
|
+
|
213
236
|
Servers must ignore the <tt>body</tt> part of the response tuple when
|
214
237
|
the <tt>rack.hijack</tt> response API is in use.
|
238
|
+
|
215
239
|
The special response header <tt>rack.hijack</tt> must only be set
|
216
240
|
if the request env has <tt>rack.hijack?</tt> <tt>true</tt>.
|
217
241
|
==== Conventions
|
@@ -226,9 +250,9 @@ This is an HTTP status. When parsed as integer (+to_i+), it must be
|
|
226
250
|
greater than or equal to 100.
|
227
251
|
=== The Headers
|
228
252
|
The header must respond to +each+, and yield values of key and value.
|
253
|
+
The header keys must be Strings.
|
229
254
|
Special headers starting "rack." are for communicating with the
|
230
255
|
server, and must not be sent back to the client.
|
231
|
-
The header keys must be Strings.
|
232
256
|
The header must not contain a +Status+ key.
|
233
257
|
The header must conform to RFC7230 token specification, i.e. cannot
|
234
258
|
contain non-printable ASCII, DQUOTE or "(),/:;<=>?@[\]{}".
|
@@ -238,23 +262,27 @@ consisting of lines (for multiple header values, e.g. multiple
|
|
238
262
|
The lines must not contain characters below 037.
|
239
263
|
=== The Content-Type
|
240
264
|
There must not be a <tt>Content-Type</tt>, when the +Status+ is 1xx,
|
241
|
-
204
|
265
|
+
204 or 304.
|
242
266
|
=== The Content-Length
|
243
267
|
There must not be a <tt>Content-Length</tt> header when the
|
244
|
-
+Status+ is 1xx, 204
|
268
|
+
+Status+ is 1xx, 204 or 304.
|
245
269
|
=== The Body
|
246
270
|
The Body must respond to +each+
|
247
271
|
and must only yield String values.
|
272
|
+
|
248
273
|
The Body itself should not be an instance of String, as this will
|
249
274
|
break in Ruby 1.9.
|
275
|
+
|
250
276
|
If the Body responds to +close+, it will be called after iteration. If
|
251
277
|
the body is replaced by a middleware after action, the original body
|
252
278
|
must be closed first, if it responds to close.
|
279
|
+
|
253
280
|
If the Body responds to +to_path+, it must return a String
|
254
281
|
identifying the location of a file whose contents are identical
|
255
282
|
to that produced by calling +each+; this may be used by the
|
256
283
|
server as an alternative, possibly more efficient way to
|
257
284
|
transport the response.
|
285
|
+
|
258
286
|
The Body commonly is an Array of Strings, the application
|
259
287
|
instance itself, or a File-like object.
|
260
288
|
== Thanks
|