cgialt 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/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