rack 1.4.0 → 1.4.5
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.
- data/COPYING +1 -1
- data/KNOWN-ISSUES +9 -0
- data/README.rdoc +118 -4
- data/Rakefile +18 -11
- data/SPEC +3 -1
- data/contrib/rack.png +0 -0
- data/contrib/rack.svg +150 -0
- data/contrib/rdoc.css +412 -0
- data/lib/rack/auth/abstract/request.rb +5 -1
- data/lib/rack/auth/basic.rb +1 -1
- data/lib/rack/auth/digest/nonce.rb +1 -1
- data/lib/rack/backports/uri/common_18.rb +14 -28
- data/lib/rack/backports/uri/common_192.rb +14 -17
- data/lib/rack/backports/uri/common_193.rb +29 -0
- data/lib/rack/body_proxy.rb +15 -2
- data/lib/rack/builder.rb +1 -1
- data/lib/rack/cascade.rb +12 -1
- data/lib/rack/commonlogger.rb +18 -5
- data/lib/rack/deflater.rb +5 -1
- data/lib/rack/directory.rb +1 -1
- data/lib/rack/etag.rb +6 -3
- data/lib/rack/file.rb +20 -16
- data/lib/rack/head.rb +1 -0
- data/lib/rack/lint.rb +3 -1
- data/lib/rack/lock.rb +3 -4
- data/lib/rack/mime.rb +1 -1
- data/lib/rack/mock.rb +3 -2
- data/lib/rack/multipart/parser.rb +22 -20
- data/lib/rack/multipart.rb +2 -2
- data/lib/rack/reloader.rb +1 -1
- data/lib/rack/request.rb +4 -6
- data/lib/rack/response.rb +19 -17
- data/lib/rack/server.rb +28 -2
- data/lib/rack/session/abstract/id.rb +8 -3
- data/lib/rack/session/cookie.rb +20 -7
- data/lib/rack/showstatus.rb +2 -2
- data/lib/rack/static.rb +91 -9
- data/lib/rack/utils.rb +74 -36
- data/lib/rack.rb +13 -1
- data/rack.gemspec +3 -3
- data/test/builder/line.ru +1 -0
- data/test/cgi/assets/folder/test.js +1 -0
- data/test/cgi/assets/fonts/font.eot +1 -0
- data/test/cgi/assets/images/image.png +1 -0
- data/test/cgi/assets/index.html +1 -0
- data/test/cgi/assets/javascripts/app.js +1 -0
- data/test/cgi/assets/stylesheets/app.css +1 -0
- data/test/multipart/filename_with_unescaped_percentages +6 -0
- data/test/multipart/filename_with_unescaped_percentages2 +6 -0
- data/test/multipart/filename_with_unescaped_percentages3 +6 -0
- data/test/spec_auth.rb +57 -0
- data/test/spec_auth_basic.rb +8 -0
- data/test/spec_auth_digest.rb +14 -0
- data/test/spec_body_proxy.rb +21 -0
- data/test/spec_builder.rb +7 -1
- data/test/spec_cascade.rb +14 -3
- data/test/spec_chunked.rb +6 -6
- data/test/spec_config.rb +0 -1
- data/test/spec_content_length.rb +26 -13
- data/test/spec_content_type.rb +15 -5
- data/test/spec_deflater.rb +35 -17
- data/test/spec_directory.rb +20 -1
- data/test/spec_etag.rb +29 -13
- data/test/spec_file.rb +58 -30
- data/test/spec_head.rb +25 -7
- data/test/spec_lobster.rb +20 -5
- data/test/spec_lock.rb +46 -21
- data/test/spec_logger.rb +2 -7
- data/test/spec_methodoverride.rb +21 -22
- data/test/spec_mock.rb +12 -7
- data/test/spec_multipart.rb +129 -2
- data/test/spec_nulllogger.rb +13 -2
- data/test/spec_recursive.rb +12 -9
- data/test/spec_request.rb +15 -2
- data/test/spec_response.rb +41 -3
- data/test/spec_runtime.rb +15 -5
- data/test/spec_sendfile.rb +13 -9
- data/test/spec_server.rb +47 -0
- data/test/spec_session_cookie.rb +93 -3
- data/test/spec_session_memcache.rb +10 -8
- data/test/spec_session_pool.rb +13 -10
- data/test/spec_showexceptions.rb +9 -4
- data/test/spec_showstatus.rb +10 -5
- data/test/spec_static.rb +89 -8
- data/test/spec_urlmap.rb +10 -10
- data/test/spec_utils.rb +34 -7
- data/test/static/another/index.html +1 -0
- metadata +26 -8
data/contrib/rdoc.css
ADDED
|
@@ -0,0 +1,412 @@
|
|
|
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/lib/rack/auth/basic.rb
CHANGED
|
@@ -8,7 +8,21 @@
|
|
|
8
8
|
|
|
9
9
|
module URI
|
|
10
10
|
TBLENCWWWCOMP_ = {} # :nodoc:
|
|
11
|
+
256.times do |i|
|
|
12
|
+
TBLENCWWWCOMP_[i.chr] = '%%%02X' % i
|
|
13
|
+
end
|
|
14
|
+
TBLENCWWWCOMP_[' '] = '+'
|
|
15
|
+
TBLENCWWWCOMP_.freeze
|
|
11
16
|
TBLDECWWWCOMP_ = {} # :nodoc:
|
|
17
|
+
256.times do |i|
|
|
18
|
+
h, l = i>>4, i&15
|
|
19
|
+
TBLDECWWWCOMP_['%%%X%X' % [h, l]] = i.chr
|
|
20
|
+
TBLDECWWWCOMP_['%%%x%X' % [h, l]] = i.chr
|
|
21
|
+
TBLDECWWWCOMP_['%%%X%x' % [h, l]] = i.chr
|
|
22
|
+
TBLDECWWWCOMP_['%%%x%x' % [h, l]] = i.chr
|
|
23
|
+
end
|
|
24
|
+
TBLDECWWWCOMP_['+'] = ' '
|
|
25
|
+
TBLDECWWWCOMP_.freeze
|
|
12
26
|
|
|
13
27
|
# Encode given +s+ to URL-encoded form data.
|
|
14
28
|
#
|
|
@@ -26,18 +40,6 @@ module URI
|
|
|
26
40
|
'%' + $1.unpack('H2' * Rack::Utils.bytesize($1)).join('%').upcase
|
|
27
41
|
end.tr(' ', '+')
|
|
28
42
|
else
|
|
29
|
-
if TBLENCWWWCOMP_.empty?
|
|
30
|
-
tbl = {}
|
|
31
|
-
256.times do |i|
|
|
32
|
-
tbl[i.chr] = '%%%02X' % i
|
|
33
|
-
end
|
|
34
|
-
tbl[' '] = '+'
|
|
35
|
-
begin
|
|
36
|
-
TBLENCWWWCOMP_.replace(tbl)
|
|
37
|
-
TBLENCWWWCOMP_.freeze
|
|
38
|
-
rescue
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
43
|
str.gsub(/[^*\-.0-9A-Z_a-z]/) {|m| TBLENCWWWCOMP_[m]}
|
|
42
44
|
end
|
|
43
45
|
end
|
|
@@ -48,22 +50,6 @@ module URI
|
|
|
48
50
|
#
|
|
49
51
|
# See URI.encode_www_form_component, URI.decode_www_form
|
|
50
52
|
def self.decode_www_form_component(str, enc=nil)
|
|
51
|
-
if TBLDECWWWCOMP_.empty?
|
|
52
|
-
tbl = {}
|
|
53
|
-
256.times do |i|
|
|
54
|
-
h, l = i>>4, i&15
|
|
55
|
-
tbl['%%%X%X' % [h, l]] = i.chr
|
|
56
|
-
tbl['%%%x%X' % [h, l]] = i.chr
|
|
57
|
-
tbl['%%%X%x' % [h, l]] = i.chr
|
|
58
|
-
tbl['%%%x%x' % [h, l]] = i.chr
|
|
59
|
-
end
|
|
60
|
-
tbl['+'] = ' '
|
|
61
|
-
begin
|
|
62
|
-
TBLDECWWWCOMP_.replace(tbl)
|
|
63
|
-
TBLDECWWWCOMP_.freeze
|
|
64
|
-
rescue
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
53
|
raise ArgumentError, "invalid %-encoding (#{str})" unless /\A(?:%[0-9a-fA-F]{2}|[^%])*\z/ =~ str
|
|
68
54
|
str.gsub(/\+|%[0-9a-fA-F]{2}/) {|m| TBLDECWWWCOMP_[m]}
|
|
69
55
|
end
|
|
@@ -17,6 +17,19 @@
|
|
|
17
17
|
require 'uri/common'
|
|
18
18
|
|
|
19
19
|
module URI
|
|
20
|
+
TBLDECWWWCOMP_ = {} unless const_defined?(:TBLDECWWWCOMP_) #:nodoc:
|
|
21
|
+
if TBLDECWWWCOMP_.empty?
|
|
22
|
+
256.times do |i|
|
|
23
|
+
h, l = i>>4, i&15
|
|
24
|
+
TBLDECWWWCOMP_['%%%X%X' % [h, l]] = i.chr
|
|
25
|
+
TBLDECWWWCOMP_['%%%x%X' % [h, l]] = i.chr
|
|
26
|
+
TBLDECWWWCOMP_['%%%X%x' % [h, l]] = i.chr
|
|
27
|
+
TBLDECWWWCOMP_['%%%x%x' % [h, l]] = i.chr
|
|
28
|
+
end
|
|
29
|
+
TBLDECWWWCOMP_['+'] = ' '
|
|
30
|
+
TBLDECWWWCOMP_.freeze
|
|
31
|
+
end
|
|
32
|
+
|
|
20
33
|
def self.decode_www_form(str, enc=Encoding::UTF_8)
|
|
21
34
|
return [] if str.empty?
|
|
22
35
|
unless /\A#{WFKV_}=#{WFKV_}(?:[;&]#{WFKV_}=#{WFKV_})*\z/o =~ str
|
|
@@ -30,26 +43,10 @@ module URI
|
|
|
30
43
|
end
|
|
31
44
|
|
|
32
45
|
def self.decode_www_form_component(str, enc=Encoding::UTF_8)
|
|
33
|
-
if TBLDECWWWCOMP_.empty?
|
|
34
|
-
tbl = {}
|
|
35
|
-
256.times do |i|
|
|
36
|
-
h, l = i>>4, i&15
|
|
37
|
-
tbl['%%%X%X' % [h, l]] = i.chr
|
|
38
|
-
tbl['%%%x%X' % [h, l]] = i.chr
|
|
39
|
-
tbl['%%%X%x' % [h, l]] = i.chr
|
|
40
|
-
tbl['%%%x%x' % [h, l]] = i.chr
|
|
41
|
-
end
|
|
42
|
-
tbl['+'] = ' '
|
|
43
|
-
begin
|
|
44
|
-
TBLDECWWWCOMP_.replace(tbl)
|
|
45
|
-
TBLDECWWWCOMP_.freeze
|
|
46
|
-
rescue
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
46
|
raise ArgumentError, "invalid %-encoding (#{str})" unless /\A[^%]*(?:%\h\h[^%]*)*\z/ =~ str
|
|
50
47
|
str.gsub(/\+|%\h\h/, TBLDECWWWCOMP_).force_encoding(enc)
|
|
51
48
|
end
|
|
52
49
|
|
|
53
|
-
remove_const :WFKV_
|
|
50
|
+
remove_const :WFKV_ if const_defined?(:WFKV_)
|
|
54
51
|
WFKV_ = '(?:[^%#=;&]*(?:%\h\h[^%#=;&]*)*)' # :nodoc:
|
|
55
52
|
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# :stopdoc:
|
|
2
|
+
|
|
3
|
+
require 'uri/common'
|
|
4
|
+
|
|
5
|
+
# Issue:
|
|
6
|
+
# http://bugs.ruby-lang.org/issues/5925
|
|
7
|
+
#
|
|
8
|
+
# Relevant commit:
|
|
9
|
+
# https://github.com/ruby/ruby/commit/edb7cdf1eabaff78dfa5ffedfbc2e91b29fa9ca1
|
|
10
|
+
|
|
11
|
+
module URI
|
|
12
|
+
256.times do |i|
|
|
13
|
+
TBLENCWWWCOMP_[i.chr] = '%%%02X' % i
|
|
14
|
+
end
|
|
15
|
+
TBLENCWWWCOMP_[' '] = '+'
|
|
16
|
+
TBLENCWWWCOMP_.freeze
|
|
17
|
+
|
|
18
|
+
256.times do |i|
|
|
19
|
+
h, l = i>>4, i&15
|
|
20
|
+
TBLDECWWWCOMP_['%%%X%X' % [h, l]] = i.chr
|
|
21
|
+
TBLDECWWWCOMP_['%%%x%X' % [h, l]] = i.chr
|
|
22
|
+
TBLDECWWWCOMP_['%%%X%x' % [h, l]] = i.chr
|
|
23
|
+
TBLDECWWWCOMP_['%%%x%x' % [h, l]] = i.chr
|
|
24
|
+
end
|
|
25
|
+
TBLDECWWWCOMP_['+'] = ' '
|
|
26
|
+
TBLDECWWWCOMP_.freeze
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# :startdoc:
|
data/lib/rack/body_proxy.rb
CHANGED
|
@@ -5,21 +5,34 @@ module Rack
|
|
|
5
5
|
end
|
|
6
6
|
|
|
7
7
|
def respond_to?(*args)
|
|
8
|
+
return false if args.first.to_s =~ /^to_ary$/
|
|
8
9
|
super or @body.respond_to?(*args)
|
|
9
10
|
end
|
|
10
11
|
|
|
11
12
|
def close
|
|
12
13
|
return if @closed
|
|
13
14
|
@closed = true
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
begin
|
|
16
|
+
@body.close if @body.respond_to? :close
|
|
17
|
+
ensure
|
|
18
|
+
@block.call
|
|
19
|
+
end
|
|
16
20
|
end
|
|
17
21
|
|
|
18
22
|
def closed?
|
|
19
23
|
@closed
|
|
20
24
|
end
|
|
21
25
|
|
|
26
|
+
# N.B. This method is a special case to address the bug described by #434.
|
|
27
|
+
# We are applying this special case for #each only. Future bugs of this
|
|
28
|
+
# class will be handled by requesting users to patch their ruby
|
|
29
|
+
# implementation, to save adding too many methods in this class.
|
|
30
|
+
def each(*args, &block)
|
|
31
|
+
@body.each(*args, &block)
|
|
32
|
+
end
|
|
33
|
+
|
|
22
34
|
def method_missing(*args, &block)
|
|
35
|
+
super if args.first.to_s =~ /^to_ary$/
|
|
23
36
|
@body.__send__(*args, &block)
|
|
24
37
|
end
|
|
25
38
|
end
|
data/lib/rack/builder.rb
CHANGED
|
@@ -38,7 +38,7 @@ module Rack
|
|
|
38
38
|
end
|
|
39
39
|
cfgfile.sub!(/^__END__\n.*\Z/m, '')
|
|
40
40
|
app = eval "Rack::Builder.new {\n" + cfgfile + "\n}.to_app",
|
|
41
|
-
TOPLEVEL_BINDING, config
|
|
41
|
+
TOPLEVEL_BINDING, config, 0
|
|
42
42
|
else
|
|
43
43
|
require config
|
|
44
44
|
app = Object.const_get(::File.basename(config, '.rb').capitalize)
|
data/lib/rack/cascade.rb
CHANGED
|
@@ -8,7 +8,7 @@ module Rack
|
|
|
8
8
|
|
|
9
9
|
attr_reader :apps
|
|
10
10
|
|
|
11
|
-
def initialize(apps, catch=404)
|
|
11
|
+
def initialize(apps, catch=[404, 405])
|
|
12
12
|
@apps = []; @has_app = {}
|
|
13
13
|
apps.each { |app| add app }
|
|
14
14
|
|
|
@@ -19,8 +19,19 @@ module Rack
|
|
|
19
19
|
def call(env)
|
|
20
20
|
result = NotFound
|
|
21
21
|
|
|
22
|
+
last_body = nil
|
|
23
|
+
|
|
22
24
|
@apps.each do |app|
|
|
25
|
+
# The SPEC says that the body must be closed after it has been iterated
|
|
26
|
+
# by the server, or if it is replaced by a middleware action. Cascade
|
|
27
|
+
# replaces the body each time a cascade happens. It is assumed that nil
|
|
28
|
+
# does not respond to close, otherwise the previous application body
|
|
29
|
+
# will be closed. The final application body will not be closed, as it
|
|
30
|
+
# will be passed to the server as a result.
|
|
31
|
+
last_body.close if last_body.respond_to? :close
|
|
32
|
+
|
|
23
33
|
result = app.call(env)
|
|
34
|
+
last_body = result[2]
|
|
24
35
|
break unless @catch.include?(result[0].to_i)
|
|
25
36
|
end
|
|
26
37
|
|
data/lib/rack/commonlogger.rb
CHANGED
|
@@ -1,13 +1,26 @@
|
|
|
1
1
|
require 'rack/body_proxy'
|
|
2
2
|
|
|
3
3
|
module Rack
|
|
4
|
-
# Rack::CommonLogger forwards every request to
|
|
5
|
-
# logs a line in the
|
|
6
|
-
#
|
|
4
|
+
# Rack::CommonLogger forwards every request to the given +app+, and
|
|
5
|
+
# logs a line in the
|
|
6
|
+
# {Apache common log format}[http://httpd.apache.org/docs/1.3/logs.html#common]
|
|
7
|
+
# to the +logger+.
|
|
8
|
+
#
|
|
9
|
+
# If +logger+ is nil, CommonLogger will fall back +rack.errors+, which is
|
|
10
|
+
# an instance of Rack::NullLogger.
|
|
11
|
+
#
|
|
12
|
+
# +logger+ can be any class, including the standard library Logger, and is
|
|
13
|
+
# expected to have a +write+ method, which accepts the CommonLogger::FORMAT.
|
|
14
|
+
# According to the SPEC, the error stream must also respond to +puts+
|
|
15
|
+
# (which takes a single argument that responds to +to_s+), and +flush+
|
|
16
|
+
# (which is called without arguments in order to make the error appear for
|
|
17
|
+
# sure)
|
|
7
18
|
class CommonLogger
|
|
8
19
|
# Common Log Format: http://httpd.apache.org/docs/1.3/logs.html#common
|
|
9
|
-
#
|
|
10
|
-
#
|
|
20
|
+
#
|
|
21
|
+
# lilith.local - - [07/Aug/2006 23:58:02] "GET / HTTP/1.1" 500 -
|
|
22
|
+
#
|
|
23
|
+
# %{%s - %s [%s] "%s %s%s %s" %d %s\n} %
|
|
11
24
|
FORMAT = %{%s - %s [%s] "%s %s%s %s" %d %s %0.4f\n}
|
|
12
25
|
|
|
13
26
|
def initialize(app, logger=nil)
|