cgi 0.5.0 → 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/ext/cgi/escape/escape.c +1 -1
- data/lib/cgi/cookie.rb +2 -0
- data/lib/cgi/core.rb +512 -139
- data/lib/cgi/escape.rb +25 -22
- data/lib/cgi/html.rb +5 -0
- data/lib/cgi/session.rb +16 -4
- data/lib/cgi/util.rb +1 -0
- data/lib/cgi.rb +61 -50
- 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/ext/cgi/escape/escape.c
CHANGED
|
@@ -45,6 +45,7 @@ escaped_length(VALUE str)
|
|
|
45
45
|
static VALUE
|
|
46
46
|
optimized_escape_html(VALUE str)
|
|
47
47
|
{
|
|
48
|
+
VALUE escaped;
|
|
48
49
|
VALUE vbuf;
|
|
49
50
|
char *buf = ALLOCV_N(char, vbuf, escaped_length(str));
|
|
50
51
|
const char *cstr = RSTRING_PTR(str);
|
|
@@ -63,7 +64,6 @@ optimized_escape_html(VALUE str)
|
|
|
63
64
|
}
|
|
64
65
|
}
|
|
65
66
|
|
|
66
|
-
VALUE escaped;
|
|
67
67
|
if (RSTRING_LEN(str) < (dest - buf)) {
|
|
68
68
|
escaped = rb_str_new(buf, dest - buf);
|
|
69
69
|
preserve_original_state(str, escaped);
|
data/lib/cgi/cookie.rb
CHANGED
|
@@ -40,9 +40,11 @@ class CGI
|
|
|
40
40
|
class Cookie < Array
|
|
41
41
|
@@accept_charset="UTF-8" unless defined?(@@accept_charset)
|
|
42
42
|
|
|
43
|
+
# :stopdoc:
|
|
43
44
|
TOKEN_RE = %r"\A[[!-~]&&[^()<>@,;:\\\"/?=\[\]{}]]+\z"
|
|
44
45
|
PATH_VALUE_RE = %r"\A[[ -~]&&[^;]]*\z"
|
|
45
46
|
DOMAIN_VALUE_RE = %r"\A\.?(?<label>(?!-)[-A-Za-z0-9]+(?<!-))(?:\.\g<label>)*\z"
|
|
47
|
+
# :startdoc:
|
|
46
48
|
|
|
47
49
|
# Create a new CGI::Cookie object.
|
|
48
50
|
#
|
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
|
-
#
|
|
76
|
+
# http_header(content_type = 'text/html') -> string
|
|
77
|
+
# http_header(headers) -> string
|
|
80
78
|
#
|
|
81
|
-
#
|
|
79
|
+
# Creates and returns an HTTP header section as a multi-line string.
|
|
82
80
|
#
|
|
83
|
-
#
|
|
84
|
-
# If this form is used, this string is the <tt>Content-Type</tt>
|
|
85
|
-
# +headers_hash+::
|
|
86
|
-
# A Hash of header values. The following header keys are recognized:
|
|
87
|
-
#
|
|
88
|
-
# type:: The Content-Type header. Defaults to "text/html"
|
|
89
|
-
# charset:: The charset of the body, appended to the Content-Type header.
|
|
90
|
-
# nph:: A boolean value. If true, prepend protocol string and status
|
|
91
|
-
# code, and date; and sets default values for "server" and
|
|
92
|
-
# "connection" if not explicitly set.
|
|
93
|
-
# status::
|
|
94
|
-
# The HTTP status code as a String, returned as the Status header. The
|
|
95
|
-
# values are:
|
|
96
|
-
#
|
|
97
|
-
# OK:: 200 OK
|
|
98
|
-
# PARTIAL_CONTENT:: 206 Partial Content
|
|
99
|
-
# MULTIPLE_CHOICES:: 300 Multiple Choices
|
|
100
|
-
# MOVED:: 301 Moved Permanently
|
|
101
|
-
# REDIRECT:: 302 Found
|
|
102
|
-
# NOT_MODIFIED:: 304 Not Modified
|
|
103
|
-
# BAD_REQUEST:: 400 Bad Request
|
|
104
|
-
# AUTH_REQUIRED:: 401 Authorization Required
|
|
105
|
-
# FORBIDDEN:: 403 Forbidden
|
|
106
|
-
# NOT_FOUND:: 404 Not Found
|
|
107
|
-
# METHOD_NOT_ALLOWED:: 405 Method Not Allowed
|
|
108
|
-
# NOT_ACCEPTABLE:: 406 Not Acceptable
|
|
109
|
-
# LENGTH_REQUIRED:: 411 Length Required
|
|
110
|
-
# PRECONDITION_FAILED:: 412 Precondition Failed
|
|
111
|
-
# SERVER_ERROR:: 500 Internal Server Error
|
|
112
|
-
# NOT_IMPLEMENTED:: 501 Method Not Implemented
|
|
113
|
-
# BAD_GATEWAY:: 502 Bad Gateway
|
|
114
|
-
# VARIANT_ALSO_VARIES:: 506 Variant Also Negotiates
|
|
115
|
-
#
|
|
116
|
-
# server:: The server software, returned as the Server header.
|
|
117
|
-
# connection:: The connection type, returned as the Connection header (for
|
|
118
|
-
# instance, "close".
|
|
119
|
-
# length:: The length of the content that will be sent, returned as the
|
|
120
|
-
# Content-Length header.
|
|
121
|
-
# language:: The language of the content, returned as the Content-Language
|
|
122
|
-
# header.
|
|
123
|
-
# expires:: The time on which the current content expires, as a +Time+
|
|
124
|
-
# object, returned as the Expires header.
|
|
125
|
-
# cookie::
|
|
126
|
-
# A cookie or cookies, returned as one or more Set-Cookie headers. The
|
|
127
|
-
# value can be the literal string of the cookie; a CGI::Cookie object;
|
|
128
|
-
# an Array of literal cookie strings or Cookie objects; or a hash all of
|
|
129
|
-
# whose values are literal cookie strings or Cookie objects.
|
|
130
|
-
#
|
|
131
|
-
# These cookies are in addition to the cookies held in the
|
|
132
|
-
# @output_cookies field.
|
|
133
|
-
#
|
|
134
|
-
# Other headers can also be set; they are appended as key: value.
|
|
135
|
-
#
|
|
136
|
-
# Examples:
|
|
137
|
-
#
|
|
138
|
-
# http_header
|
|
139
|
-
# # Content-Type: text/html
|
|
81
|
+
# The string always includes:
|
|
140
82
|
#
|
|
141
|
-
#
|
|
142
|
-
#
|
|
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:
|
|
138
|
+
#
|
|
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
|
|
143
192
|
#
|
|
144
|
-
#
|
|
145
|
-
#
|
|
146
|
-
#
|
|
147
|
-
#
|
|
148
|
-
#
|
|
149
|
-
#
|
|
150
|
-
#
|
|
151
|
-
#
|
|
152
|
-
#
|
|
153
|
-
#
|
|
154
|
-
#
|
|
155
|
-
#
|
|
156
|
-
#
|
|
157
|
-
#
|
|
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
|
|
223
|
+
#
|
|
224
|
+
# puts cgi.http_header('length' => '4096')
|
|
225
|
+
# Content-Type: text/html
|
|
226
|
+
# Content-Length: 4096
|
|
227
|
+
#
|
|
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
|
|
@@ -384,11 +560,14 @@ class CGI
|
|
|
384
560
|
stdoutput.print(*options)
|
|
385
561
|
end
|
|
386
562
|
|
|
387
|
-
#
|
|
563
|
+
# :call-seq:
|
|
564
|
+
# CGI.parse(query_string) -> hash
|
|
388
565
|
#
|
|
389
|
-
#
|
|
390
|
-
#
|
|
391
|
-
#
|
|
566
|
+
# Returns a new hash built from name/value pairs in the given +query_string+:
|
|
567
|
+
#
|
|
568
|
+
# query = 'foo=0&bar=1&foo=2&bar=3'
|
|
569
|
+
# CGI.parse(query)
|
|
570
|
+
# # => {"foo" => ["0", "2"], "bar" => ["1", "3"]}
|
|
392
571
|
#
|
|
393
572
|
def self.parse(query)
|
|
394
573
|
params = {}
|
|
@@ -478,7 +657,7 @@ class CGI
|
|
|
478
657
|
|
|
479
658
|
##
|
|
480
659
|
# Parses multipart form elements according to
|
|
481
|
-
#
|
|
660
|
+
# https://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2
|
|
482
661
|
#
|
|
483
662
|
# Returns a hash of multipart form parameters with bodies of type StringIO or
|
|
484
663
|
# Tempfile depending on whether the multipart form element exceeds 10 KB
|
|
@@ -629,8 +808,8 @@ class CGI
|
|
|
629
808
|
string = unless ARGV.empty?
|
|
630
809
|
ARGV.join(' ')
|
|
631
810
|
else
|
|
632
|
-
if
|
|
633
|
-
|
|
811
|
+
if stdinput.tty?
|
|
812
|
+
$stderr.print(
|
|
634
813
|
%|(offline mode: enter name=value pairs on standard input)\n|
|
|
635
814
|
)
|
|
636
815
|
end
|
|
@@ -659,13 +838,16 @@ class CGI
|
|
|
659
838
|
# Handles multipart forms (in particular, forms that involve file uploads).
|
|
660
839
|
# Reads query parameters in the @params field, and cookies into @cookies.
|
|
661
840
|
def initialize_query()
|
|
841
|
+
content_length = env_table['CONTENT_LENGTH']
|
|
842
|
+
content_length = nil if content_length == ''
|
|
662
843
|
if ("POST" == env_table['REQUEST_METHOD']) and
|
|
663
844
|
%r|\Amultipart/form-data.*boundary=\"?([^\";,]+)\"?| =~ env_table['CONTENT_TYPE']
|
|
664
845
|
current_max_multipart_length = @max_multipart_length.respond_to?(:call) ? @max_multipart_length.call : @max_multipart_length
|
|
665
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?
|
|
666
848
|
boundary = $1.dup
|
|
667
849
|
@multipart = true
|
|
668
|
-
@params = read_multipart(boundary, Integer(
|
|
850
|
+
@params = read_multipart(boundary, Integer(content_length))
|
|
669
851
|
else
|
|
670
852
|
@multipart = false
|
|
671
853
|
@params = CGI.parse(
|
|
@@ -678,7 +860,11 @@ class CGI
|
|
|
678
860
|
end
|
|
679
861
|
when "POST"
|
|
680
862
|
stdinput.binmode if defined? stdinput.binmode
|
|
681
|
-
|
|
863
|
+
if content_length.nil?
|
|
864
|
+
stdinput.read or ''
|
|
865
|
+
else
|
|
866
|
+
stdinput.read(Integer(content_length)) or ''
|
|
867
|
+
end
|
|
682
868
|
else
|
|
683
869
|
read_from_cmdline
|
|
684
870
|
end.dup.force_encoding(@accept_charset)
|
|
@@ -755,12 +941,75 @@ class CGI
|
|
|
755
941
|
#
|
|
756
942
|
@@accept_charset="UTF-8" if false # needed for rdoc?
|
|
757
943
|
|
|
758
|
-
#
|
|
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=.
|
|
759
949
|
def self.accept_charset
|
|
760
950
|
@@accept_charset
|
|
761
951
|
end
|
|
762
952
|
|
|
763
|
-
#
|
|
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
|
+
#
|
|
764
1013
|
def self.accept_charset=(accept_charset)
|
|
765
1014
|
@@accept_charset=accept_charset
|
|
766
1015
|
end
|
|
@@ -778,75 +1027,199 @@ class CGI
|
|
|
778
1027
|
#
|
|
779
1028
|
@@max_multipart_length= 128 * 1024 * 1024
|
|
780
1029
|
|
|
781
|
-
# Create a new CGI instance.
|
|
782
|
-
#
|
|
783
1030
|
# :call-seq:
|
|
784
|
-
# CGI.new(
|
|
785
|
-
# CGI.new(
|
|
1031
|
+
# CGI.new(options = {}) -> new_cgi
|
|
1032
|
+
# CGI.new(tag_maker) -> new_cgi
|
|
1033
|
+
# CGI.new(options = {}) {|name, value| ... } -> new_cgi
|
|
1034
|
+
# CGI.new(tag_maker) {|name, value| ... } -> new_cgi
|
|
1035
|
+
#
|
|
1036
|
+
# Returns a new \CGI object.
|
|
1037
|
+
#
|
|
1038
|
+
# The behavior of this method depends _strongly_ on whether it is called
|
|
1039
|
+
# within a standard \CGI call environment;
|
|
1040
|
+
# that is, whether <tt>ENV['REQUEST_METHOD']</tt> is defined.
|
|
1041
|
+
#
|
|
1042
|
+
# <b>Within a Standard Call Environment</b>
|
|
1043
|
+
#
|
|
1044
|
+
# This section assumes that <tt>ENV['REQUEST_METHOD']</tt> is defined;
|
|
1045
|
+
# for example:
|
|
1046
|
+
#
|
|
1047
|
+
# ENV['REQUEST_METHOD'] # => "GET"
|
|
1048
|
+
#
|
|
1049
|
+
# With no argument and no block given, returns a new \CGI object with default values:
|
|
1050
|
+
#
|
|
1051
|
+
# cgi = CGI.new
|
|
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={}>
|
|
1064
|
+
#
|
|
1065
|
+
# With hash argument +options+ given and no block given,
|
|
1066
|
+
# returns a new \CGI object with the given options.
|
|
1067
|
+
#
|
|
1068
|
+
# The options may be:
|
|
786
1069
|
#
|
|
1070
|
+
# - <tt>accept_charset: _encoding_</tt>:
|
|
1071
|
+
# specifies the encoding of the received query string.
|
|
787
1072
|
#
|
|
788
|
-
#
|
|
789
|
-
#
|
|
790
|
-
#
|
|
791
|
-
# +options_hash+ form, since it also allows you specify the charset you
|
|
792
|
-
# will accept.
|
|
793
|
-
# <tt>options_hash</tt>::
|
|
794
|
-
# A Hash that recognizes three options:
|
|
1073
|
+
# Value _encoding_ may be
|
|
1074
|
+
# an {Encoding object}[https://docs.ruby-lang.org/en/master/encodings_rdoc.html#label-Encoding+Objects]
|
|
1075
|
+
# or an {encoding name}[https://docs.ruby-lang.org/en/master/encodings_rdoc.html#label-Names+and+Aliases]:
|
|
795
1076
|
#
|
|
796
|
-
#
|
|
797
|
-
# specifies encoding of received query string. If omitted,
|
|
798
|
-
# <tt>@@accept_charset</tt> is used. If the encoding is not valid, a
|
|
799
|
-
# CGI::InvalidEncoding will be raised.
|
|
1077
|
+
# CGI.new(accept_charset: 'EUC-JP')
|
|
800
1078
|
#
|
|
801
|
-
#
|
|
1079
|
+
# If the option is not given,
|
|
1080
|
+
# the default value is the class default encoding.
|
|
802
1081
|
#
|
|
803
|
-
#
|
|
1082
|
+
# <em>Note:</em> The <tt>accept_charset</tt> method returns the HTTP Accept-Charset
|
|
1083
|
+
# header value, not the configured encoding. The configured encoding is used
|
|
1084
|
+
# internally for query string parsing.
|
|
804
1085
|
#
|
|
805
|
-
#
|
|
1086
|
+
# - <tt>max_multipart_length: _size_</tt>:
|
|
1087
|
+
# specifies maximum size (in bytes) of multipart data.
|
|
806
1088
|
#
|
|
807
|
-
#
|
|
1089
|
+
# The _size_ may be:
|
|
808
1090
|
#
|
|
809
|
-
#
|
|
1091
|
+
# - A positive integer.
|
|
1092
|
+
#
|
|
1093
|
+
# CGI.new(max_multipart_length: 1024 * 1024)
|
|
1094
|
+
#
|
|
1095
|
+
#
|
|
1096
|
+
# - A lambda to be evaluated when the request is parsed.
|
|
1097
|
+
# This is useful when determining whether to accept multipart data
|
|
1098
|
+
# (e.g. by consulting a registered user's upload allowance).
|
|
1099
|
+
#
|
|
1100
|
+
# CGI.new(max_multipart_length: -> {check_filesystem})
|
|
1101
|
+
#
|
|
1102
|
+
# If the option is not given, the default is +134217728+, specifying a maximum size of 128 megabytes.
|
|
1103
|
+
#
|
|
1104
|
+
# <em>Note:</em> This option configures internal behavior only.
|
|
1105
|
+
# There is no public method to retrieve this value after initialization.
|
|
1106
|
+
#
|
|
1107
|
+
# - <tt>tag_maker: _html_version_</tt>:
|
|
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.
|
|
1111
|
+
#
|
|
1112
|
+
# Value _html_version_ may be one of:
|
|
1113
|
+
#
|
|
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].
|
|
1119
|
+
#
|
|
1120
|
+
# Example:
|
|
1121
|
+
#
|
|
1122
|
+
# CGI.new(tag_maker: 'html5')
|
|
1123
|
+
#
|
|
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]
|
|
1147
|
+
#
|
|
1148
|
+
# With string argument +tag_maker+ given as _tag_maker_ and no block given,
|
|
1149
|
+
# equivalent to <tt>CGI.new(tag_maker: _tag_maker_)</tt>:
|
|
1150
|
+
#
|
|
1151
|
+
# CGI.new('html5')
|
|
1152
|
+
#
|
|
1153
|
+
# <b>Outside a Standard Call Environment</b>
|
|
1154
|
+
#
|
|
1155
|
+
# This section assumes that <tt>ENV['REQUEST_METHOD']</tt> is not defined;
|
|
1156
|
+
# for example:
|
|
1157
|
+
#
|
|
1158
|
+
# ENV['REQUEST_METHOD'] # => nil
|
|
1159
|
+
#
|
|
1160
|
+
# In this mode, the method reads its parameters
|
|
1161
|
+
# from the command line or (failing that) from standard input;
|
|
1162
|
+
# returns a new \CGI object.
|
|
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"]}
|
|
810
1182
|
#
|
|
811
|
-
#
|
|
812
|
-
#
|
|
813
|
-
# use. If not specified, no HTML generation methods will be loaded.
|
|
1183
|
+
# The end-of-file character is Ctrl-D on a Unix-like system (as above),
|
|
1184
|
+
# or Ctrl-Z on Windows.
|
|
814
1185
|
#
|
|
815
|
-
#
|
|
1186
|
+
# Otherwise, cookies and other parameters are parsed automatically from the standard CGI locations,
|
|
1187
|
+
# which vary according to the request method.
|
|
816
1188
|
#
|
|
817
|
-
#
|
|
818
|
-
# "html4":: HTML 4.0
|
|
819
|
-
# "html4Tr":: HTML 4.0 Transitional
|
|
820
|
-
# "html4Fr":: HTML 4.0 with Framesets
|
|
821
|
-
# "html5":: HTML 5
|
|
1189
|
+
# <b>Options vs Public Methods</b>
|
|
822
1190
|
#
|
|
823
|
-
#
|
|
824
|
-
#
|
|
825
|
-
# a lambda, that will be evaluated when the request is parsed. This
|
|
826
|
-
# allows more complex logic to be set when determining whether to accept
|
|
827
|
-
# multipart data (e.g. consult a registered users upload allowance)
|
|
1191
|
+
# Some initialization options configure internal behavior only and do not provide
|
|
1192
|
+
# corresponding public getter methods:
|
|
828
1193
|
#
|
|
829
|
-
#
|
|
1194
|
+
# - <tt>accept_charset</tt>: Configures internal encoding for parsing.
|
|
1195
|
+
# The <tt>accept_charset</tt> method returns the HTTP Accept-Charset header.
|
|
1196
|
+
# - <tt>max_multipart_length</tt>: Configures internal multipart size limits.
|
|
1197
|
+
# No public getter method is available.
|
|
1198
|
+
# - <tt>tag_maker</tt>: Loads HTML generation methods (publicly accessible).
|
|
830
1199
|
#
|
|
831
|
-
#
|
|
1200
|
+
# <b>Block</b>
|
|
832
1201
|
#
|
|
833
|
-
#
|
|
1202
|
+
# If a block is given, its code is stored as a Proc;
|
|
1203
|
+
# whenever CGI::InvalidEncoding would be raised, the proc is called instead.
|
|
834
1204
|
#
|
|
835
|
-
#
|
|
836
|
-
# If provided, the block is called when an invalid encoding is
|
|
837
|
-
# encountered. For example:
|
|
1205
|
+
# In this example, the proc simply saves the error:
|
|
838
1206
|
#
|
|
839
|
-
#
|
|
840
|
-
#
|
|
841
|
-
#
|
|
842
|
-
#
|
|
1207
|
+
# encoding_errors = {}
|
|
1208
|
+
# CGI.new(accept_charset: 'EUC-JP') do |name,value|
|
|
1209
|
+
# encoding_errors[name] = value
|
|
1210
|
+
# end
|
|
1211
|
+
# # =>
|
|
1212
|
+
# #<CGI:0x000002b0ec11bcd8
|
|
1213
|
+
# @accept_charset="EUC-JP",
|
|
1214
|
+
# @accept_charset_error_block=#<Proc:0x000002b0ed2ee190 (irb):146>,
|
|
1215
|
+
# @cookies={},
|
|
1216
|
+
# @max_multipart_length=134217728,
|
|
1217
|
+
# @multipart=false,
|
|
1218
|
+
# @options={accept_charset: "EUC-JP", max_multipart_length: 134217728},
|
|
1219
|
+
# @output_cookies=nil,
|
|
1220
|
+
# @output_hidden=nil,
|
|
1221
|
+
# @params={}>
|
|
843
1222
|
#
|
|
844
|
-
# Finally, if the CGI object is not created in a standard CGI call
|
|
845
|
-
# environment (that is, it can't locate REQUEST_METHOD in its environment),
|
|
846
|
-
# then it will run in "offline" mode. In this mode, it reads its parameters
|
|
847
|
-
# from the command line or (failing that) from standard input. Otherwise,
|
|
848
|
-
# cookies and other parameters are parsed automatically from the standard
|
|
849
|
-
# CGI locations, which varies according to the REQUEST_METHOD.
|
|
850
1223
|
def initialize(options = {}, &block) # :yields: name, value
|
|
851
1224
|
@accept_charset_error_block = block_given? ? block : nil
|
|
852
1225
|
@options={
|
data/lib/cgi/escape.rb
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# :stopdoc
|
|
3
4
|
class CGI
|
|
4
5
|
module Escape; end
|
|
5
6
|
include Escape
|
|
6
7
|
extend Escape
|
|
8
|
+
module EscapeExt; end # :nodoc:
|
|
7
9
|
end
|
|
10
|
+
# :startdoc:
|
|
8
11
|
|
|
12
|
+
# Escape/unescape for CGI, HTML, URI.
|
|
9
13
|
module CGI::Escape
|
|
10
14
|
@@accept_charset = Encoding::UTF_8 unless defined?(@@accept_charset)
|
|
11
15
|
|
|
@@ -128,41 +132,32 @@ module CGI::Escape
|
|
|
128
132
|
end
|
|
129
133
|
string = string.b
|
|
130
134
|
string.gsub!(/&(apos|amp|quot|gt|lt|\#[0-9]+|\#[xX][0-9A-Fa-f]+);/) do
|
|
131
|
-
match = $1
|
|
135
|
+
match = $1
|
|
132
136
|
case match
|
|
133
137
|
when 'apos' then "'"
|
|
134
138
|
when 'amp' then '&'
|
|
135
139
|
when 'quot' then '"'
|
|
136
140
|
when 'gt' then '>'
|
|
137
141
|
when 'lt' then '<'
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
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)
|
|
149
153
|
else
|
|
150
|
-
|
|
154
|
+
n.chr.b # ISO-8859-1 / ASCII: single byte
|
|
151
155
|
end
|
|
152
|
-
else
|
|
153
|
-
"&#{match};"
|
|
154
156
|
end
|
|
155
157
|
end
|
|
156
158
|
string.force_encoding enc
|
|
157
159
|
end
|
|
158
160
|
|
|
159
|
-
# Synonym for CGI.escapeHTML(str)
|
|
160
|
-
alias escape_html escapeHTML
|
|
161
|
-
alias h escapeHTML
|
|
162
|
-
|
|
163
|
-
# Synonym for CGI.unescapeHTML(str)
|
|
164
|
-
alias unescape_html unescapeHTML
|
|
165
|
-
|
|
166
161
|
# TruffleRuby runs the pure-Ruby variant faster, do not use the C extension there
|
|
167
162
|
unless RUBY_ENGINE == 'truffleruby'
|
|
168
163
|
begin
|
|
@@ -171,6 +166,14 @@ module CGI::Escape
|
|
|
171
166
|
end
|
|
172
167
|
end
|
|
173
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
|
+
|
|
174
177
|
# Escape only the tags of certain HTML elements in +string+.
|
|
175
178
|
#
|
|
176
179
|
# Takes an element or elements or array of elements. Each element
|
data/lib/cgi/html.rb
CHANGED
|
@@ -1006,27 +1006,32 @@ class CGI
|
|
|
1006
1006
|
|
|
1007
1007
|
end # Html5
|
|
1008
1008
|
|
|
1009
|
+
# HTML version 3 generation class.
|
|
1009
1010
|
class HTML3
|
|
1010
1011
|
include Html3
|
|
1011
1012
|
include HtmlExtension
|
|
1012
1013
|
end
|
|
1013
1014
|
|
|
1015
|
+
# HTML version 4 generation class.
|
|
1014
1016
|
class HTML4
|
|
1015
1017
|
include Html4
|
|
1016
1018
|
include HtmlExtension
|
|
1017
1019
|
end
|
|
1018
1020
|
|
|
1021
|
+
# HTML version 4 transitional generation class.
|
|
1019
1022
|
class HTML4Tr
|
|
1020
1023
|
include Html4Tr
|
|
1021
1024
|
include HtmlExtension
|
|
1022
1025
|
end
|
|
1023
1026
|
|
|
1027
|
+
# HTML version 4 with framesets generation class.
|
|
1024
1028
|
class HTML4Fr
|
|
1025
1029
|
include Html4Tr
|
|
1026
1030
|
include Html4Fr
|
|
1027
1031
|
include HtmlExtension
|
|
1028
1032
|
end
|
|
1029
1033
|
|
|
1034
|
+
# HTML version 5 generation class.
|
|
1030
1035
|
class HTML5
|
|
1031
1036
|
include Html5
|
|
1032
1037
|
include HtmlExtension
|
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/util.rb
CHANGED
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
|
#
|
|
@@ -42,6 +42,17 @@
|
|
|
42
42
|
#
|
|
43
43
|
# Read on for more details. Examples are provided at the bottom.
|
|
44
44
|
#
|
|
45
|
+
# == About the Examples
|
|
46
|
+
#
|
|
47
|
+
# Examples on this page assume that \CGI has been required:
|
|
48
|
+
#
|
|
49
|
+
# require 'cgi'
|
|
50
|
+
#
|
|
51
|
+
# Unless otherwise stated, examples also assume that environment variable 'REQUEST_METHOD' exists
|
|
52
|
+
# (which prevents CGI.new from entering its online mode):
|
|
53
|
+
#
|
|
54
|
+
# ENV.include?('REQUEST_METHOD') # => true
|
|
55
|
+
#
|
|
45
56
|
# == Queries
|
|
46
57
|
#
|
|
47
58
|
# The CGI class dynamically mixes in parameter and cookie-parsing
|
|
@@ -148,59 +159,62 @@
|
|
|
148
159
|
# Escape and unescape methods are defined in cgi/escape.rb.
|
|
149
160
|
# And when include, you can use utility methods like a function.
|
|
150
161
|
#
|
|
151
|
-
# == Examples of
|
|
162
|
+
# == Examples of Use
|
|
152
163
|
#
|
|
153
|
-
# ===
|
|
164
|
+
# === Form Values
|
|
154
165
|
#
|
|
155
|
-
#
|
|
156
|
-
# cgi = CGI.new
|
|
157
|
-
# value = cgi['field_name'] # <== value string for 'field_name'
|
|
158
|
-
# # if not 'field_name' included, then return "".
|
|
159
|
-
# fields = cgi.keys # <== array of field names
|
|
160
|
-
#
|
|
161
|
-
# # returns true if form has 'field_name'
|
|
162
|
-
# cgi.has_key?('field_name')
|
|
163
|
-
# cgi.has_key?('field_name')
|
|
164
|
-
# cgi.include?('field_name')
|
|
166
|
+
# ==== Get Form Values
|
|
165
167
|
#
|
|
166
|
-
#
|
|
167
|
-
#
|
|
168
|
+
# You can use method +cgi.params+ to retrieve form values
|
|
169
|
+
# in a {Hash}[https://docs.ruby-lang.org/en/3.4/Hash.html]:
|
|
168
170
|
#
|
|
169
|
-
#
|
|
170
|
-
#
|
|
171
|
-
#
|
|
171
|
+
# ENV.update(
|
|
172
|
+
# 'REQUEST_METHOD' => 'GET',
|
|
173
|
+
# 'QUERY_STRING' => 'a=111&&b=222&c&d='
|
|
174
|
+
# )
|
|
172
175
|
# cgi = CGI.new
|
|
173
|
-
# params
|
|
174
|
-
#
|
|
175
|
-
#
|
|
176
|
-
#
|
|
177
|
-
# cgi.params['
|
|
178
|
-
# cgi.params['
|
|
179
|
-
#
|
|
180
|
-
#
|
|
181
|
-
#
|
|
182
|
-
#
|
|
183
|
-
#
|
|
184
|
-
#
|
|
185
|
-
#
|
|
186
|
-
#
|
|
187
|
-
#
|
|
188
|
-
#
|
|
176
|
+
# cgi.params.class # => Hash
|
|
177
|
+
# cgi.params # => {"a" => ["111"], "b" => ["222"], "c" => [], "d" => [""]}
|
|
178
|
+
# cgi.params.keys # => ["a", "b", "c", "d"]
|
|
179
|
+
# cgi.params['a'] # => ["111"] # Returns an array.
|
|
180
|
+
# cgi.params['d'] # => [""] # Returns empty string in array if no value.
|
|
181
|
+
# cgi.params['x'] # => [] # Returns empty array if no key.
|
|
182
|
+
#
|
|
183
|
+
# A \CGI instance has these convenience methods:
|
|
184
|
+
#
|
|
185
|
+
# # Convenience method for cgi.params.keys.
|
|
186
|
+
# cgi.keys # => ["a", "b", "c", "d"]
|
|
187
|
+
# # Convenience method for cgi.params[key].first.
|
|
188
|
+
# cgi['a'] # => "111" # Returns string, not array.
|
|
189
|
+
# cgi['d'] # => "" # Returns empty string if no value.
|
|
190
|
+
# cgi['x'] # => "" # Returns empty string if no key.
|
|
191
|
+
# # Convenience method for cgi.params.include?.
|
|
192
|
+
# cgi.include?('a') # => true
|
|
193
|
+
# cgi.include?('x') # => false
|
|
194
|
+
#
|
|
195
|
+
# ==== Save and Restore Form Values
|
|
196
|
+
#
|
|
197
|
+
# This example uses {Pstore}[https://docs.ruby-lang.org/en/3.4/PStore.html]
|
|
198
|
+
# to store and retrieve form values:
|
|
199
|
+
#
|
|
200
|
+
# ENV.update(
|
|
201
|
+
# 'REQUEST_METHOD' => 'GET',
|
|
202
|
+
# 'QUERY_STRING' => 'a=111&&b=222&c&d='
|
|
203
|
+
# )
|
|
204
|
+
# cgi = CGI.new
|
|
205
|
+
# require 'pstore'
|
|
206
|
+
# store = PStore.new('params.store')
|
|
207
|
+
# store.transaction do
|
|
208
|
+
# store['params'] = cgi.params
|
|
189
209
|
# end
|
|
190
|
-
#
|
|
191
|
-
#
|
|
192
|
-
#
|
|
193
|
-
#
|
|
194
|
-
# require "pstore"
|
|
195
|
-
# db = PStore.new("query.db")
|
|
196
|
-
# db.transaction do
|
|
197
|
-
# cgi.params = db["params"]
|
|
210
|
+
# cgi.params.clear # Oops! Lost my params!
|
|
211
|
+
# store.transaction do
|
|
212
|
+
# cgi.params = store['params']
|
|
198
213
|
# end
|
|
214
|
+
# cgi.params # => {"a" => ["111"], "b" => ["222"], "c" => [], "d" => [""]}
|
|
199
215
|
#
|
|
216
|
+
# ==== Get multipart form values
|
|
200
217
|
#
|
|
201
|
-
# === Get multipart form values
|
|
202
|
-
#
|
|
203
|
-
# require "cgi"
|
|
204
218
|
# cgi = CGI.new
|
|
205
219
|
# value = cgi['field_name'] # <== value string for 'field_name'
|
|
206
220
|
# value.read # <== body of value
|
|
@@ -212,7 +226,6 @@
|
|
|
212
226
|
#
|
|
213
227
|
# === Get cookie values
|
|
214
228
|
#
|
|
215
|
-
# require "cgi"
|
|
216
229
|
# cgi = CGI.new
|
|
217
230
|
# values = cgi.cookies['name'] # <== array of 'name'
|
|
218
231
|
# # if not 'name' included, then return [].
|
|
@@ -222,7 +235,6 @@
|
|
|
222
235
|
#
|
|
223
236
|
# === Get cookie objects
|
|
224
237
|
#
|
|
225
|
-
# require "cgi"
|
|
226
238
|
# cgi = CGI.new
|
|
227
239
|
# for name, cookie in cgi.cookies
|
|
228
240
|
# cookie.expires = Time.now + 30
|
|
@@ -231,14 +243,12 @@
|
|
|
231
243
|
#
|
|
232
244
|
# cgi.cookies # { "name1" => cookie1, "name2" => cookie2, ... }
|
|
233
245
|
#
|
|
234
|
-
# require "cgi"
|
|
235
246
|
# cgi = CGI.new
|
|
236
247
|
# cgi.cookies['name'].expires = Time.now + 30
|
|
237
248
|
# cgi.out("cookie" => cgi.cookies['name']) {"string"}
|
|
238
249
|
#
|
|
239
250
|
# === Print http header and html string to $DEFAULT_OUTPUT ($>)
|
|
240
251
|
#
|
|
241
|
-
# require "cgi"
|
|
242
252
|
# cgi = CGI.new("html4") # add HTML generation methods
|
|
243
253
|
# cgi.out do
|
|
244
254
|
# cgi.html do
|
|
@@ -289,7 +299,8 @@
|
|
|
289
299
|
#
|
|
290
300
|
|
|
291
301
|
class CGI
|
|
292
|
-
|
|
302
|
+
# The version string
|
|
303
|
+
VERSION = "0.5.2"
|
|
293
304
|
end
|
|
294
305
|
|
|
295
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
|