nitro 0.13.0 → 0.14.0

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.
Files changed (64) hide show
  1. data/CHANGELOG +91 -1632
  2. data/INSTALL +44 -0
  3. data/README +1 -1
  4. data/Rakefile +3 -3
  5. data/doc/CHANGELOG.2 +1688 -0
  6. data/doc/RELEASES +84 -1
  7. data/examples/blog/cache/entriesadmin +12 -0
  8. data/examples/blog/conf/apache.conf.new +53 -0
  9. data/examples/blog/conf/lhttpd.conf +23 -180
  10. data/examples/blog/log/apache.error_log +271 -0
  11. data/examples/blog/log/rewrite_log +161 -0
  12. data/examples/blog/public/fcgi.rb +2 -0
  13. data/examples/blog/run.rb +4 -3
  14. data/examples/blog/src/controller.rb +10 -4
  15. data/examples/blog/src/views/index.xhtml +3 -0
  16. data/examples/blog/src/xsl/base.xsl +7 -0
  17. data/examples/no_xsl_blog/conf/lhttpd.conf +24 -181
  18. data/examples/tiny/conf/lhttpd.conf +24 -181
  19. data/examples/tiny/log/apache.error_log +24 -0
  20. data/examples/tiny/public/index.xhtml +0 -6
  21. data/examples/tiny/public/upload.xhtml +12 -14
  22. data/examples/wee_style/run.rb +2 -0
  23. data/examples/why_wiki/run.rb +2 -0
  24. data/lib/nitro.rb +2 -2
  25. data/lib/nitro/adapters/cgi.rb +36 -109
  26. data/lib/nitro/adapters/webrick.rb +76 -62
  27. data/lib/nitro/caching.rb +29 -0
  28. data/lib/nitro/caching/actions.rb +67 -0
  29. data/lib/nitro/caching/fragments.rb +72 -0
  30. data/lib/nitro/caching/invalidation.rb +51 -0
  31. data/lib/nitro/caching/output.rb +72 -0
  32. data/lib/nitro/caching/stores.rb +84 -0
  33. data/lib/nitro/controller.rb +3 -1
  34. data/lib/nitro/dispatcher.rb +0 -1
  35. data/lib/nitro/filters.rb +112 -55
  36. data/lib/nitro/mail.rb +6 -3
  37. data/lib/nitro/render.rb +27 -4
  38. data/lib/nitro/request.rb +13 -1
  39. data/test/nitro/tc_controller.rb +6 -4
  40. data/test/nitro/tc_filters.rb +111 -0
  41. metadata +19 -29
  42. data/examples/why_wiki/wiki.yml +0 -1
  43. data/vendor/README +0 -11
  44. data/vendor/binding_of_caller.rb +0 -81
  45. data/vendor/blankslate.rb +0 -53
  46. data/vendor/breakpoint.rb +0 -523
  47. data/vendor/breakpoint_client.rb +0 -196
  48. data/vendor/extensions/_base.rb +0 -153
  49. data/vendor/extensions/_template.rb +0 -36
  50. data/vendor/extensions/all.rb +0 -21
  51. data/vendor/extensions/array.rb +0 -68
  52. data/vendor/extensions/binding.rb +0 -224
  53. data/vendor/extensions/class.rb +0 -50
  54. data/vendor/extensions/continuation.rb +0 -71
  55. data/vendor/extensions/enumerable.rb +0 -250
  56. data/vendor/extensions/hash.rb +0 -23
  57. data/vendor/extensions/io.rb +0 -58
  58. data/vendor/extensions/kernel.rb +0 -42
  59. data/vendor/extensions/module.rb +0 -114
  60. data/vendor/extensions/numeric.rb +0 -230
  61. data/vendor/extensions/object.rb +0 -164
  62. data/vendor/extensions/ostruct.rb +0 -41
  63. data/vendor/extensions/string.rb +0 -316
  64. data/vendor/extensions/symbol.rb +0 -28
@@ -1,43 +1,35 @@
1
- # lighttpd configuration file
1
+ # Lighttpd configuration file
2
2
  # $Id$
3
3
 
4
- ############ Options you really have to take care of ####################
4
+ server.port = 9999
5
+ server.bind = "127.0.0.1"
6
+ # server.event-handler = "freebsd-kqueue" # needed on OS X
5
7
 
