rack 2.2.14 → 3.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of rack might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +163 -114
- data/CONTRIBUTING.md +53 -47
- data/MIT-LICENSE +1 -1
- data/README.md +293 -0
- data/SPEC.rdoc +174 -126
- data/lib/rack/auth/abstract/handler.rb +3 -1
- data/lib/rack/auth/abstract/request.rb +3 -1
- data/lib/rack/auth/basic.rb +2 -3
- data/lib/rack/auth/digest/md5.rb +1 -131
- data/lib/rack/auth/digest/nonce.rb +1 -53
- data/lib/rack/auth/digest/params.rb +1 -54
- data/lib/rack/auth/digest/request.rb +1 -43
- data/lib/rack/auth/digest.rb +256 -0
- data/lib/rack/body_proxy.rb +3 -1
- data/lib/rack/builder.rb +83 -63
- data/lib/rack/cascade.rb +2 -0
- data/lib/rack/chunked.rb +16 -13
- data/lib/rack/common_logger.rb +24 -20
- data/lib/rack/conditional_get.rb +18 -15
- data/lib/rack/constants.rb +63 -0
- data/lib/rack/content_length.rb +12 -16
- data/lib/rack/content_type.rb +8 -5
- data/lib/rack/deflater.rb +40 -26
- data/lib/rack/directory.rb +9 -3
- data/lib/rack/etag.rb +14 -23
- data/lib/rack/events.rb +4 -0
- data/lib/rack/file.rb +2 -0
- data/lib/rack/files.rb +15 -17
- data/lib/rack/head.rb +9 -8
- data/lib/rack/headers.rb +154 -0
- data/lib/rack/lint.rb +758 -646
- data/lib/rack/lock.rb +2 -5
- data/lib/rack/logger.rb +2 -0
- data/lib/rack/media_type.rb +4 -9
- data/lib/rack/method_override.rb +6 -2
- data/lib/rack/mime.rb +8 -0
- data/lib/rack/mock.rb +1 -271
- data/lib/rack/mock_request.rb +166 -0
- data/lib/rack/mock_response.rb +126 -0
- data/lib/rack/multipart/generator.rb +7 -5
- data/lib/rack/multipart/parser.rb +123 -85
- data/lib/rack/multipart/uploaded_file.rb +4 -0
- data/lib/rack/multipart.rb +20 -40
- data/lib/rack/null_logger.rb +9 -0
- data/lib/rack/query_parser.rb +78 -89
- data/lib/rack/recursive.rb +2 -0
- data/lib/rack/reloader.rb +0 -2
- data/lib/rack/request.rb +189 -91
- data/lib/rack/response.rb +136 -61
- data/lib/rack/rewindable_input.rb +24 -5
- data/lib/rack/runtime.rb +7 -6
- data/lib/rack/sendfile.rb +31 -26
- data/lib/rack/show_exceptions.rb +15 -2
- data/lib/rack/show_status.rb +17 -7
- data/lib/rack/static.rb +9 -10
- data/lib/rack/tempfile_reaper.rb +15 -4
- data/lib/rack/urlmap.rb +3 -1
- data/lib/rack/utils.rb +215 -205
- data/lib/rack/version.rb +9 -4
- data/lib/rack.rb +5 -76
- metadata +15 -35
- data/README.rdoc +0 -347
- data/Rakefile +0 -130
- data/bin/rackup +0 -5
- data/contrib/rack.png +0 -0
- data/contrib/rack.svg +0 -150
- data/contrib/rack_logo.svg +0 -164
- data/contrib/rdoc.css +0 -412
- data/example/lobster.ru +0 -6
- data/example/protectedlobster.rb +0 -16
- data/example/protectedlobster.ru +0 -10
- data/lib/rack/core_ext/regexp.rb +0 -14
- data/lib/rack/handler/cgi.rb +0 -59
- data/lib/rack/handler/fastcgi.rb +0 -100
- data/lib/rack/handler/lsws.rb +0 -61
- data/lib/rack/handler/scgi.rb +0 -71
- data/lib/rack/handler/thin.rb +0 -36
- data/lib/rack/handler/webrick.rb +0 -129
- data/lib/rack/handler.rb +0 -104
- data/lib/rack/lobster.rb +0 -70
- data/lib/rack/server.rb +0 -466
- data/lib/rack/session/abstract/id.rb +0 -523
- data/lib/rack/session/cookie.rb +0 -203
- data/lib/rack/session/memcache.rb +0 -10
- data/lib/rack/session/pool.rb +0 -90
- data/rack.gemspec +0 -46
data/contrib/rdoc.css
DELETED
@@ -1,412 +0,0 @@
|
|
1
|
-
/* Forked from the Darkfish templates rdoc.css file, much hacked, probably
|
2
|
-
* imperfect */
|
3
|
-
|
4
|
-
html { max-width: 960px; margin: 0 auto; }
|
5
|
-
body {
|
6
|
-
font: 14px "Helvetica Neue", Helvetica, Tahoma, sans-serif;
|
7
|
-
}
|
8
|
-
body.file-popup {
|
9
|
-
font-size: 90%;
|
10
|
-
margin-left: 0;
|
11
|
-
}
|
12
|
-
|
13
|
-
h1 {
|
14
|
-
color: #4183C4;
|
15
|
-
}
|
16
|
-
|
17
|
-
:link,
|
18
|
-
:visited {
|
19
|
-
color: #4183C4;
|
20
|
-
text-decoration: none;
|
21
|
-
}
|
22
|
-
:link:hover,
|
23
|
-
:visited:hover {
|
24
|
-
border-bottom: 1px dotted #4183C4;
|
25
|
-
}
|
26
|
-
|
27
|
-
pre, pre.description {
|
28
|
-
font: 12px Monaco,"Courier New","DejaVu Sans Mono","Bitstream Vera Sans Mono",monospace;
|
29
|
-
padding: 1em;
|
30
|
-
overflow: auto;
|
31
|
-
line-height: 1.4;
|
32
|
-
}
|
33
|
-
|
34
|
-
/* @group Generic Classes */
|
35
|
-
|
36
|
-
.initially-hidden {
|
37
|
-
display: none;
|
38
|
-
}
|
39
|
-
|
40
|
-
#search-field {
|
41
|
-
width: 98%;
|
42
|
-
}
|
43
|
-
|
44
|
-
.missing-docs {
|
45
|
-
font-size: 120%;
|
46
|
-
background: white url(images/wrench_orange.png) no-repeat 4px center;
|
47
|
-
color: #ccc;
|
48
|
-
line-height: 2em;
|
49
|
-
border: 1px solid #d00;
|
50
|
-
opacity: 1;
|
51
|
-
text-indent: 24px;
|
52
|
-
letter-spacing: 3px;
|
53
|
-
font-weight: bold;
|
54
|
-
-webkit-border-radius: 5px;
|
55
|
-
-moz-border-radius: 5px;
|
56
|
-
}
|
57
|
-
|
58
|
-
.target-section {
|
59
|
-
border: 2px solid #dcce90;
|
60
|
-
border-left-width: 8px;
|
61
|
-
background: #fff3c2;
|
62
|
-
}
|
63
|
-
|
64
|
-
/* @end */
|
65
|
-
|
66
|
-
/* @group Index Page, Standalone file pages */
|
67
|
-
.indexpage ul {
|
68
|
-
line-height: 160%;
|
69
|
-
list-style: none;
|
70
|
-
}
|
71
|
-
.indexpage ul :link,
|
72
|
-
.indexpage ul :visited {
|
73
|
-
font-size: 16px;
|
74
|
-
}
|
75
|
-
|
76
|
-
.indexpage li {
|
77
|
-
padding-left: 20px;
|
78
|
-
}
|
79
|
-
|
80
|
-
.indexpage ul > li {
|
81
|
-
background: url(images/bullet_black.png) no-repeat left 4px;
|
82
|
-
}
|
83
|
-
.indexpage li.method {
|
84
|
-
background: url(images/plugin.png) no-repeat left 4px;
|
85
|
-
}
|
86
|
-
.indexpage li.module {
|
87
|
-
background: url(images/package.png) no-repeat left 4px;
|
88
|
-
}
|
89
|
-
.indexpage li.class {
|
90
|
-
background: url(images/ruby.png) no-repeat left 4px;
|
91
|
-
}
|
92
|
-
.indexpage li.file {
|
93
|
-
background: url(images/page_white_text.png) no-repeat left 4px;
|
94
|
-
}
|
95
|
-
.indexpage li li {
|
96
|
-
background: url(images/tag_blue.png) no-repeat left 4px;
|
97
|
-
}
|
98
|
-
.indexpage li .toc-toggle {
|
99
|
-
width: 16px;
|
100
|
-
height: 16px;
|
101
|
-
background: url(images/add.png) no-repeat;
|
102
|
-
}
|
103
|
-
|
104
|
-
.indexpage li .toc-toggle.open {
|
105
|
-
background: url(images/delete.png) no-repeat;
|
106
|
-
}
|
107
|
-
|
108
|
-
/* @end */
|
109
|
-
|
110
|
-
/* @group Top-Level Structure */
|
111
|
-
|
112
|
-
.project-section, #file-metadata, #class-metadata {
|
113
|
-
display: block;
|
114
|
-
background: #f5f5f5;
|
115
|
-
margin-bottom: 1em;
|
116
|
-
padding: 0.5em;
|
117
|
-
}
|
118
|
-
.project-section h3, #file-metadata h3, #class-metadata h3 {
|
119
|
-
margin: 0;
|
120
|
-
}
|
121
|
-
|
122
|
-
#metadata {
|
123
|
-
float: left;
|
124
|
-
width: 280px;
|
125
|
-
}
|
126
|
-
|
127
|
-
#documentation {
|
128
|
-
margin: 2em 1em 2em 300px;
|
129
|
-
}
|
130
|
-
|
131
|
-
#validator-badges {
|
132
|
-
clear: both;
|
133
|
-
margin: 1em 1em 2em;
|
134
|
-
font-size: smaller;
|
135
|
-
}
|
136
|
-
|
137
|
-
/* @end */
|
138
|
-
|
139
|
-
/* @group Metadata Section */
|
140
|
-
|
141
|
-
#metadata ul,
|
142
|
-
#metadata dl,
|
143
|
-
#metadata p {
|
144
|
-
padding: 0px;
|
145
|
-
list-style: none;
|
146
|
-
}
|
147
|
-
|
148
|
-
dl.svninfo {
|
149
|
-
color: #666;
|
150
|
-
margin: 0;
|
151
|
-
}
|
152
|
-
dl.svninfo dt {
|
153
|
-
font-weight: bold;
|
154
|
-
}
|
155
|
-
|
156
|
-
ul.link-list li {
|
157
|
-
white-space: nowrap;
|
158
|
-
}
|
159
|
-
ul.link-list .type {
|
160
|
-
font-size: 8px;
|
161
|
-
text-transform: uppercase;
|
162
|
-
color: white;
|
163
|
-
background: #969696;
|
164
|
-
}
|
165
|
-
|
166
|
-
/* @end */
|
167
|
-
|
168
|
-
/* @group Documentation Section */
|
169
|
-
|
170
|
-
.note-list {
|
171
|
-
margin: 8px 0;
|
172
|
-
}
|
173
|
-
|
174
|
-
.label-list {
|
175
|
-
margin: 8px 1.5em;
|
176
|
-
border: 1px solid #ccc;
|
177
|
-
}
|
178
|
-
.description .label-list {
|
179
|
-
font-size: 14px;
|
180
|
-
}
|
181
|
-
|
182
|
-
.note-list dt {
|
183
|
-
font-weight: bold;
|
184
|
-
}
|
185
|
-
.note-list dd {
|
186
|
-
}
|
187
|
-
|
188
|
-
.label-list dt {
|
189
|
-
font-weight: bold;
|
190
|
-
background: #ddd;
|
191
|
-
}
|
192
|
-
.label-list dd {
|
193
|
-
}
|
194
|
-
.label-list dd + dt,
|
195
|
-
.note-list dd + dt {
|
196
|
-
margin-top: 0.7em;
|
197
|
-
}
|
198
|
-
|
199
|
-
#documentation .section {
|
200
|
-
font-size: 90%;
|
201
|
-
}
|
202
|
-
|
203
|
-
#documentation h2.section-header {
|
204
|
-
color: #333;
|
205
|
-
font-size: 175%;
|
206
|
-
}
|
207
|
-
|
208
|
-
.documentation-section-title {
|
209
|
-
position: relative;
|
210
|
-
}
|
211
|
-
.documentation-section-title .section-click-top {
|
212
|
-
position: absolute;
|
213
|
-
top: 6px;
|
214
|
-
right: 12px;
|
215
|
-
font-size: 10px;
|
216
|
-
visibility: hidden;
|
217
|
-
}
|
218
|
-
|
219
|
-
.documentation-section-title:hover .section-click-top {
|
220
|
-
visibility: visible;
|
221
|
-
}
|
222
|
-
|
223
|
-
#documentation h3.section-header {
|
224
|
-
color: #333;
|
225
|
-
font-size: 150%;
|
226
|
-
}
|
227
|
-
|
228
|
-
#constants-list > dl,
|
229
|
-
#attributes-list > dl {
|
230
|
-
margin: 1em 0 2em;
|
231
|
-
border: 0;
|
232
|
-
}
|
233
|
-
#constants-list > dl dt,
|
234
|
-
#attributes-list > dl dt {
|
235
|
-
font-weight: bold;
|
236
|
-
font-family: Monaco, "Andale Mono";
|
237
|
-
background: inherit;
|
238
|
-
}
|
239
|
-
#constants-list > dl dt a,
|
240
|
-
#attributes-list > dl dt a {
|
241
|
-
color: inherit;
|
242
|
-
}
|
243
|
-
#constants-list > dl dd,
|
244
|
-
#attributes-list > dl dd {
|
245
|
-
margin: 0 0 1em 0;
|
246
|
-
color: #666;
|
247
|
-
}
|
248
|
-
|
249
|
-
.documentation-section h2 {
|
250
|
-
position: relative;
|
251
|
-
}
|
252
|
-
|
253
|
-
.documentation-section h2 a {
|
254
|
-
position: absolute;
|
255
|
-
top: 8px;
|
256
|
-
right: 10px;
|
257
|
-
font-size: 12px;
|
258
|
-
color: #9b9877;
|
259
|
-
visibility: hidden;
|
260
|
-
}
|
261
|
-
|
262
|
-
.documentation-section h2:hover a {
|
263
|
-
visibility: visible;
|
264
|
-
}
|
265
|
-
|
266
|
-
/* @group Method Details */
|
267
|
-
|
268
|
-
#documentation .method-source-code {
|
269
|
-
display: none;
|
270
|
-
}
|
271
|
-
|
272
|
-
#documentation .method-detail {
|
273
|
-
margin: 0.2em 0.2em;
|
274
|
-
padding: 0.5em;
|
275
|
-
}
|
276
|
-
#documentation .method-detail:hover {
|
277
|
-
background-color: #f5f5f5;
|
278
|
-
}
|
279
|
-
#documentation .method-heading {
|
280
|
-
cursor: pointer;
|
281
|
-
position: relative;
|
282
|
-
font-size: 125%;
|
283
|
-
line-height: 125%;
|
284
|
-
font-weight: bold;
|
285
|
-
color: #333;
|
286
|
-
background: url(images/brick.png) no-repeat left bottom;
|
287
|
-
padding-left: 20px;
|
288
|
-
}
|
289
|
-
#documentation .method-heading :link,
|
290
|
-
#documentation .method-heading :visited {
|
291
|
-
color: inherit;
|
292
|
-
}
|
293
|
-
#documentation .method-click-advice {
|
294
|
-
position: absolute;
|
295
|
-
right: 5px;
|
296
|
-
font-size: 10px;
|
297
|
-
color: #aaa;
|
298
|
-
visibility: hidden;
|
299
|
-
background: url(images/zoom.png) no-repeat right 5px;
|
300
|
-
padding-right: 20px;
|
301
|
-
overflow: show;
|
302
|
-
}
|
303
|
-
#documentation .method-heading:hover .method-click-advice {
|
304
|
-
visibility: visible;
|
305
|
-
}
|
306
|
-
|
307
|
-
#documentation .method-alias .method-heading {
|
308
|
-
color: #666;
|
309
|
-
background: url(images/brick_link.png) no-repeat left bottom;
|
310
|
-
}
|
311
|
-
|
312
|
-
#documentation .method-description,
|
313
|
-
#documentation .aliases {
|
314
|
-
margin: 0 20px;
|
315
|
-
color: #666;
|
316
|
-
}
|
317
|
-
|
318
|
-
#documentation .method-description p,
|
319
|
-
#documentation .aliases p {
|
320
|
-
line-height: 1.2em;
|
321
|
-
}
|
322
|
-
|
323
|
-
#documentation .aliases {
|
324
|
-
font-style: italic;
|
325
|
-
cursor: default;
|
326
|
-
}
|
327
|
-
#documentation .method-description p {
|
328
|
-
margin-bottom: 0.5em;
|
329
|
-
}
|
330
|
-
#documentation .method-description ul {
|
331
|
-
margin-left: 1.5em;
|
332
|
-
}
|
333
|
-
|
334
|
-
#documentation .attribute-method-heading {
|
335
|
-
background: url(images/tag_green.png) no-repeat left bottom;
|
336
|
-
}
|
337
|
-
#documentation #attribute-method-details .method-detail:hover {
|
338
|
-
background-color: transparent;
|
339
|
-
cursor: default;
|
340
|
-
}
|
341
|
-
#documentation .attribute-access-type {
|
342
|
-
font-size: 60%;
|
343
|
-
text-transform: uppercase;
|
344
|
-
vertical-align: super;
|
345
|
-
}
|
346
|
-
|
347
|
-
.method-section .method-source-code {
|
348
|
-
background: white;
|
349
|
-
}
|
350
|
-
|
351
|
-
/* @group Source Code */
|
352
|
-
|
353
|
-
.ruby-constant .ruby-keyword .ruby-ivar .ruby-operator .ruby-identifier
|
354
|
-
.ruby-node .ruby-comment .ruby-regexp .ruby-value {
|
355
|
-
background: transparent;
|
356
|
-
}
|
357
|
-
|
358
|
-
/* Thanks GitHub!!! */
|
359
|
-
.ruby-constant { color: #458; font-weight: bold; }
|
360
|
-
.ruby-keyword { color: black; font-weight: bold; }
|
361
|
-
.ruby-ivar { color: teal; }
|
362
|
-
.ruby-operator { color: #000; }
|
363
|
-
.ruby-identifier { color: black; }
|
364
|
-
.ruby-node { color: red; }
|
365
|
-
.ruby-comment { color: #998; font-weight: bold; }
|
366
|
-
.ruby-regexp { color: #009926; }
|
367
|
-
.ruby-value { color: #099; }
|
368
|
-
.ruby-string { color: red; }
|
369
|
-
|
370
|
-
/* @group search results */
|
371
|
-
|
372
|
-
#search-section .section-header {
|
373
|
-
margin: 0;
|
374
|
-
padding: 0;
|
375
|
-
}
|
376
|
-
|
377
|
-
#search-results {
|
378
|
-
width: 100%;
|
379
|
-
list-style: none;
|
380
|
-
margin: 0;
|
381
|
-
padding: 0;
|
382
|
-
}
|
383
|
-
|
384
|
-
#search-results h1 {
|
385
|
-
font-size: 1em;
|
386
|
-
font-weight: normal;
|
387
|
-
text-shadow: none;
|
388
|
-
}
|
389
|
-
|
390
|
-
#search-results .current {
|
391
|
-
background: #eee;
|
392
|
-
}
|
393
|
-
|
394
|
-
#search-results li {
|
395
|
-
list-style: none;
|
396
|
-
line-height: 1em;
|
397
|
-
padding: 0.5em;
|
398
|
-
border-bottom: 1px solid black;
|
399
|
-
}
|
400
|
-
|
401
|
-
#search-results .search-namespace {
|
402
|
-
font-weight: bold;
|
403
|
-
}
|
404
|
-
|
405
|
-
#search-results li em {
|
406
|
-
background: yellow;
|
407
|
-
font-style: normal;
|
408
|
-
}
|
409
|
-
|
410
|
-
#search-results pre {
|
411
|
-
margin: 0.5em;
|
412
|
-
}
|
data/example/lobster.ru
DELETED
data/example/protectedlobster.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rack'
|
4
|
-
require 'rack/lobster'
|
5
|
-
|
6
|
-
lobster = Rack::Lobster.new
|
7
|
-
|
8
|
-
protected_lobster = Rack::Auth::Basic.new(lobster) do |username, password|
|
9
|
-
Rack::Utils.secure_compare('secret', password)
|
10
|
-
end
|
11
|
-
|
12
|
-
protected_lobster.realm = 'Lobster 2.0'
|
13
|
-
|
14
|
-
pretty_protected_lobster = Rack::ShowStatus.new(Rack::ShowExceptions.new(protected_lobster))
|
15
|
-
|
16
|
-
Rack::Server.start app: pretty_protected_lobster, Port: 9292
|
data/example/protectedlobster.ru
DELETED
data/lib/rack/core_ext/regexp.rb
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Regexp has `match?` since Ruby 2.4
|
4
|
-
# so to support Ruby < 2.4 we need to define this method
|
5
|
-
|
6
|
-
module Rack
|
7
|
-
module RegexpExtensions
|
8
|
-
refine Regexp do
|
9
|
-
def match?(string, pos = 0)
|
10
|
-
!!match(string, pos)
|
11
|
-
end
|
12
|
-
end unless //.respond_to?(:match?)
|
13
|
-
end
|
14
|
-
end
|
data/lib/rack/handler/cgi.rb
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Rack
|
4
|
-
module Handler
|
5
|
-
class CGI
|
6
|
-
def self.run(app, **options)
|
7
|
-
$stdin.binmode
|
8
|
-
serve app
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.serve(app)
|
12
|
-
env = ENV.to_hash
|
13
|
-
env.delete "HTTP_CONTENT_LENGTH"
|
14
|
-
|
15
|
-
env[SCRIPT_NAME] = "" if env[SCRIPT_NAME] == "/"
|
16
|
-
|
17
|
-
env.update(
|
18
|
-
RACK_VERSION => Rack::VERSION,
|
19
|
-
RACK_INPUT => Rack::RewindableInput.new($stdin),
|
20
|
-
RACK_ERRORS => $stderr,
|
21
|
-
RACK_MULTITHREAD => false,
|
22
|
-
RACK_MULTIPROCESS => true,
|
23
|
-
RACK_RUNONCE => true,
|
24
|
-
RACK_URL_SCHEME => ["yes", "on", "1"].include?(ENV[HTTPS]) ? "https" : "http"
|
25
|
-
)
|
26
|
-
|
27
|
-
env[QUERY_STRING] ||= ""
|
28
|
-
env[HTTP_VERSION] ||= env[SERVER_PROTOCOL]
|
29
|
-
env[REQUEST_PATH] ||= "/"
|
30
|
-
|
31
|
-
status, headers, body = app.call(env)
|
32
|
-
begin
|
33
|
-
send_headers status, headers
|
34
|
-
send_body body
|
35
|
-
ensure
|
36
|
-
body.close if body.respond_to? :close
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def self.send_headers(status, headers)
|
41
|
-
$stdout.print "Status: #{status}\r\n"
|
42
|
-
headers.each { |k, vs|
|
43
|
-
vs.split("\n").each { |v|
|
44
|
-
$stdout.print "#{k}: #{v}\r\n"
|
45
|
-
}
|
46
|
-
}
|
47
|
-
$stdout.print "\r\n"
|
48
|
-
$stdout.flush
|
49
|
-
end
|
50
|
-
|
51
|
-
def self.send_body(body)
|
52
|
-
body.each { |part|
|
53
|
-
$stdout.print part
|
54
|
-
$stdout.flush
|
55
|
-
}
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
data/lib/rack/handler/fastcgi.rb
DELETED
@@ -1,100 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'fcgi'
|
4
|
-
require 'socket'
|
5
|
-
|
6
|
-
if defined? FCGI::Stream
|
7
|
-
class FCGI::Stream
|
8
|
-
alias _rack_read_without_buffer read
|
9
|
-
|
10
|
-
def read(n, buffer = nil)
|
11
|
-
buf = _rack_read_without_buffer n
|
12
|
-
buffer.replace(buf.to_s) if buffer
|
13
|
-
buf
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
module Rack
|
19
|
-
module Handler
|
20
|
-
class FastCGI
|
21
|
-
def self.run(app, **options)
|
22
|
-
if options[:File]
|
23
|
-
STDIN.reopen(UNIXServer.new(options[:File]))
|
24
|
-
elsif options[:Port]
|
25
|
-
STDIN.reopen(TCPServer.new(options[:Host], options[:Port]))
|
26
|
-
end
|
27
|
-
FCGI.each { |request|
|
28
|
-
serve request, app
|
29
|
-
}
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.valid_options
|
33
|
-
environment = ENV['RACK_ENV'] || 'development'
|
34
|
-
default_host = environment == 'development' ? 'localhost' : '0.0.0.0'
|
35
|
-
|
36
|
-
{
|
37
|
-
"Host=HOST" => "Hostname to listen on (default: #{default_host})",
|
38
|
-
"Port=PORT" => "Port to listen on (default: 8080)",
|
39
|
-
"File=PATH" => "Creates a Domain socket at PATH instead of a TCP socket. Ignores Host and Port if set.",
|
40
|
-
}
|
41
|
-
end
|
42
|
-
|
43
|
-
def self.serve(request, app)
|
44
|
-
env = request.env
|
45
|
-
env.delete "HTTP_CONTENT_LENGTH"
|
46
|
-
|
47
|
-
env[SCRIPT_NAME] = "" if env[SCRIPT_NAME] == "/"
|
48
|
-
|
49
|
-
rack_input = RewindableInput.new(request.in)
|
50
|
-
|
51
|
-
env.update(
|
52
|
-
RACK_VERSION => Rack::VERSION,
|
53
|
-
RACK_INPUT => rack_input,
|
54
|
-
RACK_ERRORS => request.err,
|
55
|
-
RACK_MULTITHREAD => false,
|
56
|
-
RACK_MULTIPROCESS => true,
|
57
|
-
RACK_RUNONCE => false,
|
58
|
-
RACK_URL_SCHEME => ["yes", "on", "1"].include?(env[HTTPS]) ? "https" : "http"
|
59
|
-
)
|
60
|
-
|
61
|
-
env[QUERY_STRING] ||= ""
|
62
|
-
env[HTTP_VERSION] ||= env[SERVER_PROTOCOL]
|
63
|
-
env[REQUEST_PATH] ||= "/"
|
64
|
-
env.delete "CONTENT_TYPE" if env["CONTENT_TYPE"] == ""
|
65
|
-
env.delete "CONTENT_LENGTH" if env["CONTENT_LENGTH"] == ""
|
66
|
-
|
67
|
-
begin
|
68
|
-
status, headers, body = app.call(env)
|
69
|
-
begin
|
70
|
-
send_headers request.out, status, headers
|
71
|
-
send_body request.out, body
|
72
|
-
ensure
|
73
|
-
body.close if body.respond_to? :close
|
74
|
-
end
|
75
|
-
ensure
|
76
|
-
rack_input.close
|
77
|
-
request.finish
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def self.send_headers(out, status, headers)
|
82
|
-
out.print "Status: #{status}\r\n"
|
83
|
-
headers.each { |k, vs|
|
84
|
-
vs.split("\n").each { |v|
|
85
|
-
out.print "#{k}: #{v}\r\n"
|
86
|
-
}
|
87
|
-
}
|
88
|
-
out.print "\r\n"
|
89
|
-
out.flush
|
90
|
-
end
|
91
|
-
|
92
|
-
def self.send_body(out, body)
|
93
|
-
body.each { |part|
|
94
|
-
out.print part
|
95
|
-
out.flush
|
96
|
-
}
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
data/lib/rack/handler/lsws.rb
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'lsapi'
|
4
|
-
|
5
|
-
module Rack
|
6
|
-
module Handler
|
7
|
-
class LSWS
|
8
|
-
def self.run(app, **options)
|
9
|
-
while LSAPI.accept != nil
|
10
|
-
serve app
|
11
|
-
end
|
12
|
-
end
|
13
|
-
def self.serve(app)
|
14
|
-
env = ENV.to_hash
|
15
|
-
env.delete "HTTP_CONTENT_LENGTH"
|
16
|
-
env[SCRIPT_NAME] = "" if env[SCRIPT_NAME] == "/"
|
17
|
-
|
18
|
-
rack_input = RewindableInput.new($stdin.read.to_s)
|
19
|
-
|
20
|
-
env.update(
|
21
|
-
RACK_VERSION => Rack::VERSION,
|
22
|
-
RACK_INPUT => rack_input,
|
23
|
-
RACK_ERRORS => $stderr,
|
24
|
-
RACK_MULTITHREAD => false,
|
25
|
-
RACK_MULTIPROCESS => true,
|
26
|
-
RACK_RUNONCE => false,
|
27
|
-
RACK_URL_SCHEME => ["yes", "on", "1"].include?(ENV[HTTPS]) ? "https" : "http"
|
28
|
-
)
|
29
|
-
|
30
|
-
env[QUERY_STRING] ||= ""
|
31
|
-
env[HTTP_VERSION] ||= env[SERVER_PROTOCOL]
|
32
|
-
env[REQUEST_PATH] ||= "/"
|
33
|
-
status, headers, body = app.call(env)
|
34
|
-
begin
|
35
|
-
send_headers status, headers
|
36
|
-
send_body body
|
37
|
-
ensure
|
38
|
-
body.close if body.respond_to? :close
|
39
|
-
end
|
40
|
-
ensure
|
41
|
-
rack_input.close
|
42
|
-
end
|
43
|
-
def self.send_headers(status, headers)
|
44
|
-
print "Status: #{status}\r\n"
|
45
|
-
headers.each { |k, vs|
|
46
|
-
vs.split("\n").each { |v|
|
47
|
-
print "#{k}: #{v}\r\n"
|
48
|
-
}
|
49
|
-
}
|
50
|
-
print "\r\n"
|
51
|
-
STDOUT.flush
|
52
|
-
end
|
53
|
-
def self.send_body(body)
|
54
|
-
body.each { |part|
|
55
|
-
print part
|
56
|
-
STDOUT.flush
|
57
|
-
}
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|