cgi 0.5.1 → 0.5.2
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.
- checksums.yaml +4 -4
- data/README.md +6 -3
- data/lib/cgi/core.rb +399 -106
- data/lib/cgi/escape.rb +21 -22
- data/lib/cgi/session.rb +16 -4
- data/lib/cgi.rb +2 -2
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9c5aa5b0794db539b4fa7b8a3da82182b587829ac7de10a444ef52447eef3811
|
|
4
|
+
data.tar.gz: 9a90fdb11ac132bd2c5693fa34c9ffdd5f492e66961561ef51bfab109e1deff0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: aaa90e2e539670dd03dfea7dcc26cb6382eef97fd783bcbc99f509018492386e7160a3944f52eb6fae589bfec628c5d935d5226412243d3267d7781945dd6f70
|
|
7
|
+
data.tar.gz: e9b846ecf59d6834dc02e7f1e1f5eb47ca845f2f85451a85c54c088aa547d01daf3a65651d61d769a86e30da2a242ea826bb231e83cf2421c811b4de67d07144
|
data/README.md
CHANGED
|
@@ -22,11 +22,15 @@ gem 'cgi'
|
|
|
22
22
|
|
|
23
23
|
And then execute:
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
```bash
|
|
26
|
+
bundle
|
|
27
|
+
```
|
|
26
28
|
|
|
27
29
|
Or install it yourself as:
|
|
28
30
|
|
|
29
|
-
|
|
31
|
+
```bash
|
|
32
|
+
gem install cgi
|
|
33
|
+
```
|
|
30
34
|
|
|
31
35
|
## Usage
|
|
32
36
|
|
|
@@ -73,7 +77,6 @@ db.transaction do
|
|
|
73
77
|
end
|
|
74
78
|
```
|
|
75
79
|
|
|
76
|
-
|
|
77
80
|
### Restore form values from file
|
|
78
81
|
|
|
79
82
|
```ruby
|
data/lib/cgi/core.rb
CHANGED
|
@@ -72,91 +72,267 @@ class CGI
|
|
|
72
72
|
|
|
73
73
|
private :env_table, :stdinput, :stdoutput
|
|
74
74
|
|
|
75
|
-
# Create an HTTP header block as a string.
|
|
76
|
-
#
|
|
77
75
|
# :call-seq:
|
|
78
|
-
#
|
|
79
|
-
#
|
|
80
|
-
#
|
|
81
|
-
#
|
|
76
|
+
# http_header(content_type = 'text/html') -> string
|
|
77
|
+
# http_header(headers) -> string
|
|
78
|
+
#
|
|
79
|
+
# Creates and returns an HTTP header section as a multi-line string.
|
|
80
|
+
#
|
|
81
|
+
# The string always includes:
|
|
82
|
+
#
|
|
83
|
+
# - Header +Content-Type+ (with a default value if none given).
|
|
84
|
+
# - A trailing newline, which delimits the header block;
|
|
85
|
+
# that last line is omitted from the examples below.
|
|
86
|
+
#
|
|
87
|
+
# <b>In Brief</b>
|
|
88
|
+
#
|
|
89
|
+
# headers = {
|
|
90
|
+
# 'charset' => 'iso-2022-jp',
|
|
91
|
+
# 'connection' => 'keep-alive',
|
|
92
|
+
# 'cookie' => 'foo=0',
|
|
93
|
+
# 'expires' => Time.now + (60 * 60 * 24 * 365),
|
|
94
|
+
# 'language' => 'en-US, en-CA',
|
|
95
|
+
# 'length' => 4096,
|
|
96
|
+
# 'nph' => true,
|
|
97
|
+
# 'server' => 'Apache/2.4.1 (Unix)',
|
|
98
|
+
# 'status' => 'OK',
|
|
99
|
+
# 'type' => 'text/xml',
|
|
100
|
+
# MyHeader: true
|
|
101
|
+
# }
|
|
102
|
+
#
|
|
103
|
+
# puts cgi.http_header(headers)
|
|
104
|
+
# HTTP/1.0 200 OK
|
|
105
|
+
# Date: Mon, 01 Dec 2025 22:08:22 GMT
|
|
106
|
+
# Server: Apache/2.4.1 (Unix)
|
|
107
|
+
# Connection: keep-alive
|
|
108
|
+
# Content-Type: text/xml; charset=iso-2022-jp
|
|
109
|
+
# Content-Length: 4096
|
|
110
|
+
# Content-Language: en-US, en-CA
|
|
111
|
+
# Expires: Tue, 01 Dec 2026 22:05:30 GMT
|
|
112
|
+
# Set-Cookie: foo=0
|
|
113
|
+
# MyHeader: true
|
|
114
|
+
#
|
|
115
|
+
# headers.delete('nph')
|
|
116
|
+
#
|
|
117
|
+
# puts cgi.http_header(headers)
|
|
118
|
+
# Status: 200 OK
|
|
119
|
+
# Server: Apache/2.4.1 (Unix)
|
|
120
|
+
# Connection: keep-alive
|
|
121
|
+
# Content-Type: text/xml; charset=iso-2022-jp
|
|
122
|
+
# Content-Length: 4096
|
|
123
|
+
# Content-Language: en-US, en-CA
|
|
124
|
+
# Expires: Tue, 01 Dec 2026 22:05:30 GMT
|
|
125
|
+
# Set-Cookie: foo=0
|
|
126
|
+
# MyHeader: true
|
|
127
|
+
#
|
|
128
|
+
# <b>Arguments</b>
|
|
129
|
+
#
|
|
130
|
+
# With no argument given,
|
|
131
|
+
# includes only header +Content-Type+ with its default value <tt>'text/html'</tt>:
|
|
132
|
+
#
|
|
133
|
+
# puts cgi.http_header
|
|
134
|
+
# Content-Type: text/html
|
|
135
|
+
#
|
|
136
|
+
# With string argument +content_type+ given,
|
|
137
|
+
# includes header +Content-Type+ with the given value:
|
|
82
138
|
#
|
|
83
|
-
#
|
|
84
|
-
#
|
|
85
|
-
#
|
|
86
|
-
#
|
|
87
|
-
#
|
|
88
|
-
#
|
|
89
|
-
#
|
|
90
|
-
#
|
|
91
|
-
#
|
|
92
|
-
#
|
|
93
|
-
#
|
|
94
|
-
#
|
|
95
|
-
#
|
|
96
|
-
#
|
|
97
|
-
#
|
|
98
|
-
#
|
|
99
|
-
#
|
|
100
|
-
#
|
|
101
|
-
#
|
|
102
|
-
#
|
|
103
|
-
#
|
|
104
|
-
#
|
|
105
|
-
#
|
|
106
|
-
#
|
|
107
|
-
#
|
|
108
|
-
#
|
|
109
|
-
#
|
|
110
|
-
#
|
|
111
|
-
#
|
|
112
|
-
#
|
|
113
|
-
#
|
|
114
|
-
#
|
|
115
|
-
#
|
|
116
|
-
#
|
|
117
|
-
#
|
|
118
|
-
#
|
|
119
|
-
#
|
|
120
|
-
#
|
|
121
|
-
#
|
|
122
|
-
#
|
|
123
|
-
#
|
|
124
|
-
#
|
|
125
|
-
#
|
|
126
|
-
#
|
|
127
|
-
#
|
|
128
|
-
#
|
|
129
|
-
#
|
|
130
|
-
#
|
|
131
|
-
#
|
|
132
|
-
#
|
|
133
|
-
#
|
|
134
|
-
#
|
|
135
|
-
#
|
|
136
|
-
#
|
|
137
|
-
#
|
|
138
|
-
#
|
|
139
|
-
#
|
|
139
|
+
# puts cgi.http_header('text/xml')
|
|
140
|
+
# Content-Type: text/xml
|
|
141
|
+
#
|
|
142
|
+
# With hash argument +headers+ given,
|
|
143
|
+
# includes a header for hash entry, whose name is based on the entry's key,
|
|
144
|
+
# and whose value is the entry's value.
|
|
145
|
+
#
|
|
146
|
+
# <i>Recognized Keys</i>
|
|
147
|
+
#
|
|
148
|
+
# The following keys are recognized;
|
|
149
|
+
# each is a lowercase string:
|
|
150
|
+
#
|
|
151
|
+
# <tt>'charset'</tt>::
|
|
152
|
+
# The character set of the body; appended to the +Content-Type+ header:
|
|
153
|
+
#
|
|
154
|
+
# puts cgi.http_header('charset' => 'iso-2022-jp')
|
|
155
|
+
# Content-Type: text/html; charset=iso-2022-jp
|
|
156
|
+
#
|
|
157
|
+
# <tt>'connection'</tt>::
|
|
158
|
+
# Sets header +Connection+ to the given string:
|
|
159
|
+
#
|
|
160
|
+
# puts cgi.http_header('connection' => 'keep-alive')
|
|
161
|
+
# Connection: keep-alive
|
|
162
|
+
# Content-Type: text/html
|
|
163
|
+
#
|
|
164
|
+
# <tt>'cookie'</tt>::
|
|
165
|
+
# Sets one or more +Set-Cookie+ headers to the given value, which may be:
|
|
166
|
+
#
|
|
167
|
+
# - String cookie.
|
|
168
|
+
# - CGI::Cookie object.
|
|
169
|
+
# - Array of string cookies and CGI::Cookie objects.
|
|
170
|
+
# - A hash whose values are string cookies and CGI::Cookie objects
|
|
171
|
+
# (the keys are not used).
|
|
172
|
+
#
|
|
173
|
+
# Examples:
|
|
174
|
+
#
|
|
175
|
+
# foo_string = 'foo=0'
|
|
176
|
+
# bar_string = 'bar=1'
|
|
177
|
+
# foo_cookie = CGI::Cookie.new('foo', '0')
|
|
178
|
+
# bar_cookie = CGI::Cookie.new('bar', '1')
|
|
179
|
+
#
|
|
180
|
+
# puts cgi.http_header('cookie' => foo_string)
|
|
181
|
+
# Content-Type: text/html
|
|
182
|
+
# Set-Cookie: foo=0
|
|
183
|
+
#
|
|
184
|
+
# puts cgi.http_header('cookie' => foo_cookie)
|
|
185
|
+
# Content-Type: text/html
|
|
186
|
+
# Set-Cookie: foo=0; path=
|
|
187
|
+
#
|
|
188
|
+
# puts cgi.http_header('cookie' => [foo_cookie, bar_string])
|
|
189
|
+
# Content-Type: text/html
|
|
190
|
+
# Set-Cookie: foo=0; path=
|
|
191
|
+
# Set-Cookie: bar=1
|
|
192
|
+
#
|
|
193
|
+
# puts cgi.http_header('cookie' => {foo: foo_cookie, bar: bar_string})
|
|
194
|
+
# Content-Type: text/html
|
|
195
|
+
# Set-Cookie: foo=0; path=
|
|
196
|
+
# Set-Cookie: bar=1
|
|
197
|
+
#
|
|
198
|
+
# These cookies are in addition to the cookies held
|
|
199
|
+
# in the <tt>@output_cookies</tt> variable.
|
|
200
|
+
#
|
|
201
|
+
# <tt>'expires'</tt>::
|
|
202
|
+
# Sets header +Expires+ to the given time,
|
|
203
|
+
# which must be a {Time}[https://docs.ruby-lang.org/en/master/Time.html] object:
|
|
204
|
+
#
|
|
205
|
+
# puts cgi.http_header('expires' => Time.now + (60 * 60 * 24 * 365))
|
|
206
|
+
# Content-Type: text/html
|
|
207
|
+
# Expires: Tue, 01 Dec 2026 23:42:37 GMT
|
|
208
|
+
#
|
|
209
|
+
# <tt>'language'</tt>::
|
|
210
|
+
# Sets header +Content-Language+ to the given string:
|
|
211
|
+
#
|
|
212
|
+
# puts cgi.http_header('language' => 'en-US, en-CA')
|
|
213
|
+
# Content-Type: text/html
|
|
214
|
+
# Content-Language: en-US, en-CA
|
|
215
|
+
#
|
|
216
|
+
# <tt>'length'</tt>::
|
|
217
|
+
# Sets header +Content-Length+ to the given value,
|
|
218
|
+
# which may be an integer or a string:
|
|
219
|
+
#
|
|
220
|
+
# puts cgi.http_header('length' => 4096)
|
|
221
|
+
# Content-Type: text/html
|
|
222
|
+
# Content-Length: 4096
|
|
140
223
|
#
|
|
141
|
-
#
|
|
142
|
-
#
|
|
224
|
+
# puts cgi.http_header('length' => '4096')
|
|
225
|
+
# Content-Type: text/html
|
|
226
|
+
# Content-Length: 4096
|
|
143
227
|
#
|
|
144
|
-
#
|
|
145
|
-
#
|
|
146
|
-
#
|
|
147
|
-
#
|
|
148
|
-
#
|
|
149
|
-
#
|
|
150
|
-
#
|
|
151
|
-
#
|
|
152
|
-
#
|
|
153
|
-
#
|
|
154
|
-
#
|
|
155
|
-
#
|
|
156
|
-
#
|
|
157
|
-
#
|
|
228
|
+
# <tt>'nph'</tt>::
|
|
229
|
+
# If +true+:
|
|
230
|
+
#
|
|
231
|
+
# - Adds protocol string and status code as first line.
|
|
232
|
+
# - Adds date as second line.
|
|
233
|
+
# - Adds headers +Server+ with no value,
|
|
234
|
+
# and +Connection+ with default value <tt>'close'</tt>;
|
|
235
|
+
# either or both values may be overridden with explicit values.
|
|
236
|
+
#
|
|
237
|
+
# Examples:
|
|
238
|
+
#
|
|
239
|
+
# puts cgi.http_header('nph' => true)
|
|
240
|
+
# HTTP/1.0 200 OK
|
|
241
|
+
# Date: Mon, 01 Dec 2025 19:42:22 GMT
|
|
242
|
+
# Server:
|
|
243
|
+
# Connection: close
|
|
244
|
+
# Content-Type: text/html
|
|
245
|
+
#
|
|
246
|
+
# puts cgi.http_header('nph' => true, 'server' => 'Apache/2.4.1 (Unix)', 'connection' => 'keep-alive')
|
|
247
|
+
# HTTP/1.0 200 OK
|
|
248
|
+
# Date: Mon, 01 Dec 2025 20:00:41 GMT
|
|
249
|
+
# Server: Apache/2.4.1 (Unix)
|
|
250
|
+
# Connection: keep-alive
|
|
251
|
+
# Content-Type: text/html
|
|
252
|
+
#
|
|
253
|
+
# <tt>'server'</tt>::
|
|
254
|
+
# Sets header +Server+ to the given string:
|
|
255
|
+
#
|
|
256
|
+
# puts cgi.http_header('server' => 'Apache/2.4.1 (Unix)')
|
|
257
|
+
# Server: Apache/2.4.1 (Unix)
|
|
258
|
+
# Content-Type: text/html
|
|
259
|
+
#
|
|
260
|
+
# <tt>'status'</tt>::
|
|
261
|
+
# Sets header +Status+ to the given string:
|
|
262
|
+
#
|
|
263
|
+
# puts cgi.http_header('status' => '666 MyVeryOwnStatus')
|
|
264
|
+
# Status: 666 MyVeryOwnStatus
|
|
265
|
+
# Content-Type: text/html
|
|
266
|
+
#
|
|
267
|
+
# If the given string is a key in the hash constant +CGI::HTTP_STATUS+,
|
|
268
|
+
# the status becomes the value for that key:
|
|
269
|
+
#
|
|
270
|
+
# CGI::HTTP_STATUS
|
|
271
|
+
# # =>
|
|
272
|
+
# {"OK" => "200 OK",
|
|
273
|
+
# "PARTIAL_CONTENT" => "206 Partial Content",
|
|
274
|
+
# "MULTIPLE_CHOICES" => "300 Multiple Choices",
|
|
275
|
+
# "MOVED" => "301 Moved Permanently",
|
|
276
|
+
# "REDIRECT" => "302 Found",
|
|
277
|
+
# "NOT_MODIFIED" => "304 Not Modified",
|
|
278
|
+
# "BAD_REQUEST" => "400 Bad Request",
|
|
279
|
+
# "AUTH_REQUIRED" => "401 Authorization Required",
|
|
280
|
+
# "FORBIDDEN" => "403 Forbidden",
|
|
281
|
+
# "NOT_FOUND" => "404 Not Found",
|
|
282
|
+
# "METHOD_NOT_ALLOWED" => "405 Method Not Allowed",
|
|
283
|
+
# "NOT_ACCEPTABLE" => "406 Not Acceptable",
|
|
284
|
+
# "LENGTH_REQUIRED" => "411 Length Required",
|
|
285
|
+
# "PRECONDITION_FAILED" => "412 Precondition Failed",
|
|
286
|
+
# "SERVER_ERROR" => "500 Internal Server Error",
|
|
287
|
+
# "NOT_IMPLEMENTED" => "501 Method Not Implemented",
|
|
288
|
+
# "BAD_GATEWAY" => "502 Bad Gateway",
|
|
289
|
+
# "VARIANT_ALSO_VARIES" => "506 Variant Also Negotiates"}
|
|
290
|
+
#
|
|
291
|
+
# puts cgi.http_header('status' => 'OK')
|
|
292
|
+
# Status: 200 OK
|
|
293
|
+
# Content-Type: text/html
|
|
294
|
+
#
|
|
295
|
+
# puts cgi.http_header('status' => 'NOT_FOUND')
|
|
296
|
+
# Status: 404 Not Found
|
|
297
|
+
# Content-Type: text/html
|
|
298
|
+
#
|
|
299
|
+
# <tt>'type'</tt>::
|
|
300
|
+
# Sets +Content-Type+, overriding the default value <tt>'text/html'</tt>:
|
|
301
|
+
#
|
|
302
|
+
# puts cgi.http_header('type' => 'text/xml')
|
|
303
|
+
# Content-Type: text/xml
|
|
304
|
+
#
|
|
305
|
+
# <i>Unrecognized Keys</i>
|
|
306
|
+
#
|
|
307
|
+
# Headers may also be set for unrecognized keys;
|
|
308
|
+
# an unrecognized key becomes a header name with the given value:
|
|
309
|
+
#
|
|
310
|
+
# puts cgi.http_header('length' => 0) # Recognized key (lowercase string).
|
|
311
|
+
# Content-Type: text/html
|
|
312
|
+
# Content-Length: 0
|
|
313
|
+
#
|
|
314
|
+
# puts cgi.http_header('Length' => 0) # Unrecognized key (string key not lowercase).
|
|
315
|
+
# Content-Type: text/html
|
|
316
|
+
# Length: 0
|
|
317
|
+
#
|
|
318
|
+
# puts cgi.http_header(length: 0) # Unrecognized key (symbol key not string)
|
|
319
|
+
# Content-Type: text/html
|
|
320
|
+
# length: 0
|
|
158
321
|
#
|
|
159
322
|
# This method does not perform charset conversion.
|
|
323
|
+
#
|
|
324
|
+
# It's best to use this method (CGI#http_header), not its aliased method +header+,
|
|
325
|
+
# which is provided only for backward compatibility.
|
|
326
|
+
#
|
|
327
|
+
# Method CGI#http_header is preferred because when +tag_maker+ is <tt>'html5'</tt>,
|
|
328
|
+
# calling method +header+ generates an HTML +header+ element:
|
|
329
|
+
#
|
|
330
|
+
# cgi = CGI.new(tag_maker: 'html5')
|
|
331
|
+
# puts cgi.http_header # Works as expected.
|
|
332
|
+
# Content-Type: text/html
|
|
333
|
+
# puts cgi.header # Maybe a surprise.
|
|
334
|
+
# <HEADER></HEADER>
|
|
335
|
+
#
|
|
160
336
|
def http_header(options='text/html')
|
|
161
337
|
if options.is_a?(String)
|
|
162
338
|
content_type = options
|
|
@@ -481,7 +657,7 @@ class CGI
|
|
|
481
657
|
|
|
482
658
|
##
|
|
483
659
|
# Parses multipart form elements according to
|
|
484
|
-
#
|
|
660
|
+
# https://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2
|
|
485
661
|
#
|
|
486
662
|
# Returns a hash of multipart form parameters with bodies of type StringIO or
|
|
487
663
|
# Tempfile depending on whether the multipart form element exceeds 10 KB
|
|
@@ -662,13 +838,16 @@ class CGI
|
|
|
662
838
|
# Handles multipart forms (in particular, forms that involve file uploads).
|
|
663
839
|
# Reads query parameters in the @params field, and cookies into @cookies.
|
|
664
840
|
def initialize_query()
|
|
841
|
+
content_length = env_table['CONTENT_LENGTH']
|
|
842
|
+
content_length = nil if content_length == ''
|
|
665
843
|
if ("POST" == env_table['REQUEST_METHOD']) and
|
|
666
844
|
%r|\Amultipart/form-data.*boundary=\"?([^\";,]+)\"?| =~ env_table['CONTENT_TYPE']
|
|
667
845
|
current_max_multipart_length = @max_multipart_length.respond_to?(:call) ? @max_multipart_length.call : @max_multipart_length
|
|
668
846
|
raise StandardError.new("too large multipart data.") if env_table['CONTENT_LENGTH'].to_i > current_max_multipart_length
|
|
847
|
+
raise StandardError.new("no content length for multipart data.") if content_length.nil?
|
|
669
848
|
boundary = $1.dup
|
|
670
849
|
@multipart = true
|
|
671
|
-
@params = read_multipart(boundary, Integer(
|
|
850
|
+
@params = read_multipart(boundary, Integer(content_length))
|
|
672
851
|
else
|
|
673
852
|
@multipart = false
|
|
674
853
|
@params = CGI.parse(
|
|
@@ -681,7 +860,11 @@ class CGI
|
|
|
681
860
|
end
|
|
682
861
|
when "POST"
|
|
683
862
|
stdinput.binmode if defined? stdinput.binmode
|
|
684
|
-
|
|
863
|
+
if content_length.nil?
|
|
864
|
+
stdinput.read or ''
|
|
865
|
+
else
|
|
866
|
+
stdinput.read(Integer(content_length)) or ''
|
|
867
|
+
end
|
|
685
868
|
else
|
|
686
869
|
read_from_cmdline
|
|
687
870
|
end.dup.force_encoding(@accept_charset)
|
|
@@ -758,12 +941,75 @@ class CGI
|
|
|
758
941
|
#
|
|
759
942
|
@@accept_charset="UTF-8" if false # needed for rdoc?
|
|
760
943
|
|
|
761
|
-
#
|
|
944
|
+
# :call-seq:
|
|
945
|
+
# CGI.accept_charset -> encoding
|
|
946
|
+
#
|
|
947
|
+
# Returns the default accept character set to be used for new \CGI instances;
|
|
948
|
+
# see CGI.accept_charset=.
|
|
762
949
|
def self.accept_charset
|
|
763
950
|
@@accept_charset
|
|
764
951
|
end
|
|
765
952
|
|
|
766
|
-
#
|
|
953
|
+
# :call-seq:
|
|
954
|
+
# CGI.accept_charset = encoding
|
|
955
|
+
#
|
|
956
|
+
# Sets the default accept character set to be used for new \CGI instances;
|
|
957
|
+
# returns the argument.
|
|
958
|
+
#
|
|
959
|
+
# The argument may be an Encoding object or an Encoding name;
|
|
960
|
+
# see {Encodings}[https://docs.ruby-lang.org/en/master/language/encodings_rdoc.html]:
|
|
961
|
+
#
|
|
962
|
+
# # The initial value.
|
|
963
|
+
# CGI.accept_charset # => #<Encoding:UTF-8>
|
|
964
|
+
# CGI.new
|
|
965
|
+
# # =>
|
|
966
|
+
# #<CGI:0x0000018991db6ae8
|
|
967
|
+
# @accept_charset=#<Encoding:UTF-8>,
|
|
968
|
+
# @accept_charset_error_block=nil,
|
|
969
|
+
# @cookies={},
|
|
970
|
+
# @max_multipart_length=134217728,
|
|
971
|
+
# @multipart=false,
|
|
972
|
+
# @options={accept_charset: #<Encoding:UTF-8>, max_multipart_length: 134217728},
|
|
973
|
+
# @output_cookies=nil,
|
|
974
|
+
# @output_hidden=nil,
|
|
975
|
+
# @params={}>
|
|
976
|
+
#
|
|
977
|
+
# # Set by Encoding name.
|
|
978
|
+
# CGI.accept_charset = 'US-ASCII' # => "US-ASCII"
|
|
979
|
+
# CGI.new
|
|
980
|
+
# # =>
|
|
981
|
+
# #<CGI:0x0000018991cf4100
|
|
982
|
+
# @accept_charset="US-ASCII",
|
|
983
|
+
# @accept_charset_error_block=nil,
|
|
984
|
+
# @cookies={},
|
|
985
|
+
# @max_multipart_length=134217728,
|
|
986
|
+
# @multipart=false,
|
|
987
|
+
# @options={accept_charset: "US-ASCII", max_multipart_length: 134217728},
|
|
988
|
+
# @output_cookies=nil,
|
|
989
|
+
# @output_hidden=nil,
|
|
990
|
+
# @params={}>
|
|
991
|
+
#
|
|
992
|
+
# # Set by Encoding object.
|
|
993
|
+
# CGI.accept_charset = Encoding::ASCII_8BIT # => #<Encoding:BINARY (ASCII-8BIT)>
|
|
994
|
+
# CGI.new
|
|
995
|
+
# # =>
|
|
996
|
+
# #<CGI:0x0000018991cfc800
|
|
997
|
+
# @accept_charset=#<Encoding:BINARY (ASCII-8BIT)>,
|
|
998
|
+
# @accept_charset_error_block=nil,
|
|
999
|
+
# @cookies={},
|
|
1000
|
+
# @max_multipart_length=134217728,
|
|
1001
|
+
# @multipart=false,
|
|
1002
|
+
# @options={accept_charset: #<Encoding:BINARY (ASCII-8BIT)>, max_multipart_length: 134217728},
|
|
1003
|
+
# @output_cookies=nil,
|
|
1004
|
+
# @output_hidden=nil,
|
|
1005
|
+
# @params={}>
|
|
1006
|
+
#
|
|
1007
|
+
# The given encoding is not checked in this method,
|
|
1008
|
+
# but if it is invalid, a call to CGI.new will fail:
|
|
1009
|
+
#
|
|
1010
|
+
# CGI.accept_charset = 'foo'
|
|
1011
|
+
# CGI.new # Raises ArgumentError: unknown encoding name - foo
|
|
1012
|
+
#
|
|
767
1013
|
def self.accept_charset=(accept_charset)
|
|
768
1014
|
@@accept_charset=accept_charset
|
|
769
1015
|
end
|
|
@@ -803,16 +1049,18 @@ class CGI
|
|
|
803
1049
|
# With no argument and no block given, returns a new \CGI object with default values:
|
|
804
1050
|
#
|
|
805
1051
|
# cgi = CGI.new
|
|
806
|
-
#
|
|
807
|
-
#
|
|
808
|
-
#
|
|
809
|
-
#
|
|
810
|
-
#
|
|
811
|
-
#
|
|
812
|
-
#
|
|
813
|
-
#
|
|
814
|
-
#
|
|
815
|
-
#
|
|
1052
|
+
# cgi
|
|
1053
|
+
# # =>
|
|
1054
|
+
# #<CGI:0x00000189917aff00
|
|
1055
|
+
# @accept_charset=#<Encoding:UTF-8>,
|
|
1056
|
+
# @accept_charset_error_block=nil,
|
|
1057
|
+
# @cookies={},
|
|
1058
|
+
# @max_multipart_length=134217728,
|
|
1059
|
+
# @multipart=false,
|
|
1060
|
+
# @options={accept_charset: #<Encoding:UTF-8>, max_multipart_length: 134217728},
|
|
1061
|
+
# @output_cookies=nil,
|
|
1062
|
+
# @output_hidden=nil,
|
|
1063
|
+
# @params={}>
|
|
816
1064
|
#
|
|
817
1065
|
# With hash argument +options+ given and no block given,
|
|
818
1066
|
# returns a new \CGI object with the given options.
|
|
@@ -852,27 +1100,50 @@ class CGI
|
|
|
852
1100
|
# CGI.new(max_multipart_length: -> {check_filesystem})
|
|
853
1101
|
#
|
|
854
1102
|
# If the option is not given, the default is +134217728+, specifying a maximum size of 128 megabytes.
|
|
855
|
-
#
|
|
856
|
-
# <em>Note:</em> This option configures internal behavior only.
|
|
857
|
-
# There is no public method to retrieve this value after initialization.
|
|
1103
|
+
#
|
|
1104
|
+
# <em>Note:</em> This option configures internal behavior only.
|
|
1105
|
+
# There is no public method to retrieve this value after initialization.
|
|
858
1106
|
#
|
|
859
1107
|
# - <tt>tag_maker: _html_version_</tt>:
|
|
860
|
-
# specifies
|
|
1108
|
+
# specifies a version of HTML;
|
|
1109
|
+
# this determines which tag-generating instance methods
|
|
1110
|
+
# (such as +html+, +head+, +body+, etc.) are to be loaded.
|
|
861
1111
|
#
|
|
862
1112
|
# Value _html_version_ may be one of:
|
|
863
1113
|
#
|
|
864
|
-
# - <tt>'html3'</tt>: {HTML version 3}[https://
|
|
865
|
-
# - <tt>'html4'</tt>: {HTML version 4}[https://
|
|
866
|
-
# - <tt>'html4Tr'</tt>: HTML 4.0 Transitional.
|
|
867
|
-
# - <tt>'html4Fr'</tt>: HTML 4.0 with Framesets.
|
|
868
|
-
# - <tt>'html5'</tt>: {HTML version 5}[https://
|
|
1114
|
+
# - <tt>'html3'</tt>: {HTML version 3}[https://www.w3.org/MarkUp/html3/Contents.html].
|
|
1115
|
+
# - <tt>'html4'</tt>: {HTML version 4}[https://www.w3.org/TR/html4].
|
|
1116
|
+
# - <tt>'html4Tr'</tt>: {HTML 4.0 Transitional}[https://www.w3.org/TR/html4/sgml/loosedtd.html].
|
|
1117
|
+
# - <tt>'html4Fr'</tt>: {HTML 4.0 with Framesets}[https://www.w3.org/TR/html4/present/frames.html].
|
|
1118
|
+
# - <tt>'html5'</tt>: {HTML version 5}[https://html.spec.whatwg.org/multipage].
|
|
869
1119
|
#
|
|
870
1120
|
# Example:
|
|
871
1121
|
#
|
|
872
1122
|
# CGI.new(tag_maker: 'html5')
|
|
873
1123
|
#
|
|
874
|
-
# If the option is not given,
|
|
875
|
-
# no
|
|
1124
|
+
# If the option is not given (or if an invalid value is given),
|
|
1125
|
+
# no tag-generating methods are loaded.
|
|
1126
|
+
#
|
|
1127
|
+
# Examples:
|
|
1128
|
+
#
|
|
1129
|
+
# CGI.new.respond_to?(:html) # => false # Tag-generating methods not loaded.
|
|
1130
|
+
# CGI.new(tag_maker: 'html3').respond_to?(:html) # => true # Tag-generating methods loaded.
|
|
1131
|
+
# # Tag 'button' is new in HTML 4.
|
|
1132
|
+
# CGI.new(tag_maker: 'html3').respond_to?(:button) # => false
|
|
1133
|
+
# CGI.new(tag_maker: 'html4').respond_to?(:button) # => true
|
|
1134
|
+
# # Tag 'canvas' is new in HTML 5.
|
|
1135
|
+
# CGI.new(tag_maker: 'html4').respond_to?(:canvas) # => false
|
|
1136
|
+
# CGI.new(tag_maker: 'html5').respond_to?(:canvas) # => true
|
|
1137
|
+
# # Value is case-sensitive.
|
|
1138
|
+
# CGI.new(tag_maker: 'HTML4').respond_to?(:html) # => false
|
|
1139
|
+
#
|
|
1140
|
+
# You can determine exactly which methods have been loaded;
|
|
1141
|
+
# this example captures the methods loaded by <tt>'html4'</tt>:
|
|
1142
|
+
#
|
|
1143
|
+
# methods_loaded = CGI.new('html4').methods - CGI.new.methods
|
|
1144
|
+
# methods_loaded.size # => 98
|
|
1145
|
+
# methods_loaded.sort.take(10)
|
|
1146
|
+
# # => [:a, :abbr, :acronym, :address, :area, :b, :base, :bdo, :big, :blockquote]
|
|
876
1147
|
#
|
|
877
1148
|
# With string argument +tag_maker+ given as _tag_maker_ and no block given,
|
|
878
1149
|
# equivalent to <tt>CGI.new(tag_maker: _tag_maker_)</tt>:
|
|
@@ -890,6 +1161,28 @@ class CGI
|
|
|
890
1161
|
# from the command line or (failing that) from standard input;
|
|
891
1162
|
# returns a new \CGI object.
|
|
892
1163
|
#
|
|
1164
|
+
# Parameters from command line:
|
|
1165
|
+
#
|
|
1166
|
+
# $ cat t.rb
|
|
1167
|
+
# require 'cgi'
|
|
1168
|
+
# cgi = CGI.new
|
|
1169
|
+
# p cgi.params
|
|
1170
|
+
# ruby t.rb foo=0 bar=1 foo=2 bar=3
|
|
1171
|
+
# {"foo" => ["0", "2"], "bar" => ["1", "3"]}
|
|
1172
|
+
#
|
|
1173
|
+
# Parameters from standard input:
|
|
1174
|
+
#
|
|
1175
|
+
# cgi = CGI.new
|
|
1176
|
+
# (offline mode: enter name=value pairs on standard input)
|
|
1177
|
+
# foo=0
|
|
1178
|
+
# bar=1
|
|
1179
|
+
# ^D
|
|
1180
|
+
# cgi.params
|
|
1181
|
+
# # => {"foo" => ["0"], "bar" => ["1"]}
|
|
1182
|
+
#
|
|
1183
|
+
# The end-of-file character is Ctrl-D on a Unix-like system (as above),
|
|
1184
|
+
# or Ctrl-Z on Windows.
|
|
1185
|
+
#
|
|
893
1186
|
# Otherwise, cookies and other parameters are parsed automatically from the standard CGI locations,
|
|
894
1187
|
# which vary according to the request method.
|
|
895
1188
|
#
|
|
@@ -911,7 +1204,7 @@ class CGI
|
|
|
911
1204
|
#
|
|
912
1205
|
# In this example, the proc simply saves the error:
|
|
913
1206
|
#
|
|
914
|
-
# encoding_errors={}
|
|
1207
|
+
# encoding_errors = {}
|
|
915
1208
|
# CGI.new(accept_charset: 'EUC-JP') do |name,value|
|
|
916
1209
|
# encoding_errors[name] = value
|
|
917
1210
|
# end
|
data/lib/cgi/escape.rb
CHANGED
|
@@ -132,41 +132,32 @@ module CGI::Escape
|
|
|
132
132
|
end
|
|
133
133
|
string = string.b
|
|
134
134
|
string.gsub!(/&(apos|amp|quot|gt|lt|\#[0-9]+|\#[xX][0-9A-Fa-f]+);/) do
|
|
135
|
-
match = $1
|
|
135
|
+
match = $1
|
|
136
136
|
case match
|
|
137
137
|
when 'apos' then "'"
|
|
138
138
|
when 'amp' then '&'
|
|
139
139
|
when 'quot' then '"'
|
|
140
140
|
when 'gt' then '>'
|
|
141
141
|
when 'lt' then '<'
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
n.
|
|
142
|
+
else
|
|
143
|
+
# Numeric character reference. Decode into the binary buffer so that a
|
|
144
|
+
# non-ASCII byte already present in it never triggers an encoding
|
|
145
|
+
# compatibility error on concatenation; the trailing force_encoding
|
|
146
|
+
# re-tags the whole buffer. This mirrors the C extension's
|
|
147
|
+
# optimized_unescape_html.
|
|
148
|
+
n = match.start_with?('#x', '#X') ? match[2..-1].hex : match[1..-1].to_i
|
|
149
|
+
if n >= charlimit
|
|
150
|
+
"&#{match};" # out of range: keep the reference verbatim
|
|
151
|
+
elsif charlimit > 256
|
|
152
|
+
[n].pack('U').b # UTF-8: code point bytes, surrogates included (like rb_enc_mbcput)
|
|
153
153
|
else
|
|
154
|
-
|
|
154
|
+
n.chr.b # ISO-8859-1 / ASCII: single byte
|
|
155
155
|
end
|
|
156
|
-
else
|
|
157
|
-
"&#{match};"
|
|
158
156
|
end
|
|
159
157
|
end
|
|
160
158
|
string.force_encoding enc
|
|
161
159
|
end
|
|
162
160
|
|
|
163
|
-
# Synonym for CGI.escapeHTML(str)
|
|
164
|
-
alias escape_html escapeHTML
|
|
165
|
-
alias h escapeHTML
|
|
166
|
-
|
|
167
|
-
# Synonym for CGI.unescapeHTML(str)
|
|
168
|
-
alias unescape_html unescapeHTML
|
|
169
|
-
|
|
170
161
|
# TruffleRuby runs the pure-Ruby variant faster, do not use the C extension there
|
|
171
162
|
unless RUBY_ENGINE == 'truffleruby'
|
|
172
163
|
begin
|
|
@@ -175,6 +166,14 @@ module CGI::Escape
|
|
|
175
166
|
end
|
|
176
167
|
end
|
|
177
168
|
|
|
169
|
+
# Aliases must be defined on EscapeExt so they resolve to the C methods.
|
|
170
|
+
target = defined?(CGI::EscapeExt) && CGI::EscapeExt.method_defined?(:escapeHTML) ? CGI::EscapeExt : self
|
|
171
|
+
target.module_eval do
|
|
172
|
+
alias escape_html escapeHTML
|
|
173
|
+
alias h escapeHTML
|
|
174
|
+
alias unescape_html unescapeHTML
|
|
175
|
+
end
|
|
176
|
+
|
|
178
177
|
# Escape only the tags of certain HTML elements in +string+.
|
|
179
178
|
#
|
|
180
179
|
# Takes an element or elements or array of elements. Each element
|
data/lib/cgi/session.rb
CHANGED
|
@@ -206,19 +206,28 @@ class CGI
|
|
|
206
206
|
# on Unix systems).
|
|
207
207
|
# prefix:: the prefix to add to the session id when generating
|
|
208
208
|
# the filename for this session's FileStore file.
|
|
209
|
-
# Defaults to
|
|
209
|
+
# Defaults to the empty string.
|
|
210
210
|
# suffix:: the prefix to add to the session id when generating
|
|
211
211
|
# the filename for this session's FileStore file.
|
|
212
212
|
# Defaults to the empty string.
|
|
213
|
+
# digest:: the digest algorithm to hash the session id when
|
|
214
|
+
# generating the filename for this session's FileStore
|
|
215
|
+
# file. Defaults to "SHA256".
|
|
216
|
+
# length:: the length of the session id part of the filestore,
|
|
217
|
+
# excluding +prefix+ and +suffix+ parts. Defaults to 16.
|
|
213
218
|
def new_store_file(option={}) # :nodoc:
|
|
214
219
|
dir = option['tmpdir'] || Dir::tmpdir
|
|
215
220
|
prefix = option['prefix']
|
|
216
221
|
suffix = option['suffix']
|
|
217
|
-
|
|
218
|
-
|
|
222
|
+
algorithm = option['digest'] || 'SHA256'
|
|
223
|
+
if String === algorithm
|
|
224
|
+
require 'digest'
|
|
225
|
+
algorithm = Digest(algorithm)
|
|
226
|
+
end
|
|
227
|
+
digest = algorithm.hexdigest(session_id)[0, option['length'] || 16]
|
|
219
228
|
path = dir+"/"
|
|
220
229
|
path << prefix if prefix
|
|
221
|
-
path <<
|
|
230
|
+
path << digest
|
|
222
231
|
path << suffix if suffix
|
|
223
232
|
if File::exist? path
|
|
224
233
|
hash = nil
|
|
@@ -410,6 +419,9 @@ class CGI
|
|
|
410
419
|
# suffix:: the prefix to add to the session id when generating
|
|
411
420
|
# the filename for this session's FileStore file.
|
|
412
421
|
# Defaults to the empty string.
|
|
422
|
+
# digest:: the digest algorithm to hash the session id when
|
|
423
|
+
# generating the filename for this session's FileStore
|
|
424
|
+
# file. Defaults to "MD5".
|
|
413
425
|
#
|
|
414
426
|
# This session's FileStore file will be created if it does
|
|
415
427
|
# not exist, or opened if it does.
|
data/lib/cgi.rb
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
# The file CGI::Session provides session management functionality; see that
|
|
27
27
|
# class for more details.
|
|
28
28
|
#
|
|
29
|
-
# See
|
|
29
|
+
# See https://www.w3.org/CGI/ for more information on the CGI protocol.
|
|
30
30
|
#
|
|
31
31
|
# == Introduction
|
|
32
32
|
#
|
|
@@ -300,7 +300,7 @@
|
|
|
300
300
|
|
|
301
301
|
class CGI
|
|
302
302
|
# The version string
|
|
303
|
-
VERSION = "0.5.
|
|
303
|
+
VERSION = "0.5.2"
|
|
304
304
|
end
|
|
305
305
|
|
|
306
306
|
require 'cgi/util'
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cgi
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Yukihiro Matsumoto
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 2026-06-23 00:00:00.000000000 Z
|
|
11
11
|
dependencies: []
|
|
12
12
|
description: Support for the Common Gateway Interface protocol.
|
|
13
13
|
email:
|
|
@@ -38,6 +38,7 @@ licenses:
|
|
|
38
38
|
metadata:
|
|
39
39
|
homepage_uri: https://github.com/ruby/cgi
|
|
40
40
|
source_code_uri: https://github.com/ruby/cgi
|
|
41
|
+
changelog_uri: https://github.com/ruby/cgi/releases
|
|
41
42
|
rdoc_options: []
|
|
42
43
|
require_paths:
|
|
43
44
|
- lib
|