6
- ## modules to load
7
- # at least mod_access and mod_accesslog should be loaded
8
- # all other module should only be loaded if really neccesary
9
- # - saves some time
10
- # - saves memory
8
+ server.modules = ( "mod_rewrite", "mod_fastcgi", "mod_access", "mod_accesslog" )
11
9
 
12
- server.modules = (
13
- "mod_rewrite",
14
- # "mod_redirect",
15
- "mod_access",
16
- # "mod_auth",
17
- # "mod_status",
18
- "mod_fastcgi",
19
- # "mod_simple_vhost",
20
- # "mod_evhost",
21
- # "mod_cgi",
22
- # "mod_compress",
23
- # "mod_ssi",
24
- # "mod_usertrack",
25
- # "mod_rrdtool",
26
- "mod_accesslog"
27
- )
10
+ server.document-root = "/home/gmosx/navel/nitro/examples/tiny/public/"
11
+ server.errorlog = "/home/gmosx/navel/nitro/examples/tiny/log/lighttpd.error.log"
12
+ accesslog.filename = "/home/gmosx/navel/nitro/examples/tiny/log/access.log"
28
13
 
29
- ## a static document-root, for virtual-hosting take look at the
30
- ## server.virtual-* options
31
- server.document-root = "/home/gmosx/navel/nitro/examples/tiny/root/"
14
+ server.indexfiles = ( "index.html" )
15
+ url.access-deny = ( "~", ".inc" )
32
16
 
33
- ## where to send error-messages to
34
- server.errorlog = "/home/gmosx/navel/nitro/examples/tiny/log/lighttpd.error.log"
17
+ url.rewrite = ( "^/$" => "index.html", "^([^.]+)$" => "$1.html" )
18
+ server.error-handler-404 = "/fcgi.rb"
35
19
 
36
- # files to check for if .../ is requested
37
- server.indexfiles = ( "index.html" )
20
+ fastcgi.server = ( ".rb" =>
21
+ ( "localhost" =>
22
+ (
23
+ "min-procs" => 1,
24
+ "max-procs" => 1,
25
+ "socket" => "/tmp/tiny.fcgi.socket",
26
+ "bin-path" => "/home/gmosx/navel/nitro/examples/tiny/public/fcgi.rb",
27
+ "bin-environment" => ( "NITRO_ENV" => "development" )
28
+ )
29
+ )
30
+ )
38
31
 
