cgialt 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.txt ADDED
@@ -0,0 +1,137 @@
1
+ = README.txt
2
+
3
+ Release: 0.0.1
4
+
5
+ copyright(c) 2007 kuwata-lab.com all rights reserved.
6
+
7
+
8
+ == About
9
+
10
+ 'CGIAlt' is an alternative library of standard 'cgi.rb'.
11
+ It is written in pure Ruby but works faster than 'cgi.rb'.
12
+
13
+
14
+ == Features
15
+
16
+ * Compatible with 'cgi.rb'.
17
+ * Faster and more lightweight than 'cgi.rb'.
18
+ * Available to install with CGIExt (which is a re-implementation of 'cgi.rb'
19
+ in C extension).
20
+
21
+
22
+ == Install
23
+
24
+ Download cgialt-0.0.1.tar.gz and install it according to the following:
25
+
26
+ $ tar xzf cgialt-0.0.1.tar.gz
27
+ $ cd cgialt-0.0.1/
28
+ $ ruby setup.rb config
29
+ $ ruby setup.rb setup
30
+ $ sudo ruby setup.rb install
31
+
32
+ Or if you have installed RubyGems, you can install CGIAlt by 'gem' command.
33
+
34
+ $ sudo gem install cgialt
35
+
36
+ It is recommended not to use RubyGems if you have to develop CGI program
37
+ because loading RubyGems is very heavy-weight for CGI program.
38
+
39
+
40
+ == Usage
41
+
42
+ All you have to do is to require 'cgialt' instead of 'cgi', and you can use
43
+ CGI class which is compatible with 'cgi.rb'.
44
+
45
+ require 'rubygems' # if you have installed with RubyGems
46
+ require 'cgialt'
47
+
48
+ If you want to replace original 'cgi.rb' entirely by 'cgialt',
49
+ create 'cgi.rb' which requires 'cgialt' under proper directory such as
50
+ '/usr/local/lib/ruby/site_ruby/1.8'.
51
+
52
+ $ sudo echo 'require "cgialt"' > /usr/local/lib/ruby/site_ruby/1.8/cgi.rb
53
+
54
+ When $DEBUG is true or ENV['DEBUG'] is set, CGIAlt prints release number
55
+ to $stderr when loaded.
56
+
57
+ $ DEBUG=1 ruby -e 'require "cgi"'
58
+ *** CGIAlt: release 0.0.1
59
+
60
+
61
+ == Benchmark
62
+
63
+ Try 'bench.rb' included in CGIAlt archive.
64
+ The following is an example of benchmark.
65
+
66
+ ## cgi.rb
67
+ $ ruby -s bench.rb -N=1000
68
+ *** 1000 times user system total real
69
+ ruby -e 'nil' 0.0900 0.8300 11.5400 ( 11.9631)
70
+ ruby -e 'require "cgi"' 0.1000 1.2400 24.7000 ( 25.2709)
71
+
72
+ *** 100000 times user system total real
73
+ CGI#new (simple) 20.3100 0.0300 20.3400 ( 20.3770)
74
+ CGI#new (complex) 26.5800 0.0400 26.6200 ( 26.6604)
75
+
76
+ *** 1000000 times user system total real
77
+ CGI#header (simple) 12.6700 0.0100 12.6800 ( 12.7137)
78
+ CGI#header (complex) 43.4600 0.0600 43.5200 ( 43.5749)
79
+
80
+ ## CGIAlt
81
+ $ ruby -s bench.rb -N=1000 -cgialt
82
+ *** CGIAlt: release 0.0.0
83
+ *** 1000 times user system total real
84
+ ruby -e 'nil' 0.0900 0.8000 11.5900 ( 12.0581)
85
+ ruby -e 'require "cgi"' 0.1000 1.2300 19.4800 ( 20.0621)
86
+
87
+ *** 100000 times user system total real
88
+ CGI#new (simple) 14.5000 0.0300 14.5300 ( 14.5594)
89
+ CGI#new (complex) 20.0700 0.0300 20.1000 ( 20.1356)
90
+
91
+ *** 1000000 times user system total real
92
+ CGI#header (simple) 6.0400 0.0100 6.0500 ( 6.0553)
93
+ CGI#header (complex) 36.2200 0.0400 36.2600 ( 36.3138)
94
+
95
+ It is good thing for performance to install CGIExt as well as CGIAlt.
96
+ The following is an benchmark example of using both CGIAlt and CGIExt.
97
+
98
+ ## CGIAlt and CGIExt
99
+ $ ruby -s bench.rb -N=1000 -cgialt -cgiext
100
+ *** CGIAlt: release 0.0.0
101
+ *** 1000 times user system total real
102
+ ruby -e 'nil' 0.0900 0.8100 11.6600 ( 12.1769)
103
+ ruby -e 'require "cgi","cgiext"' 0.1000 1.2100 20.8400 ( 21.5575)
104
+
105
+ *** 100000 times user system total real
106
+ CGI#new (simple) 12.4200 0.0400 12.4600 ( 12.5207)
107
+ CGI#new (complex) 13.1600 0.0300 13.1900 ( 13.2443)
108
+
109
+ *** 1000000 times user system total real
110
+ CGI#header (simple) 6.0300 0.0100 6.0400 ( 6.0651)
111
+ CGI#header (complex) 36.5400 0.0800 36.6200 ( 37.0642)
112
+
113
+ The following is a summary of above benchmark results.
114
+
115
+ Table 1. summary of benchmark
116
+ cgi.rb CGIAlt CGIAlt+CGIExt
117
+ -----------------------------------------------------------------------
118
+ require "cgi" (x1000) 13.16 7.89 9.18
119
+ CGI#new (simple) (x100000) 20.34 14.53 12.46
120
+ CGI#new (comple) (x100000) 26.62 20.10 13.19
121
+ CGI#header (simple) (x1000000) 12.68 6.05 6.04
122
+ CGI#header (complex) (x1000000) 43.52 36.26 36.62
123
+
124
+
125
+ == License
126
+
127
+ Ruby's license
128
+
129
+
130
+ == Authoer
131
+
132
+ makoto kuwata <kwa(at)kuwata-lab.com>
133
+
134
+
135
+ == Bug reports
136
+
137
+ If you have bugs or questions, report them to kwa(at)kuwata-lab.com.
data/bench.rb ADDED
@@ -0,0 +1,245 @@
1
+ ##
2
+ ## $Rev: 30 $
3
+ ## $Release: 0.0.1 $
4
+ ## copyright(c) 2007 kuwata-lab.com all rights reserved.
5
+ ##
6
+
7
+ ##
8
+ ## usage: ruby -s bench.rb [-cgialt] [-cgiext] [-rubygems] [-N=1000]
9
+ ##
10
+
11
+ begin
12
+ require($cgialt ? 'cgialt' : 'cgi')
13
+ rescue LoadError
14
+ begin
15
+ $:.unshift 'lib'
16
+ require($cgialt ? 'cgialt' : 'cgi')
17
+ $rubylib = 'lib'
18
+ rescue LoadError
19
+ require 'rubygems'
20
+ require($cgialt ? 'cgialt' : 'cgi')
21
+ $rubygems = true
22
+ end
23
+ end
24
+
25
+ require 'benchmark'
26
+ require 'cgiext' if $cgiext
27
+ require 'rubygems' if $profile
28
+ require 'ruby-prof' if $profile
29
+
30
+ if defined?(CGI::RELEASE)
31
+ puts "*** CGIAlt: release #{CGI::RELEASE}"
32
+ end
33
+
34
+ $N = ($N || 1000).to_i
35
+
36
+
37
+ class BenchmarkApplication
38
+
39
+
40
+ QUERY_STRING = 'id=123&name=John+Smith&passwd=%40h%3D%7E%2F%5E%24%2F'
41
+ #COOKIE_STRING = "name1=val1&val2&val3; name2=val2&%26%3C%3E%22;_session_id=abcdefg0123456789"
42
+ COOKIE_STRING = '_session_id=e15eb25e3d8f3d51814024aab7ccbca0; dbx-pagemeta=grabit:0-|1-|2-|3-|4-|5-|6-|7-&advancedstuff:0-; dbx-postmeta=grabit:0+|1+|2+|3+|4+|5+|6+&advancedstuff:0-|1-|2-'
43
+ #COOKIE_STRING = "name1=val1&val2&val3"
44
+ SCRIPT_NAME = '/cgi-bin/app/example/command.cgi'
45
+
46
+ def initialize
47
+ @request_method = 'GET'
48
+ @query_string = QUERY_STRING
49
+ @cookie_string = COOKIE_STRING
50
+ @script_name = SCRIPT_NAME
51
+ end
52
+
53
+ def setup
54
+ ENV['REQUEST_METHOD'] = @request_method
55
+ ENV['QUERY_STRING'] = @query_string
56
+ ENV['HTTP_COOKIE'] = @cookie_string
57
+ ENV['SCRIPT_NAME'] = @script_name
58
+ end
59
+
60
+
61
+ def bench_invoke_ruby(ntimes)
62
+ (ntimes/10).times do
63
+ `ruby -e 'nil'`
64
+ `ruby -e 'nil'`
65
+ `ruby -e 'nil'`
66
+ `ruby -e 'nil'`
67
+ `ruby -e 'nil'`
68
+ `ruby -e 'nil'`
69
+ `ruby -e 'nil'`
70
+ `ruby -e 'nil'`
71
+ `ruby -e 'nil'`
72
+ `ruby -e 'nil'`
73
+ end
74
+ end
75
+
76
+ def self._def_bench_require(*names)
77
+ if names.empty?
78
+ method = 'bench_invoke_ruby'
79
+ statement = 'nil'
80
+ else
81
+ method = "bench_require_" + names.join('_')
82
+ statement = names.collect{|name| "require \"#{name}\""}.join('; ')
83
+ end
84
+ statement = "$:.unshift \"#{$rubylib}\"; " + statement if $rubylib
85
+ command_opt = $rubygems ? '-rubygems' : ''
86
+ s = ''
87
+ s << %Q|def #{method}(ntimes)\n|
88
+ s << %Q| (ntimes / 10).times do\n|
89
+ 10.times do
90
+ s << %Q| `ruby #{command_opt} -e '#{statement}'`\n|
91
+ end
92
+ s << %Q| end\n|
93
+ s << %Q|end\n|
94
+ return s
95
+ end
96
+
97
+ eval self._def_bench_require()
98
+ eval self._def_bench_require('cgi')
99
+ eval self._def_bench_require('cgi', 'cgiext')
100
+ eval self._def_bench_require('cgialt')
101
+ eval self._def_bench_require('cgialt', 'cgiext')
102
+
103
+ def bench_cgi_new_simple(ntimes)
104
+ ENV['QUERY_STRING'] = ''
105
+ ENV['COOKIE_STRING'] = ''
106
+ (ntimes / 10).times do
107
+ CGI.new
108
+ CGI.new
109
+ CGI.new
110
+ CGI.new
111
+ CGI.new
112
+ CGI.new
113
+ CGI.new
114
+ CGI.new
115
+ CGI.new
116
+ CGI.new
117
+ end
118
+ end
119
+
120
+ def bench_cgi_new_complex(ntimes)
121
+ ENV['QUERY_STRING'] = @query_string
122
+ ENV['COOKIE_STRING'] = @cookie_string
123
+ (ntimes / 10).times do
124
+ CGI.new
125
+ CGI.new
126
+ CGI.new
127
+ CGI.new
128
+ CGI.new
129
+ CGI.new
130
+ CGI.new
131
+ CGI.new
132
+ CGI.new
133
+ CGI.new
134
+ end
135
+ end
136
+
137
+ def bench_cgi_header_simple(ntimes)
138
+ cgi = CGI.new
139
+ (ntimes / 10).times do
140
+ cgi.header("text/html; charset=utf8")
141
+ cgi.header("text/html; charset=utf8")
142
+ cgi.header("text/html; charset=utf8")
143
+ cgi.header("text/html; charset=utf8")
144
+ cgi.header("text/html; charset=utf8")
145
+ cgi.header("text/html; charset=utf8")
146
+ cgi.header("text/html; charset=utf8")
147
+ cgi.header("text/html; charset=utf8")
148
+ cgi.header("text/html; charset=utf8")
149
+ cgi.header("text/html; charset=utf8")
150
+ end
151
+ return cgi.header("text/html; charset=utf8")
152
+ end
153
+
154
+ def bench_cgi_header_complex(ntimes)
155
+ cgi = CGI.new
156
+ options = {
157
+ 'type' => 'text/xhtml',
158
+ 'charset' => 'utf8',
159
+ 'length' => 1024,
160
+ 'status' => 'REDIRECT',
161
+ 'location' => 'http://www.example.com/',
162
+ 'server' => 'webrick',
163
+ 'language' => 'ja',
164
+ 'Cache-Control' => 'none',
165
+ }
166
+ (ntimes / 10).times do
167
+ cgi.header(options)
168
+ cgi.header(options)
169
+ cgi.header(options)
170
+ cgi.header(options)
171
+ cgi.header(options)
172
+ cgi.header(options)
173
+ cgi.header(options)
174
+ cgi.header(options)
175
+ cgi.header(options)
176
+ cgi.header(options)
177
+ end
178
+ return cgi.header(options)
179
+ end
180
+
181
+
182
+
183
+ def execute
184
+
185
+ method = "bench_require_#{$cgialt ? 'cgialt' : 'cgi'}#{$cgiext ? '_cgiext' : ''}"
186
+ libname = "#{$cgialt ? 'cgialt' : 'cgi'}#{$cgiext ? '","cgiext': ''}"
187
+ cmdopt = $rubygems ? '-rubygems ' : ''
188
+ data = [
189
+ [ 1,
190
+ [ :bench_invoke_ruby, "ruby #{cmdopt}-e 'nil'" ],
191
+ [ method.intern, "ruby #{cmdopt}-e 'require \"#{libname}\"'" ],
192
+ ],
193
+ [ 100,
194
+ [ :bench_cgi_new_simple, 'CGI#new (simple)' ],
195
+ [ :bench_cgi_new_complex, 'CGI#new (complex)' ],
196
+ ],
197
+ [ 1000,
198
+ [ :bench_cgi_header_simple, 'CGI#header (simple)' ],
199
+ [ :bench_cgi_header_complex, 'CGI#header (complex)' ],
200
+ ],
201
+ ]
202
+
203
+ nl = ''
204
+ data.each do |list|
205
+ factor = list.shift
206
+ ntimes = factor * $N
207
+ s = "#{ntimes} times"
208
+ s << ' ' * (32 - s.length)
209
+ header = "*** %s user system total real\n" % s
210
+ format = "%8.3u %8.3y %8.3t %8.3r\n"
211
+ print nl
212
+ nl = "\n"
213
+ Benchmark.benchmark(header, 38, format) do |job|
214
+ list.each do |method, title|
215
+ self.setup()
216
+ output = nil
217
+ if $profile
218
+ result = RubyProf.profile do
219
+ job.report(title) do
220
+ output = self.__send__(method, ntimes)
221
+ end
222
+ end
223
+ outfile = $o || "profile_#{method.to_s.sub(/bench_cgi_/,'')}.html"
224
+ RubyProf::GraphHtmlPrinter.new(result).print(output='')
225
+ File.open(outfile, 'w') {|f| f.write(output) }
226
+ else
227
+ job.report(title) do
228
+ output = self.__send__(method, ntimes)
229
+ end
230
+ end
231
+ if $DEBUG
232
+ #puts "*** debug: "
233
+ output.each {|line| p line }
234
+ end
235
+ end
236
+ end
237
+ end
238
+ end
239
+
240
+ end
241
+
242
+
243
+ if $0 == __FILE__
244
+ BenchmarkApplication.new.execute
245
+ end
data/lib/cgialt.rb ADDED
@@ -0,0 +1,43 @@
1
+ #
2
+ # cgi.rb - cgi support library
3
+ #
4
+ # Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
5
+ #
6
+ # Copyright (C) 2000 Information-technology Promotion Agency, Japan
7
+ #
8
+ # Author: Wakou Aoyama <wakou@ruby-lang.org>
9
+ #
10
+ # Documentation: Wakou Aoyama (RDoc'd and embellished by William Webber)
11
+ #
12
+ # == Overview
13
+ #
14
+ # The Common Gateway Interface (CGI) is a simple protocol
15
+ # for passing an HTTP request from a web server to a
16
+ # standalone program, and returning the output to the web
17
+ # browser. Basically, a CGI program is called with the
18
+ # parameters of the request passed in either in the
19
+ # environment (GET) or via $stdin (POST), and everything
20
+ # it prints to $stdout is returned to the client.
21
+ #
22
+ # This file holds the +CGI+ class. This class provides
23
+ # functionality for retrieving HTTP request parameters,
24
+ # managing cookies, and generating HTML output. See the
25
+ # class documentation for more details and examples of use.
26
+ #
27
+ # The file cgi/session.rb provides session management
28
+ # functionality; see that file for more details.
29
+ #
30
+ # See http://www.w3.org/CGI/ for more information on the CGI
31
+ # protocol.
32
+
33
+ class CGI
34
+ RELEASE = ('$Release: 0.0.1 $' =~ /[.\d]+/) && $&
35
+ if $DEBUG || ENV['DEBUG']
36
+ $stderr.puts "*** CGIAlt: release #{RELEASE}"
37
+ end
38
+ end
39
+
40
+ require 'cgialt/util'
41
+ require 'cgialt/cookie'
42
+ require 'cgialt/core'
43
+ #require 'cgialt/html' # loaded by core only when CGI.new(type) and type != nil
@@ -0,0 +1,245 @@
1
+ ##
2
+ ## copyright(c) 2007 kuwata-lab.com all rights reserved.
3
+ ##
4
+ ## Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
5
+ ##
6
+ ## Copyright (C) 2000 Information-technology Promotion Agency, Japan
7
+ ##
8
+ ## Original Author: Wakou Aoyama <wakou@ruby-lang.org>
9
+ ##
10
+ ## Documentation: Wakou Aoyama (RDoc'd and embellished by William Webber)
11
+ ##
12
+
13
+ class CGI
14
+
15
+ #*** original
16
+ #*require "delegate"
17
+ #***
18
+
19
+ # Class representing an HTTP cookie.
20
+ #
21
+ # In addition to its specific fields and methods, a Cookie instance
22
+ # is a delegator to the array of its values.
23
+ #
24
+ # See RFC 2965.
25
+ #
26
+ # == Examples of use
27
+ # cookie1 = CGI::Cookie::new("name", "value1", "value2", ...)
28
+ # cookie1 = CGI::Cookie::new("name" => "name", "value" => "value")
29
+ # cookie1 = CGI::Cookie::new('name' => 'name',
30
+ # 'value' => ['value1', 'value2', ...],
31
+ # 'path' => 'path', # optional
32
+ # 'domain' => 'domain', # optional
33
+ # 'expires' => Time.now, # optional
34
+ # 'secure' => true # optional
35
+ # )
36
+ #
37
+ # cgi.out("cookie" => [cookie1, cookie2]) { "string" }
38
+ #
39
+ # name = cookie1.name
40
+ # values = cookie1.value
41
+ # path = cookie1.path
42
+ # domain = cookie1.domain
43
+ # expires = cookie1.expires
44
+ # secure = cookie1.secure
45
+ #
46
+ # cookie1.name = 'name'
47
+ # cookie1.value = ['value1', 'value2', ...]
48
+ # cookie1.path = 'path'
49
+ # cookie1.domain = 'domain'
50
+ # cookie1.expires = Time.now + 30
51
+ # cookie1.secure = true
52
+ class Cookie ## DelegateClass(Array) is too high cost!
53
+ #*** original
54
+ #*class Cookie < DelegateClass(Array)
55
+ #*** /original
56
+
57
+ # Create a new CGI::Cookie object.
58
+ #
59
+ # The contents of the cookie can be specified as a +name+ and one
60
+ # or more +value+ arguments. Alternatively, the contents can
61
+ # be specified as a single hash argument. The possible keywords of
62
+ # this hash are as follows:
63
+ #
64
+ # name:: the name of the cookie. Required.
65
+ # value:: the cookie's value or list of values.
66
+ # path:: the path for which this cookie applies. Defaults to the
67
+ # base directory of the CGI script.
68
+ # domain:: the domain for which this cookie applies.
69
+ # expires:: the time at which this cookie expires, as a +Time+ object.
70
+ # secure:: whether this cookie is a secure cookie or not (default to
71
+ # false). Secure cookies are only transmitted to HTTPS
72
+ # servers.
73
+ #
74
+ # These keywords correspond to attributes of the cookie object.
75
+ def initialize(name='', *value)
76
+ rexp = %r|\A.*/|
77
+ if name.is_a?(String)
78
+ @name = name
79
+ @value = value # value is an Array
80
+ @path = rexp.match(ENV['SCRIPT_NAME']) ? $& : ''
81
+ @secure = false
82
+ else
83
+ options = name
84
+ @name = options['name'] or raise ArgumentError, "`name' required"
85
+ @value = Array(options['value'])
86
+ @path = options['path'] || (rexp.match(ENV['SCRIPT_NAME']) ? $& : '') # simple support for IE
87
+ @domain = options['domain']
88
+ @expires = options['expires']
89
+ @secure = options['secure'] == true
90
+ end
91
+ #super(@value)
92
+ end
93
+ #*** original
94
+ #*def initialize(name = "", *value)
95
+ #* options = if name.kind_of?(String)
96
+ #* { "name" => name, "value" => value }
97
+ #* else
98
+ #* name
99
+ #* end
100
+ #* unless options.has_key?("name")
101
+ #* raise ArgumentError, "`name' required"
102
+ #* end
103
+ #*
104
+ #* @name = options["name"]
105
+ #* @value = Array(options["value"])
106
+ #* # simple support for IE
107
+ #* if options["path"]
108
+ #* @path = options["path"]
109
+ #* else
110
+ #* %r|^(.*/)|.match(ENV["SCRIPT_NAME"])
111
+ #* @path = ($1 or "")
112
+ #* end
113
+ #* @domain = options["domain"]
114
+ #* @expires = options["expires"]
115
+ #* @secure = options["secure"] == true ? true : false
116
+ #*
117
+ #* super(@value)
118
+ #*end
119
+ #*** /original
120
+
121
+ attr_accessor :name, :value, :path, :domain, :expires
122
+ attr_reader :secure
123
+ #*** original
124
+ #*attr_accessor("name", "value", "path", "domain", "expires")
125
+ #*attr_reader("secure")
126
+ #*** original
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
+ # Convert the Cookie to its string representation.
137
+ def to_s
138
+ val = @value.is_a?(String) ? CGI.escape(@value) \
139
+ : @value.collect{|v| CGI.escape(v) }.join('&')
140
+ buf = "#{CGI.escape(@name)}=#{val}"
141
+ buf << "; domain=#{@domain}" if @domain
142
+ buf << "; path=#{@path}" if @path
143
+ buf << "; expires=#{CGI.rfc1123_date(@expires)}" if @expires
144
+ buf << "; secure" if @secure == true
145
+ return buf
146
+ end
147
+ #*** original
148
+ #*def to_s
149
+ #* buf = ""
150
+ #* buf += @name + '='
151
+ #*
152
+ #* if @value.kind_of?(String)
153
+ #* buf += CGI::escape(@value)
154
+ #* else
155
+ #* buf += @value.collect{|v| CGI::escape(v) }.join("&")
156
+ #* end
157
+ #*
158
+ #* if @domain
159
+ #* buf += '; domain=' + @domain
160
+ #* end
161
+ #*
162
+ #* if @path
163
+ #* buf += '; path=' + @path
164
+ #* end
165
+ #*
166
+ #* if @expires
167
+ #* buf += '; expires=' + CGI::rfc1123_date(@expires)
168
+ #* end
169
+ #*
170
+ #* if @secure == true
171
+ #* buf += '; secure'
172
+ #* end
173
+ #*
174
+ #* buf
175
+ #*end
176
+ #*** /original
177
+
178
+ ## define methods instead of DelegateClass(Array)
179
+ include Enumerable ##:nodoc:
180
+ def [](*args) ##:nodoc:
181
+ @value[*args]
182
+ end
183
+ def []=(index, value) ##:nodoc:
184
+ @value[index] = value
185
+ end
186
+ def each(&block) ##:nodoc:
187
+ @value.each(&block)
188
+ end
189
+ def method_missing(m, *args) ##:nodoc:
190
+ @value.respond_to?(m) ? @value.__send__(m, *args) : super
191
+ end
192
+ def respond_to?(m) ##:nodoc:
193
+ super(m) || @value.respond_to?(m)
194
+ end
195
+ #def inspect; @value.inspect; end
196
+ #def ==(arg); @value == arg; end
197
+ #def ===(arg); @value === arg; end
198
+
199
+ end # class Cookie
200
+
201
+
202
+ # Parse a raw cookie string into a hash of cookie-name=>Cookie
203
+ # pairs.
204
+ #
205
+ # cookies = CGI::Cookie::parse("raw_cookie_string")
206
+ # # { "name1" => cookie1, "name2" => cookie2, ... }
207
+ #
208
+ def Cookie::parse(raw_cookie)
209
+ cookies = Hash.new([])
210
+ return cookies if !raw_cookie || raw_cookie.empty?
211
+ for pairs in raw_cookie.split(/[;,]\s?/)
212
+ name, value = pairs.split('=', 2)
213
+ next unless name && value
214
+ name = CGI.unescape(name)
215
+ values = value.split('&').collect{|v| CGI.unescape(v) }
216
+ if cookies.has_key?(name)
217
+ cookies[name].value.concat(values)
218
+ else
219
+ cookies[name] = self.new(name, *values)
220
+ end
221
+ end
222
+ return cookies
223
+ end
224
+ #*** original
225
+ #*def Cookie::parse(raw_cookie)
226
+ #* cookies = Hash.new([])
227
+ #* return cookies unless raw_cookie
228
+ #*
229
+ #* raw_cookie.split(/[;,]\s?/).each do |pairs|
230
+ #* name, values = pairs.split('=',2)
231
+ #* next unless name and values
232
+ #* name = CGI::unescape(name)
233
+ #* values ||= ""
234
+ #* values = values.split('&').collect{|v| CGI::unescape(v) }
235
+ #* if cookies.has_key?(name)
236
+ #* values = cookies[name].value + values
237
+ #* end
238
+ #* cookies[name] = Cookie::new({ "name" => name, "value" => values })
239
+ #* end
240
+ #*
241
+ #* cookies
242
+ #*end
243
+ #*** /original
244
+
245
+ end