cgi 0.1.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of cgi might be problematic. Click here for more details.

@@ -0,0 +1,3 @@
1
+ require 'mkmf'
2
+
3
+ create_makefile 'cgi/escape'
@@ -0,0 +1,296 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # cgi.rb - cgi support library
4
+ #
5
+ # Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
6
+ #
7
+ # Copyright (C) 2000 Information-technology Promotion Agency, Japan
8
+ #
9
+ # Author: Wakou Aoyama <wakou@ruby-lang.org>
10
+ #
11
+ # Documentation: Wakou Aoyama (RDoc'd and embellished by William Webber)
12
+ #
13
+
14
+ # == Overview
15
+ #
16
+ # The Common Gateway Interface (CGI) is a simple protocol for passing an HTTP
17
+ # request from a web server to a standalone program, and returning the output
18
+ # to the web browser. Basically, a CGI program is called with the parameters
19
+ # of the request passed in either in the environment (GET) or via $stdin
20
+ # (POST), and everything it prints to $stdout is returned to the client.
21
+ #
22
+ # This file holds the CGI class. This class provides functionality for
23
+ # retrieving HTTP request parameters, managing cookies, and generating HTML
24
+ # output.
25
+ #
26
+ # The file CGI::Session provides session management functionality; see that
27
+ # class for more details.
28
+ #
29
+ # See http://www.w3.org/CGI/ for more information on the CGI protocol.
30
+ #
31
+ # == Introduction
32
+ #
33
+ # CGI is a large class, providing several categories of methods, many of which
34
+ # are mixed in from other modules. Some of the documentation is in this class,
35
+ # some in the modules CGI::QueryExtension and CGI::HtmlExtension. See
36
+ # CGI::Cookie for specific information on handling cookies, and cgi/session.rb
37
+ # (CGI::Session) for information on sessions.
38
+ #
39
+ # For queries, CGI provides methods to get at environmental variables,
40
+ # parameters, cookies, and multipart request data. For responses, CGI provides
41
+ # methods for writing output and generating HTML.
42
+ #
43
+ # Read on for more details. Examples are provided at the bottom.
44
+ #
45
+ # == Queries
46
+ #
47
+ # The CGI class dynamically mixes in parameter and cookie-parsing
48
+ # functionality, environmental variable access, and support for
49
+ # parsing multipart requests (including uploaded files) from the
50
+ # CGI::QueryExtension module.
51
+ #
52
+ # === Environmental Variables
53
+ #
54
+ # The standard CGI environmental variables are available as read-only
55
+ # attributes of a CGI object. The following is a list of these variables:
56
+ #
57
+ #
58
+ # AUTH_TYPE HTTP_HOST REMOTE_IDENT
59
+ # CONTENT_LENGTH HTTP_NEGOTIATE REMOTE_USER
60
+ # CONTENT_TYPE HTTP_PRAGMA REQUEST_METHOD
61
+ # GATEWAY_INTERFACE HTTP_REFERER SCRIPT_NAME
62
+ # HTTP_ACCEPT HTTP_USER_AGENT SERVER_NAME
63
+ # HTTP_ACCEPT_CHARSET PATH_INFO SERVER_PORT
64
+ # HTTP_ACCEPT_ENCODING PATH_TRANSLATED SERVER_PROTOCOL
65
+ # HTTP_ACCEPT_LANGUAGE QUERY_STRING SERVER_SOFTWARE
66
+ # HTTP_CACHE_CONTROL REMOTE_ADDR
67
+ # HTTP_FROM REMOTE_HOST
68
+ #
69
+ #
70
+ # For each of these variables, there is a corresponding attribute with the
71
+ # same name, except all lower case and without a preceding HTTP_.
72
+ # +content_length+ and +server_port+ are integers; the rest are strings.
73
+ #
74
+ # === Parameters
75
+ #
76
+ # The method #params() returns a hash of all parameters in the request as
77
+ # name/value-list pairs, where the value-list is an Array of one or more
78
+ # values. The CGI object itself also behaves as a hash of parameter names
79
+ # to values, but only returns a single value (as a String) for each
80
+ # parameter name.
81
+ #
82
+ # For instance, suppose the request contains the parameter
83
+ # "favourite_colours" with the multiple values "blue" and "green". The
84
+ # following behavior would occur:
85
+ #
86
+ # cgi.params["favourite_colours"] # => ["blue", "green"]
87
+ # cgi["favourite_colours"] # => "blue"
88
+ #
89
+ # If a parameter does not exist, the former method will return an empty
90
+ # array, the latter an empty string. The simplest way to test for existence
91
+ # of a parameter is by the #has_key? method.
92
+ #
93
+ # === Cookies
94
+ #
95
+ # HTTP Cookies are automatically parsed from the request. They are available
96
+ # from the #cookies() accessor, which returns a hash from cookie name to
97
+ # CGI::Cookie object.
98
+ #
99
+ # === Multipart requests
100
+ #
101
+ # If a request's method is POST and its content type is multipart/form-data,
102
+ # then it may contain uploaded files. These are stored by the QueryExtension
103
+ # module in the parameters of the request. The parameter name is the name
104
+ # attribute of the file input field, as usual. However, the value is not
105
+ # a string, but an IO object, either an IOString for small files, or a
106
+ # Tempfile for larger ones. This object also has the additional singleton
107
+ # methods:
108
+ #
109
+ # #local_path():: the path of the uploaded file on the local filesystem
110
+ # #original_filename():: the name of the file on the client computer
111
+ # #content_type():: the content type of the file
112
+ #
113
+ # == Responses
114
+ #
115
+ # The CGI class provides methods for sending header and content output to
116
+ # the HTTP client, and mixes in methods for programmatic HTML generation
117
+ # from CGI::HtmlExtension and CGI::TagMaker modules. The precise version of HTML
118
+ # to use for HTML generation is specified at object creation time.
119
+ #
120
+ # === Writing output
121
+ #
122
+ # The simplest way to send output to the HTTP client is using the #out() method.
123
+ # This takes the HTTP headers as a hash parameter, and the body content
124
+ # via a block. The headers can be generated as a string using the #http_header()
125
+ # method. The output stream can be written directly to using the #print()
126
+ # method.
127
+ #
128
+ # === Generating HTML
129
+ #
130
+ # Each HTML element has a corresponding method for generating that
131
+ # element as a String. The name of this method is the same as that
132
+ # of the element, all lowercase. The attributes of the element are
133
+ # passed in as a hash, and the body as a no-argument block that evaluates
134
+ # to a String. The HTML generation module knows which elements are
135
+ # always empty, and silently drops any passed-in body. It also knows
136
+ # which elements require matching closing tags and which don't. However,
137
+ # it does not know what attributes are legal for which elements.
138
+ #
139
+ # There are also some additional HTML generation methods mixed in from
140
+ # the CGI::HtmlExtension module. These include individual methods for the
141
+ # different types of form inputs, and methods for elements that commonly
142
+ # take particular attributes where the attributes can be directly specified
143
+ # as arguments, rather than via a hash.
144
+ #
145
+ # === Utility HTML escape and other methods like a function.
146
+ #
147
+ # There are some utility tool defined in cgi/util.rb .
148
+ # And when include, you can use utility methods like a function.
149
+ #
150
+ # == Examples of use
151
+ #
152
+ # === Get form values
153
+ #
154
+ # require "cgi"
155
+ # cgi = CGI.new
156
+ # value = cgi['field_name'] # <== value string for 'field_name'
157
+ # # if not 'field_name' included, then return "".
158
+ # fields = cgi.keys # <== array of field names
159
+ #
160
+ # # returns true if form has 'field_name'
161
+ # cgi.has_key?('field_name')
162
+ # cgi.has_key?('field_name')
163
+ # cgi.include?('field_name')
164
+ #
165
+ # CAUTION! cgi['field_name'] returned an Array with the old
166
+ # cgi.rb(included in Ruby 1.6)
167
+ #
168
+ # === Get form values as hash
169
+ #
170
+ # require "cgi"
171
+ # cgi = CGI.new
172
+ # params = cgi.params
173
+ #
174
+ # cgi.params is a hash.
175
+ #
176
+ # cgi.params['new_field_name'] = ["value"] # add new param
177
+ # cgi.params['field_name'] = ["new_value"] # change value
178
+ # cgi.params.delete('field_name') # delete param
179
+ # cgi.params.clear # delete all params
180
+ #
181
+ #
182
+ # === Save form values to file
183
+ #
184
+ # require "pstore"
185
+ # db = PStore.new("query.db")
186
+ # db.transaction do
187
+ # db["params"] = cgi.params
188
+ # end
189
+ #
190
+ #
191
+ # === Restore form values from file
192
+ #
193
+ # require "pstore"
194
+ # db = PStore.new("query.db")
195
+ # db.transaction do
196
+ # cgi.params = db["params"]
197
+ # end
198
+ #
199
+ #
200
+ # === Get multipart form values
201
+ #
202
+ # require "cgi"
203
+ # cgi = CGI.new
204
+ # value = cgi['field_name'] # <== value string for 'field_name'
205
+ # value.read # <== body of value
206
+ # value.local_path # <== path to local file of value
207
+ # value.original_filename # <== original filename of value
208
+ # value.content_type # <== content_type of value
209
+ #
210
+ # and value has StringIO or Tempfile class methods.
211
+ #
212
+ # === Get cookie values
213
+ #
214
+ # require "cgi"
215
+ # cgi = CGI.new
216
+ # values = cgi.cookies['name'] # <== array of 'name'
217
+ # # if not 'name' included, then return [].
218
+ # names = cgi.cookies.keys # <== array of cookie names
219
+ #
220
+ # and cgi.cookies is a hash.
221
+ #
222
+ # === Get cookie objects
223
+ #
224
+ # require "cgi"
225
+ # cgi = CGI.new
226
+ # for name, cookie in cgi.cookies
227
+ # cookie.expires = Time.now + 30
228
+ # end
229
+ # cgi.out("cookie" => cgi.cookies) {"string"}
230
+ #
231
+ # cgi.cookies # { "name1" => cookie1, "name2" => cookie2, ... }
232
+ #
233
+ # require "cgi"
234
+ # cgi = CGI.new
235
+ # cgi.cookies['name'].expires = Time.now + 30
236
+ # cgi.out("cookie" => cgi.cookies['name']) {"string"}
237
+ #
238
+ # === Print http header and html string to $DEFAULT_OUTPUT ($>)
239
+ #
240
+ # require "cgi"
241
+ # cgi = CGI.new("html4") # add HTML generation methods
242
+ # cgi.out do
243
+ # cgi.html do
244
+ # cgi.head do
245
+ # cgi.title { "TITLE" }
246
+ # end +
247
+ # cgi.body do
248
+ # cgi.form("ACTION" => "uri") do
249
+ # cgi.p do
250
+ # cgi.textarea("get_text") +
251
+ # cgi.br +
252
+ # cgi.submit
253
+ # end
254
+ # end +
255
+ # cgi.pre do
256
+ # CGI::escapeHTML(
257
+ # "params: #{cgi.params.inspect}\n" +
258
+ # "cookies: #{cgi.cookies.inspect}\n" +
259
+ # ENV.collect do |key, value|
260
+ # "#{key} --> #{value}\n"
261
+ # end.join("")
262
+ # )
263
+ # end
264
+ # end
265
+ # end
266
+ # end
267
+ #
268
+ # # add HTML generation methods
269
+ # CGI.new("html3") # html3.2
270
+ # CGI.new("html4") # html4.01 (Strict)
271
+ # CGI.new("html4Tr") # html4.01 Transitional
272
+ # CGI.new("html4Fr") # html4.01 Frameset
273
+ # CGI.new("html5") # html5
274
+ #
275
+ # === Some utility methods
276
+ #
277
+ # require 'cgi/util'
278
+ # CGI.escapeHTML('Usage: foo "bar" <baz>')
279
+ #
280
+ #
281
+ # === Some utility methods like a function
282
+ #
283
+ # require 'cgi/util'
284
+ # include CGI::Util
285
+ # escapeHTML('Usage: foo "bar" <baz>')
286
+ # h('Usage: foo "bar" <baz>') # alias
287
+ #
288
+ #
289
+
290
+ class CGI
291
+ end
292
+
293
+ require 'cgi/core'
294
+ require 'cgi/cookie'
295
+ require 'cgi/util'
296
+ CGI.autoload(:HtmlExtension, 'cgi/html')
@@ -0,0 +1,188 @@
1
+ # frozen_string_literal: true
2
+ require_relative 'util'
3
+ class CGI
4
+ # Class representing an HTTP cookie.
5
+ #
6
+ # In addition to its specific fields and methods, a Cookie instance
7
+ # is a delegator to the array of its values.
8
+ #
9
+ # See RFC 2965.
10
+ #
11
+ # == Examples of use
12
+ # cookie1 = CGI::Cookie.new("name", "value1", "value2", ...)
13
+ # cookie1 = CGI::Cookie.new("name" => "name", "value" => "value")
14
+ # cookie1 = CGI::Cookie.new('name' => 'name',
15
+ # 'value' => ['value1', 'value2', ...],
16
+ # 'path' => 'path', # optional
17
+ # 'domain' => 'domain', # optional
18
+ # 'expires' => Time.now, # optional
19
+ # 'secure' => true, # optional
20
+ # 'httponly' => true # optional
21
+ # )
22
+ #
23
+ # cgi.out("cookie" => [cookie1, cookie2]) { "string" }
24
+ #
25
+ # name = cookie1.name
26
+ # values = cookie1.value
27
+ # path = cookie1.path
28
+ # domain = cookie1.domain
29
+ # expires = cookie1.expires
30
+ # secure = cookie1.secure
31
+ # httponly = cookie1.httponly
32
+ #
33
+ # cookie1.name = 'name'
34
+ # cookie1.value = ['value1', 'value2', ...]
35
+ # cookie1.path = 'path'
36
+ # cookie1.domain = 'domain'
37
+ # cookie1.expires = Time.now + 30
38
+ # cookie1.secure = true
39
+ # cookie1.httponly = true
40
+ class Cookie < Array
41
+ @@accept_charset="UTF-8" unless defined?(@@accept_charset)
42
+
43
+ # Create a new CGI::Cookie object.
44
+ #
45
+ # :call-seq:
46
+ # Cookie.new(name_string,*value)
47
+ # Cookie.new(options_hash)
48
+ #
49
+ # +name_string+::
50
+ # The name of the cookie; in this form, there is no #domain or
51
+ # #expiration. The #path is gleaned from the +SCRIPT_NAME+ environment
52
+ # variable, and #secure is false.
53
+ # <tt>*value</tt>::
54
+ # value or list of values of the cookie
55
+ # +options_hash+::
56
+ # A Hash of options to initialize this Cookie. Possible options are:
57
+ #
58
+ # name:: the name of the cookie. Required.
59
+ # value:: the cookie's value or list of values.
60
+ # path:: the path for which this cookie applies. Defaults to the
61
+ # the value of the +SCRIPT_NAME+ environment variable.
62
+ # domain:: the domain for which this cookie applies.
63
+ # expires:: the time at which this cookie expires, as a +Time+ object.
64
+ # secure:: whether this cookie is a secure cookie or not (default to
65
+ # false). Secure cookies are only transmitted to HTTPS
66
+ # servers.
67
+ # httponly:: whether this cookie is a HttpOnly cookie or not (default to
68
+ # false). HttpOnly cookies are not available to javascript.
69
+ #
70
+ # These keywords correspond to attributes of the cookie object.
71
+ def initialize(name = "", *value)
72
+ @domain = nil
73
+ @expires = nil
74
+ if name.kind_of?(String)
75
+ @name = name
76
+ %r|^(.*/)|.match(ENV["SCRIPT_NAME"])
77
+ @path = ($1 or "")
78
+ @secure = false
79
+ @httponly = false
80
+ return super(value)
81
+ end
82
+
83
+ options = name
84
+ unless options.has_key?("name")
85
+ raise ArgumentError, "`name' required"
86
+ end
87
+
88
+ @name = options["name"]
89
+ value = Array(options["value"])
90
+ # simple support for IE
91
+ if options["path"]
92
+ @path = options["path"]
93
+ else
94
+ %r|^(.*/)|.match(ENV["SCRIPT_NAME"])
95
+ @path = ($1 or "")
96
+ end
97
+ @domain = options["domain"]
98
+ @expires = options["expires"]
99
+ @secure = options["secure"] == true
100
+ @httponly = options["httponly"] == true
101
+
102
+ super(value)
103
+ end
104
+
105
+ # Name of this cookie, as a +String+
106
+ attr_accessor :name
107
+ # Path for which this cookie applies, as a +String+
108
+ attr_accessor :path
109
+ # Domain for which this cookie applies, as a +String+
110
+ attr_accessor :domain
111
+ # Time at which this cookie expires, as a +Time+
112
+ attr_accessor :expires
113
+ # True if this cookie is secure; false otherwise
114
+ attr_reader :secure
115
+ # True if this cookie is httponly; false otherwise
116
+ attr_reader :httponly
117
+
118
+ # Returns the value or list of values for this cookie.
119
+ def value
120
+ self
121
+ end
122
+
123
+ # Replaces the value of this cookie with a new value or list of values.
124
+ def value=(val)
125
+ replace(Array(val))
126
+ end
127
+
128
+ # Set whether the Cookie is a secure cookie or not.
129
+ #
130
+ # +val+ must be a boolean.
131
+ def secure=(val)
132
+ @secure = val if val == true or val == false
133
+ @secure
134
+ end
135
+
136
+ # Set whether the Cookie is a httponly cookie or not.
137
+ #
138
+ # +val+ must be a boolean.
139
+ def httponly=(val)
140
+ @httponly = !!val
141
+ end
142
+
143
+ # Convert the Cookie to its string representation.
144
+ def to_s
145
+ val = collect{|v| CGI.escape(v) }.join("&")
146
+ buf = "#{@name}=#{val}".dup
147
+ buf << "; domain=#{@domain}" if @domain
148
+ buf << "; path=#{@path}" if @path
149
+ buf << "; expires=#{CGI::rfc1123_date(@expires)}" if @expires
150
+ buf << "; secure" if @secure
151
+ buf << "; HttpOnly" if @httponly
152
+ buf
153
+ end
154
+
155
+ # Parse a raw cookie string into a hash of cookie-name=>Cookie
156
+ # pairs.
157
+ #
158
+ # cookies = CGI::Cookie.parse("raw_cookie_string")
159
+ # # { "name1" => cookie1, "name2" => cookie2, ... }
160
+ #
161
+ def self.parse(raw_cookie)
162
+ cookies = Hash.new([])
163
+ return cookies unless raw_cookie
164
+
165
+ raw_cookie.split(/;\s?/).each do |pairs|
166
+ name, values = pairs.split('=',2)
167
+ next unless name and values
168
+ name = CGI.unescape(name)
169
+ values ||= ""
170
+ values = values.split('&').collect{|v| CGI.unescape(v,@@accept_charset) }
171
+ if cookies.has_key?(name)
172
+ values = cookies[name].value + values
173
+ end
174
+ cookies[name] = Cookie.new(name, *values)
175
+ end
176
+
177
+ cookies
178
+ end
179
+
180
+ # A summary of cookie string.
181
+ def inspect
182
+ "#<CGI::Cookie: #{self.to_s.inspect}>"
183
+ end
184
+
185
+ end # class Cookie
186
+ end
187
+
188
+