39
- # mimetype mapping
40
- mimetype.assign = (
32
+ mimetype.assign = (
41
33
  ".pdf" => "application/pdf",
42
34
  ".sig" => "application/pgp-signature",
43
35
  ".spl" => "application/futuresplash",
@@ -84,153 +76,4 @@ mimetype.assign = (
84
76
  ".asf" => "video/x-ms-asf",
85
77
  ".asx" => "video/x-ms-asf",
86
78
  ".wmv" => "video/x-ms-wmv"
87
- )
88
-
89
- # Use the "Content-Type" extended attribute to obtain mime type if possible
90
- # mimetypes.use-xattr = "enable"
91
-
92
- #### accesslog module
93
- accesslog.filename = "/home/gmosx/navel/nitro/examples/tiny/log/access.log"
94
-
95
- ## deny access the file-extensions
96
- #
97
- # ~ is for backupfiles from vi, emacs, joe, ...
98
- # .inc is often used for code includes which should in general not be part
99
- # of the document-root
100
- url.access-deny = ( "~", ".inc" )
101
-
102
-
103
-
104
- ######### Options that are good to be but not neccesary to be changed #######
105
-
106
- ## bind to port (default: 80)
107
- server.port = 9999
108
-
109
- ## bind to localhost (default: all interfaces)
110
- #server.bind = "grisu.home.kneschke.de"
111
-
112
- ## error-handler for status 404
113
- #server.error-handler-404 = "/error-handler.html"
114
- #server.error-handler-404 = "/error-handler.php"
115
-
116
- ## to help the rc.scripts
117
- # server.pid-file = "/var/run/lighttpd.pid"
118
-
119
-
120
- ###### virtual hosts
121
- ##
122
- ## If you want name-based virtual hosting add the next three settings and load
123
- ## mod_simple_vhost
124
- ##
125
- ## document-root =
126
- ## virtual-server-root + virtual-server-default-host + virtual-server-docroot or
127
- ## virtual-server-root + http-host + virtual-server-docroot
128
- ##
129
- #simple-vhost.server-root = "/home/weigon/wwwroot/servers/"
130
- #simple-vhost.default-host = "grisu.home.kneschke.de"
131
- #simple-vhost.document-root = "/pages/"
132
-
133
-
134
- ##
135
- ## Format: <errorfile-prefix><status>.html
136
- ## -> ..../status-404.html for 'File not found'
137
- #server.errorfile-prefix = "/home/weigon/projects/lighttpd/doc/status-"
138
-
139
- ## virtual directory listings
140
- #server.dir-listing = "enable"
141
-
142
- ## send unhandled HTTP-header headers to error-log
143
- #debug.dump-unknown-headers = "enable"
144
-
145
- ### only root can use these options
146
- #
147
- # chroot() to directory (default: no chroot() )
148
- #server.chroot = "/"
149
-
150
- ## change uid to <uid> (default: don't care)
151
- #server.username = "wwwrun"
152
-
153
- ## change uid to <uid> (default: don't care)
154
- #server.groupname = "wwwrun"
155
-
156
- #### compress module
157
- #compress.cache-dir = "/tmp/lighttpd/cache/compress/"
158
- #compress.filetype = ("text/plain", "text/html")
159
-
160
- #### fastcgi module
161
- ## read fastcgi.txt for more info
162
- fastcgi.server = ( ".rb" =>
163
- ( "localhost" =>
164
- (
165
- "socket" => "/tmp/nitro-fcgi.socket",
166
- "bin-path" => "/home/gmosx/navel/nitro/examples/tiny/root/fcgi.rb"
167
- )
168
- )
169
- )
170
-
171
- #### CGI module
172
- #cgi.assign = ( ".pl" => "/usr/bin/perl",
173
- # ".cgi" => "/usr/bin/perl" )
174
- #
175
-
176
- #### SSL engine
177
- #ssl.engine = "enable"
178
- #ssl.pemfile = "server.pem"
179
-
180
- #### status module
181
- # status.status-url = "/server-status"
182
- # status.config-url = "/server-config"
183
-
184
- #### auth module
185
- ## read authentification.txt for more info
186
- # auth.backend = "plain"
187
- # auth.backend.plain.userfile = "lighttpd.user"
188
- # auth.backend.plain.groupfile = "lighttpd.group"
189
-
190
- # auth.backend.ldap.hostname = "localhost"
191
- # auth.backend.ldap.base-dn = "dc=my-domain,dc=com"
192
- # auth.backend.ldap.filter = "(uid=$)"
193
-
194
- # auth.require = ( "/server-status" =>
195
- # (
196
- # "method" => "digest",
197
- # "realm" => "download archiv",
198
- # "require" => "group=www|user=jan|host=192.168.2.10"
199
- # ),
200
- # "/server-info" =>
201
- # (
202
- # "method" => "digest",
203
- # "realm" => "download archiv",
204
- # "require" => "group=www|user=jan|host=192.168.2.10"
205
- # )
206
- # )
207
-
208
- #### url handling modules (rewrite, redirect, access)
209
-
210
- url.rewrite = (
211
- "^/([\/\-_a-zA-Z0-9]+)?$" => "/fcgi.rb",
212
- "^/([\/\-_a-zA-Z0-9]+)?\?([\-_a-zA-Z0-9=;&%]*)$" => "/fcgi.rb?$2"
213
79
  )
214
-
215
- # url.redirect = ( "^/wishlist/(.+)" => "http://www.123.org/$1" )
216
-
217
- #
218
- # define a pattern for the host url finding
219
- # %% => % sign
220
- # %0 => domain name + tld
221
- # %1 => tld
222
- # %2 => domain name without tld
223
- # %3 => subdomain 1 name
224
- # %4 => subdomain 2 name
225
- #
226
- # evhost.path-pattern = "/home/storage/dev/www/%3/htdocs/"
227
-
228
- #### expire module
229
- # expire.url = ( "/buggy/" => "access 2 hours", "/asdhas/" => "access plus 1 seconds 2 minutes")
230
-
231
- #### ssi
232
- # ssi.extension = ( ".shtml" )
233
-
234
- #### rrdtool
235
- # rrdtool.binary = "/usr/bin/rrdtool"
236
- # rrdtool.db-name = "/var/www/lighttpd.rrd"
@@ -128,3 +128,27 @@ DEBUG: Rendering '/include'.
128
128
  DEBUG: Compiling action 'public/include'
129
129
  DEBUG: Transforming 'public/include.xhtml'
130
130
  [Thu Mar 17 12:34:48 2005] [notice] caught SIGTERM, shutting down
131
+ [Fri Mar 25 12:23:00 2005] [notice] Digest: generating secret for digest authentication ...
132
+ [Fri Mar 25 12:23:00 2005] [notice] Digest: done
133
+ [Fri Mar 25 12:23:01 2005] [notice] FastCGI: process manager initialized (pid 4731)
134
+ [Fri Mar 25 12:23:01 2005] [notice] Apache/2.0.53 (Unix) DAV/2 mod_fastcgi/2.4.2 configured -- resuming normal operations
135
+ [Fri Mar 25 12:23:05 2005] [warn] FastCGI: (dynamic) server "/home/gmosx/navel/nitro/examples/tiny/public/fcgi.rb" started (pid 4737)
136
+ DEBUG: Rendering '/'.
137
+ DEBUG: Compiling action 'public/index'
138
+ DEBUG: Transforming 'public/index.xhtml'
139
+ DEBUG: Rendering '/include'.
140
+ DEBUG: Compiling action 'public/include'
141
+ DEBUG: Transforming 'public/include.xhtml'
142
+ DEBUG: Rendering '/'.
143
+ DEBUG: Compiling action 'public/index'
144
+ DEBUG: Transforming 'public/index.xhtml'
145
+ DEBUG: Rendering '/include'.
146
+ DEBUG: Compiling action 'public/include'
147
+ DEBUG: Transforming 'public/include.xhtml'
148
+ DEBUG: Rendering '/'.
149
+ DEBUG: Compiling action 'public/index'
150
+ DEBUG: Transforming 'public/index.xhtml'
151
+ DEBUG: Rendering '/include'.
152
+ DEBUG: Compiling action 'public/include'
153
+ DEBUG: Transforming 'public/include.xhtml'
154
+ [Fri Mar 25 12:24:03 2005] [notice] caught SIGTERM, shutting down
@@ -32,12 +32,7 @@
32
32
  <p>
33
33
  Counter: #{session[:counter]}
34
34
  </p>
35
- <br />
36
-
37
35
  <render href="include" />
38
-
39
- <!--
40
- <p>#{context.headers.collect { |h| "#{h}<br/>" }}</p>
41
36
  <p>
42
37
  <h3>Upload a picture</h3>
43
38
 
@@ -53,6 +48,5 @@
53
48
  <input type="submit" value="Upload" />
54
49
  </form>
55
50
  </p>
56
- -->
57
51
 
58
52
  </html>
@@ -2,22 +2,20 @@
2
2
 
3
3
  <html>
4
4
 
5
- <?r
6
- file = context['file']
5
+ <?r
6
+ file = context['file'].read
7
+ File.open('public/image.png', 'wb') do |f|
8
+ f << file
9
+ end
10
+ ?>
7
11
 
8
- File.open('koko.png', 'wb') do |f|
9
- f << file
10
- end
11
- ?>
12
- <h1>#{context['title']}</h1>
12
+ <h1>#{request['title']}</h1>
13
13
 
14
- <img src="" />
14
+ <p><img src="image.png" /></p>
15
15
 
16
- --- #{context['file'].class}<br />
17
-
18
- #{context.params.keys}
19
- <br />
20
-
21
- #{context.params.values.collect {|v| v.class}.join('<br />')}
16
+ <p>
17
+ <strong>original:</strong> #{request['file'].original_filename}<br />
18
+ <strong>content type:</strong>#{request['file'].content_type}<br />
19
+ </p>
22
20
 
23
21
  </html>
@@ -2,6 +2,8 @@
2
2
  # (c) 2004-2005 Navel, all rights reserved.
3
3
  # $Id: run.rb 266 2005-02-28 14:50:48Z gmosx $
4
4
 
5
+ Dir.chdir File.dirname(__FILE__)
6
+
5
7
  require 'nitro'; include N
6
8
  require 'nitro/adapters/webrick'
7
9
 
@@ -1,6 +1,8 @@
1
1
  # * George Moschovitis <gm@navel.gr>
2
2
  # $Id: run.rb 270 2005-03-07 17:52:16Z gmosx $
3
3
 
4
+ Dir.chdir File.dirname(__FILE__)
5
+
4
6
  require 'cgi'
5
7
  require 'redcloth'
6
8
  require 'yaml/store'
data/lib/nitro.rb CHANGED
@@ -12,7 +12,7 @@
12
12
  #
13
13
  # * George Moschovitis <gm@navel.gr>
14
14
  # (c) 2004-2005 Navel, all rights reserved.
15
- # $Id: nitro.rb 300 2005-03-16 13:23:10Z gmosx $
15
+ # $Id: nitro.rb 326 2005-03-28 11:07:17Z gmosx $
16
16
 
17
17
  require 'glue'
18
18
  require 'glue/logger'
@@ -23,7 +23,7 @@ module Nitro
23
23
 
24
24
  # The version.
25
25
 
26
- Version = '0.13.0'
26
+ Version = '0.14.0'
27
27
 
28
28
  # Library path.
29
29
 
@@ -3,6 +3,8 @@
3
3
  # $Id$
4
4
 
5
5
  require 'cgi'
6
+ require 'stringio'
7
+ require 'tempfile'
6
8
 
7
9
  require 'glue/attribute'
8
10
 
@@ -185,112 +187,38 @@ class CgiUtils
185
187
  %r|\Amultipart/form-data.*boundary=\"?([^\";,]+)\"?|n.match(context.headers['CONTENT_TYPE'])
186
188
  boundary = $1.dup
187
189
  # context.params = read_multipart(boundary, Integer(context.headers['CONTENT_LENGTH']), context.in, context.headers)
188
- parse_multipart(context, boundary)
190
+ context.params = parse_multipart(context, boundary)
189
191
  else
190
192
  case method
191
193
  when :get, :head
192
194
  context.params = CgiUtils.parse_query_string(context.query_string)
193
195
  when :post
194
196
  context.in.binmode # if defined?(context.in.binmode)
195
-
196
- context.params = CgiUtils.parse_query_string(
197
- context.in.read(
198
- Integer(context.headers['CONTENT_LENGTH'])) || '')
197
+ context.params = CgiUtils.parse_query_string(context.in.read(context.content_length) || '')
199
198
  end
200
199
  end
201
200
  end
202
201
 
203
202
  # Parse a multipart request.
203
+ # Adapted from Ruby's cgi.rb
204
204
  #--
205
- # FIXME: implement me, not working
205
+ # TODO: optimize and rationalize this.
206
206
  #++
207
207
 
208
208
  def self.parse_multipart(context, boundary)
209
- io = context.in
210
- env = context.headers
211
-
212
- io.binmode # if defined?(ins.binmode)
213
-
214
- buffer = ''
215
- bufsize = Cgi.buffer_size
216
-
217
- boundary = "--" + boundary
218
- boundary_size = boundary.size + EOL.size
219
-
220
- content_length = context.headers['CONTENT_LENGTH'].to_i
221
-
222
- if content_length > Cgi.max_content_length
223
- raise 'Request content length exceeds limit'
224
- end
225
-
226
- context.params = {}
227
-
228
- status = io.read(boundary_size)
229
-
230
- if (status.nil?) or ( (boundary + EOL) != status )
231
- raise 'Bad content body'
232
- end
209
+ input = context.in
210
+ content_length = context.content_length
211
+ env_table = context.env
233
212
 
234
- content_length -= boundary_size
235
-
236
- head = nil
237
-
238
- loop do
239
- until head and /#{boundary}(?:#{EOL}|--)/n.match(buffer)
240
- if (not head) and /#{EOL}#{EOL}/n.match(buffer)
241
- buffer = buffer.sub(/\A((?:.|\n)*?#{EOL})#{EOL}/n) do
242
- head = $1.dup
243
- ""
244
- end
245
- next
246
- end
247
-
248
- puts "*** #{head}"
249
-
250
- /Content-Disposition:.* filename="?([^\";]*)"?/ni.match(head)
251
- filename = $1
252
- if /Mac/ni.match(env['HTTP_USER_AGENT']) and
253
- /Mozilla/ni.match(env['HTTP_USER_AGENT']) and
254
- (not /MSIE/ni.match(env['HTTP_USER_AGENT']))
255
- filename = CGI::unescape(filename)
256
- end
257
-
258
- puts "--- f: #{filename}"
259
-
260
- if filename
261
- /Content-Type: (.*)/ni.match(head)
262
- content_type = $1 or ''
263
-
264
- puts "--- c: #{content_type}"
265
- end
266
-
267
- chunk = if bufsize < content_length
268
- io.read(bufsize)
269
- else
270
- io.read(content_length)
271
- end
272
-
273
- raise 'Bad content body' unless chunk
274
-
275
-
276
- buffer << chunk
277
- content_length -= chunk.size
278
- end
279
- end
280
- end
281
-
282
- # Parse a multipart request.
283
- # Copied from ruby's cgi.rb
284
-
285
- def self.read_multipart(boundary, content_length, stdinput, env_table)
286
213
  params = Hash.new([])
287
214
  boundary = "--" + boundary
288
215
  buf = ""
289
- bufsize = 10 * 1024
290
216
 
291
- # start multipart/form-data
292
- stdinput.binmode if defined? stdinput.binmode
293
-
217
+ input.binmode if defined? input.binmode
218
+ boundary_size = boundary.size + EOL.size
219
+ content_length -= boundary_size
220
+ status = input.read(boundary_size)
221
+
294
222
  if nil == status
295
223
  raise EOFError, "no content body"
296
224
  elsif boundary + EOL != status
@@ -299,15 +227,13 @@ class CgiUtils
299
227
 
300
228
  loop do
301
229
  head = nil
230
+
302
231
  if 10240 < content_length
303
- require "tempfile"
304
232
  body = Tempfile.new("CGI")
305
233
  else
306
234
  begin
307
- require "stringio"
308
235
  body = StringIO.new
309
236
  rescue LoadError
310
- require "tempfile"
311
237
  body = Tempfile.new("CGI")
312
238
  end
313
239
  end
@@ -328,10 +254,10 @@ class CgiUtils
328
254
  buf[0 ... (buf.size - (EOL + boundary + EOL).size)] = ""
329
255
  end
330
256
 
331
- c = if bufsize < content_length
332
- stdinput.read(bufsize)
257
+ c = if Cgi.buffer_size < content_length
258
+ input.read(Cgi.buffer_size)
333
259
  else
334
- stdinput.read(content_length)
260
+ input.read(content_length)
335
261
  end
336
262
  if c.nil?
337
263
  raise EOFError, "bad content body"
@@ -351,40 +277,41 @@ class CgiUtils
351
277
  body.rewind
352
278
 
353
279
  /Content-Disposition:.* filename="?([^\";]*)"?/ni.match(head)
354
- filename = ($1 or "")
355
- if /Mac/ni.match(env_table['HTTP_USER_AGENT']) and
356
- /Mozilla/ni.match(env_table['HTTP_USER_AGENT']) and
357
- (not /MSIE/ni.match(env_table['HTTP_USER_AGENT']))
358
- filename = CGI::unescape(filename)
359
- end
280
+
281
+ filename = ($1 or "")
282
+
283
+ if /Mac/ni.match(env_table['HTTP_USER_AGENT']) and
284
+ /Mozilla/ni.match(env_table['HTTP_USER_AGENT']) and
285
+ (not /MSIE/ni.match(env_table['HTTP_USER_AGENT']))
286
+ filename = CGI::unescape(filename)
287
+ end
360
288
 
361
289
  /Content-Type: (.*)/ni.match(head)
362
290
  content_type = ($1 or "")
363
291
 
364
292
  (class << body; self; end).class_eval do
365
293
  alias local_path path
366
- define_method(:original_filename) {filename.dup.taint}
367
- define_method(:content_type) {content_type.dup.taint}
294
+ define_method(:original_filename) { filename.dup.taint }
295
+ define_method(:content_type) { content_type.dup.taint }
296
+
297
+ # gmosx: this hides the performance hit!!
298
+ define_method(:to_s) { read }
368
299
  end
369
300
 
370
301
  /Content-Disposition:.* name="?([^\";]*)"?/ni.match(head)
371
302
  name = $1.dup
372
303
 
373
- if name =~ /(.*)\[\]$/
374
- if params.has_name?($1)
375
- params[$1] << body
376
- else
377
- params[$1] = [body]
378
- end
304
+ if params.has_key?(name)
305
+ params[name] = [params[name]] << body
379
306
  else
380
- params[name] = body.nil? ? nil : body
307
+ params[name] = body
381
308
  end
382
-
309
+
383
310
  break if buf.size == 0
384
311
  break if content_length === -1
385
312
  end
386
313
 
387
- params
314
+ return params
388
315
  end
389
316
 
390
317
  end