nitro 0.26.0 → 0.27.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +312 -0
- data/INSTALL +3 -1
- data/ProjectInfo +6 -9
- data/README +32 -5
- data/Rakefile +5 -1
- data/bin/nitrogen +3 -60
- data/doc/MIGRATION +24 -0
- data/doc/RELEASES +141 -0
- data/doc/lhttpd.txt +3 -0
- data/lib/glue/magick.rb +38 -0
- data/lib/glue/thumbnails.rb +3 -0
- data/lib/glue/webfile.rb +137 -0
- data/lib/nitro.rb +1 -1
- data/lib/nitro/adapter/acgi.rb +235 -0
- data/lib/nitro/adapter/cgi.rb +16 -17
- data/lib/nitro/adapter/scgi.rb +4 -4
- data/lib/nitro/adapter/webrick.rb +9 -2
- data/lib/nitro/cgi.rb +49 -49
- data/lib/nitro/cgi/response.rb +4 -0
- data/lib/nitro/cgi/stream.rb +7 -7
- data/lib/nitro/cgi/utils.rb +2 -1
- data/lib/nitro/compiler.rb +47 -4
- data/lib/nitro/compiler/elements.rb +40 -20
- data/lib/nitro/compiler/layout.rb +21 -0
- data/lib/nitro/compiler/localization.rb +3 -1
- data/lib/nitro/compiler/markup.rb +2 -0
- data/lib/nitro/compiler/morphing.rb +16 -4
- data/lib/nitro/compiler/script.rb +109 -0
- data/lib/nitro/context.rb +10 -10
- data/lib/nitro/dispatcher.rb +4 -2
- data/lib/nitro/element.rb +107 -26
- data/lib/nitro/element/{java_script.rb → javascript.rb} +7 -1
- data/lib/nitro/flash.rb +4 -1
- data/lib/nitro/helper.rb +15 -0
- data/lib/nitro/helper/benchmark.rb +8 -2
- data/lib/nitro/helper/form.rb +3 -3
- data/lib/nitro/helper/form/controls.rb +131 -29
- data/lib/nitro/helper/{dojo.rb → form/test.xhtml} +0 -0
- data/lib/nitro/helper/javascript.rb +69 -59
- data/lib/nitro/helper/{scriptaculous.rb → javascript/dojo.rb} +0 -0
- data/lib/nitro/helper/javascript/morphing.rb +163 -0
- data/lib/nitro/helper/javascript/prototype.rb +96 -0
- data/lib/nitro/helper/javascript/scriptaculous.rb +18 -0
- data/lib/nitro/helper/layout.rb +42 -0
- data/lib/nitro/helper/table.rb +190 -27
- data/lib/nitro/{adapter → helper}/wee.rb +9 -3
- data/lib/nitro/render.rb +23 -17
- data/lib/nitro/scaffolding.rb +19 -2
- data/lib/nitro/server.rb +4 -8
- data/lib/nitro/server/runner.rb +28 -6
- data/lib/nitro/session.rb +7 -7
- data/lib/nitro_and_og.rb +2 -0
- data/proto/public/Makefile.acgi +40 -0
- data/proto/public/acgi.c +138 -0
- data/proto/public/js/builder.js +7 -3
- data/proto/public/js/controls.js +32 -12
- data/proto/public/js/dragdrop.js +4 -3
- data/proto/public/js/effects.js +111 -62
- data/proto/public/js/scriptaculous.js +10 -13
- data/proto/public/js/slider.js +88 -31
- data/proto/public/scaffold/new.xhtml +2 -2
- data/setup.rb +1585 -0
- data/src/part/admin.rb +6 -0
- data/src/part/admin/controller.rb +3 -3
- data/src/part/admin/skin.rb +1 -8
- data/test/nitro/adapter/tc_webrick.rb +2 -0
- data/test/nitro/tc_controller_aspect.rb +1 -1
- data/test/nitro/tc_element.rb +5 -6
- data/test/nitro/tc_table.rb +66 -0
- metadata +277 -271
- data/doc/architecture.txt +0 -2
- data/doc/bugs.txt +0 -15
- data/doc/tutorial.txt +0 -26
- data/install.rb +0 -37
- data/lib/nitro/compiler/script_generator.rb +0 -14
- data/lib/nitro/compiler/shaders.rb +0 -206
- data/lib/nitro/helper/prototype.rb +0 -49
- data/lib/nitro/scaffold/relations.rb +0 -54
data/lib/nitro.rb
CHANGED
@@ -0,0 +1,235 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
require 'posixlock'
|
3
|
+
|
4
|
+
STDOUT.sync = STDERR.sync = true
|
5
|
+
$VERBOSE = nil
|
6
|
+
|
7
|
+
require 'nitro/context'
|
8
|
+
require 'nitro/dispatcher'
|
9
|
+
require 'nitro/cgi'
|
10
|
+
|
11
|
+
require 'glue/flexob'
|
12
|
+
|
13
|
+
# Speeds things up, more comaptible with OSX.
|
14
|
+
|
15
|
+
Socket.do_not_reverse_lookup = true
|
16
|
+
|
17
|
+
module Nitro
|
18
|
+
|
19
|
+
# ACGI Adaptor. ACGI is a language independent,
|
20
|
+
# scalable, open extension to CGI that provides high
|
21
|
+
# performance without the limitations of server
|
22
|
+
# specific APIs.
|
23
|
+
#
|
24
|
+
# This code is directly from the author. Please go to
|
25
|
+
# http://codeforpeople.com/lib/ruby/acgi/ for more
|
26
|
+
# information about ACGI.
|
27
|
+
# or email: ara [dot] t [dot] howard [at] noaa [dot] gov
|
28
|
+
#
|
29
|
+
# It uses a compiled C cgi program to handle
|
30
|
+
# connections compile the acgi.c by executing
|
31
|
+
# "make -f Makefile.acgi" in your public/ folder.
|
32
|
+
# then make your .htaccess redirect all calls to acgi.cgi
|
33
|
+
# instead of fcgi.rb / cgi.rb
|
34
|
+
#
|
35
|
+
#--
|
36
|
+
# gmosx: not tested
|
37
|
+
#++
|
38
|
+
|
39
|
+
class ACGI < ::CGI
|
40
|
+
THIS = File::expand_path $0
|
41
|
+
COMMAND_LINE = [THIS, ARGV].join ' '
|
42
|
+
LOADED = Time::now
|
43
|
+
IPC_DIR = "/tmp/acgi_ipc"
|
44
|
+
CLIENT_LOCK_PATH = File::join IPC_DIR, "client.lock"
|
45
|
+
SERVER_LOCK_PATH = File::join IPC_DIR, "server.lock"
|
46
|
+
SERVER_ENVIRONMENT_PATH = File::join IPC_DIR, "server.environment"
|
47
|
+
SERVER_STDIN_PATH = File::join IPC_DIR, "server.stdin"
|
48
|
+
SERVER_STDOUT_PATH = File::join IPC_DIR, "server.stdout"
|
49
|
+
SERVER_STDERR_PATH = File::join IPC_DIR, "server.stderr"
|
50
|
+
SERVER_PID_PATH = File::join IPC_DIR, "server.pid"
|
51
|
+
|
52
|
+
RE_ENV = %r/^ ([^=]+) = (.*) $/ox
|
53
|
+
RE_NUL = %r/#{ Regexp::escape "\0" }/ox
|
54
|
+
|
55
|
+
SERVER = ENV['ACGI_SERVER'] || ARGV.delete('--server') || ARGV.delete('-s')
|
56
|
+
|
57
|
+
if SERVER
|
58
|
+
trap('HUP'){ exec ::ACGI::COMMAND_LINE }
|
59
|
+
%w( INT KILL TERM ).each{|s| trap(s){ exit }}
|
60
|
+
end
|
61
|
+
|
62
|
+
class << self
|
63
|
+
def each_cgi(*a, &b)
|
64
|
+
if SERVER
|
65
|
+
start_server(*a, &b)
|
66
|
+
else
|
67
|
+
munge_environment
|
68
|
+
@cgi = new(*a)
|
69
|
+
catching_errors{ b[ @cgi ] }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def start_server(*a, &b)
|
74
|
+
daemon do
|
75
|
+
ENV.clear # __very__ important for speed!
|
76
|
+
aquire_server_lock
|
77
|
+
record_pid
|
78
|
+
loop do
|
79
|
+
load_environment
|
80
|
+
munge_environment
|
81
|
+
@cgi = redirecting_stdin{ new(*a) }
|
82
|
+
redirecting_stdout_and_stderr{ catching_errors{ b[ @cgi ] }}
|
83
|
+
restart_if_updated
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def restart_if_updated
|
89
|
+
# put the full path to your run.rb here if it doesn't work
|
90
|
+
#th = "/path/to/app/run.rb"
|
91
|
+
if File::stat(THIS).mtime > LOADED
|
92
|
+
#if File::stat(th).mtime > LOADED
|
93
|
+
exec COMMAND_LINE
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def aquire_server_lock
|
98
|
+
lockfile = File.open(SERVER_LOCK_PATH)
|
99
|
+
lockfile.reopen(SERVER_LOCK_PATH, 'w')
|
100
|
+
at_exit{ lockfile.close }
|
101
|
+
ret = lockfile.posixlock(File::LOCK_EX|File::LOCK_NB)
|
102
|
+
|
103
|
+
raise("#{ File::basename $0 } already running..") if(!ret or !ret.zero?)
|
104
|
+
end
|
105
|
+
|
106
|
+
def record_pid
|
107
|
+
begin
|
108
|
+
f = File::open(SERVER_PID_PATH)
|
109
|
+
f.reopen(SERVER_PID_PATH, 'w')
|
110
|
+
f.print Process::pid
|
111
|
+
f.chmod 0777 rescue nil
|
112
|
+
ensure
|
113
|
+
f.close
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def env_table
|
118
|
+
SERVER ? (@environment ||= {}) : ENV
|
119
|
+
end
|
120
|
+
|
121
|
+
def env
|
122
|
+
env_table
|
123
|
+
end
|
124
|
+
|
125
|
+
def load_environment
|
126
|
+
begin
|
127
|
+
f = File::open(SERVER_ENVIRONMENT_PATH)
|
128
|
+
f.reopen(SERVER_ENVIRONMENT_PATH, "r")
|
129
|
+
env_table.clear
|
130
|
+
kvs = f.read.chop.split RE_NUL
|
131
|
+
kvs.each do |kv|
|
132
|
+
m = RE_ENV.match(kv)
|
133
|
+
k, v = m[1], m[2]
|
134
|
+
env_table[k] = v
|
135
|
+
end
|
136
|
+
ensure
|
137
|
+
f.close
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def munge_environment # because CGI::Cookie::parse is broken!
|
142
|
+
env_table['HTTP_COOKIE'] =
|
143
|
+
munge_http_cookie env_table['HTTP_COOKIE']
|
144
|
+
end
|
145
|
+
|
146
|
+
def munge_http_cookie http_cookie
|
147
|
+
return unless http_cookie
|
148
|
+
kvs = http_cookie.split %r/[;,]\s+/o
|
149
|
+
h = Hash::new{|h,k| h[k] = []}
|
150
|
+
kvs.each do |kv|
|
151
|
+
k, v = kv.split %r/=/o, 2
|
152
|
+
next unless k
|
153
|
+
k = CGI::unescape k
|
154
|
+
vs = v.to_s.split(%r/&/).map{|v| CGI::unescape v}
|
155
|
+
h[k].push(*vs)
|
156
|
+
end
|
157
|
+
h.sort.map{|k,vs| [k, vs.join('&')].join('=')}.join('; ')
|
158
|
+
end
|
159
|
+
|
160
|
+
def redirecting_stdin
|
161
|
+
stdin = $stdin
|
162
|
+
begin
|
163
|
+
@stdin = File::open(SERVER_STDIN_PATH)
|
164
|
+
@stdin.reopen(SERVER_STDIN_PATH, "r")
|
165
|
+
$stdin = @stdin
|
166
|
+
yield
|
167
|
+
ensure
|
168
|
+
@stdin.close if @stdin
|
169
|
+
$stdin = stdin
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def redirecting_stdout_and_stderr
|
174
|
+
stdout, stderr = $stdout, $stderr
|
175
|
+
begin
|
176
|
+
@stdout = File::open(SERVER_STDOUT_PATH)
|
177
|
+
@stdout.reopen(SERVER_STDOUT_PATH, "w")
|
178
|
+
@stderr = File::open(SERVER_STDERR_PATH)
|
179
|
+
@stderr.reopen(SERVER_STDERR_PATH, "w")
|
180
|
+
$stdout, $stderr = @stdout, @stderr
|
181
|
+
yield
|
182
|
+
ensure
|
183
|
+
@stdout.close if @stdout
|
184
|
+
@stderr.close if @stderr
|
185
|
+
$stdout, $stderr = stdout, stderr
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
def catching_errors
|
190
|
+
@cgi ||= CGI::new
|
191
|
+
begin
|
192
|
+
yield
|
193
|
+
rescue Exception => e
|
194
|
+
m, c, b = e.message, e.class, e.backtrace.join("<br>\n")
|
195
|
+
@cgi.out{ "<hr><b><i>#{ m } (#{ c })</b></i><hr><hr>#{ b }" }
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
def daemon
|
200
|
+
exit!(0) if fork
|
201
|
+
Process::setsid
|
202
|
+
exit!(0) if fork
|
203
|
+
# Dir::chdir("/")
|
204
|
+
# File::umask(0)
|
205
|
+
|
206
|
+
# uncomment these if you don't want logs
|
207
|
+
#STDIN.reopen("/dev/null")
|
208
|
+
#STDOUT.reopen("/dev/null", "w")
|
209
|
+
#STDERR.reopen("/dev/null", "w")
|
210
|
+
yield if block_given?
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
def env_table
|
215
|
+
self::class.env_table
|
216
|
+
end
|
217
|
+
def env
|
218
|
+
self::class.env
|
219
|
+
end
|
220
|
+
|
221
|
+
# use this to start the ACGI server.
|
222
|
+
|
223
|
+
def self.start(server)
|
224
|
+
ACGI.each_cgi do |cgi|
|
225
|
+
begin
|
226
|
+
Cgi.process(server, cgi, $stdin, $stdout)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
end
|
232
|
+
|
233
|
+
end
|
234
|
+
|
235
|
+
# * Ara Howard <ara.t.howard@noaa.gov>
|
data/lib/nitro/adapter/cgi.rb
CHANGED
@@ -2,12 +2,27 @@ require 'cgi'
|
|
2
2
|
require 'stringio'
|
3
3
|
require 'tempfile'
|
4
4
|
|
5
|
+
#--
|
6
|
+
# Adapt the default CGI object to suit Nitro.
|
7
|
+
#++
|
8
|
+
|
9
|
+
class CGI # :nodoc: all
|
10
|
+
def env
|
11
|
+
ENV
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
5
15
|
# Speeds things up, more comaptible with OSX.
|
6
16
|
|
7
17
|
Socket.do_not_reverse_lookup = true
|
8
18
|
|
9
19
|
module Nitro
|
10
20
|
|
21
|
+
# A plain CGI adapter. To be used only in development
|
22
|
+
# environments, this adapter is *extremely* slow for
|
23
|
+
# live/production environments. This adapter is provided for
|
24
|
+
# the sake of completeness.
|
25
|
+
|
11
26
|
class CgiAdapter
|
12
27
|
#--
|
13
28
|
# No need for connection pooling, CGI uses process.
|
@@ -15,23 +30,8 @@ class CgiAdapter
|
|
15
30
|
|
16
31
|
def self.start(server)
|
17
32
|
cgi = CGI.new
|
18
|
-
def cgi.env
|
19
|
-
env_table
|
20
|
-
end
|
21
33
|
Router.strip_path = cgi.env["SCRIPT_NAME"]
|
22
|
-
Cgi.process(server, cgi,
|
23
|
-
=begin
|
24
|
-
context = Context.new(server)
|
25
|
-
context.headers = ENV
|
26
|
-
|
27
|
-
CgiUtils.parse_params(context)
|
28
|
-
CgiUtils.parse_cookies(context)
|
29
|
-
|
30
|
-
context.render(context.path)
|
31
|
-
|
32
|
-
cgi.print(CgiUtils.response_headers(context))
|
33
|
-
cgi.print(context.out)
|
34
|
-
=end
|
34
|
+
Cgi.process(server, cgi, $stdin, $stdout)
|
35
35
|
end
|
36
36
|
|
37
37
|
end
|
@@ -40,4 +40,3 @@ end
|
|
40
40
|
|
41
41
|
# * James Britt <james_b@neurogami.com>
|
42
42
|
# * George Moschovitis <gm@navel.gr>
|
43
|
-
|
data/lib/nitro/adapter/scgi.rb
CHANGED
@@ -8,7 +8,7 @@ require 'cgi'
|
|
8
8
|
require 'monitor'
|
9
9
|
require 'singleton'
|
10
10
|
|
11
|
-
module SCGI
|
11
|
+
module SCGI # :nodoc: all
|
12
12
|
|
13
13
|
class LogFactory < Monitor
|
14
14
|
include Singleton
|
@@ -62,7 +62,7 @@ module SCGI
|
|
62
62
|
end
|
63
63
|
|
64
64
|
# Modifies CGI so that we can use it.
|
65
|
-
class SCGIFixed < ::CGI
|
65
|
+
class SCGIFixed < ::CGI # :nodoc: all
|
66
66
|
public :env_table
|
67
67
|
|
68
68
|
def initialize(params, data, out, *args)
|
@@ -87,7 +87,7 @@ module SCGI
|
|
87
87
|
end
|
88
88
|
|
89
89
|
|
90
|
-
class SCGIProcessor < Monitor
|
90
|
+
class SCGIProcessor < Monitor # :nodoc: all
|
91
91
|
attr_reader :settings
|
92
92
|
|
93
93
|
def initialize(settings = {})
|
@@ -243,4 +243,4 @@ module SCGI
|
|
243
243
|
end
|
244
244
|
|
245
245
|
# * Zed A Shaw <zedshaw@zedshaw.com>
|
246
|
-
# * George Moschovitis <gm@navel.gr>
|
246
|
+
# * George Moschovitis <gm@navel.gr>
|
@@ -80,7 +80,13 @@ class XhtmlFileHandler < WEBrick::HTTPServlet::DefaultFileHandler
|
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
83
|
-
# A Webrick Adapter for Nitro.
|
83
|
+
# A Webrick Adapter for Nitro. Webrick is a pure Ruby web server
|
84
|
+
# included in the default Ruby distribution. The Webrick Adapter
|
85
|
+
# is the prefered adapter in development/debug environments. It
|
86
|
+
# is also extremely easy to setup.
|
87
|
+
#
|
88
|
+
# However, for live/production environments, you should prefer
|
89
|
+
# a more performant adapter like FCGI or SCGI.
|
84
90
|
|
85
91
|
class WebrickAdapter < WEBrick::HTTPServlet::AbstractServlet
|
86
92
|
include WEBrick
|
@@ -152,6 +158,7 @@ class WebrickAdapter < WEBrick::HTTPServlet::AbstractServlet
|
|
152
158
|
|
153
159
|
context.close
|
154
160
|
ensure
|
161
|
+
$autoreload_dirty = false
|
155
162
|
Og.manager.put_store if defined?(Og) and Og.respond_to?(:manager)
|
156
163
|
end
|
157
164
|
end
|
@@ -186,4 +193,4 @@ end
|
|
186
193
|
|
187
194
|
# * George Moschovitis <gm@navel.gr>
|
188
195
|
# * Guillaume Pierronnet <guillaume.pierronnet@laposte.net>
|
189
|
-
# * Bryan Soto <bryan.a.soto@gmail.com>
|
196
|
+
# * Bryan Soto <bryan.a.soto@gmail.com>
|
data/lib/nitro/cgi.rb
CHANGED
@@ -5,6 +5,9 @@ require 'nitro/cgi/http'
|
|
5
5
|
|
6
6
|
module Nitro
|
7
7
|
|
8
|
+
# Nitro CGI (Common Gateway Interface) methods. Typically
|
9
|
+
# handles HTTP Request parsing and HTTP Response generation.
|
10
|
+
|
8
11
|
class Cgi
|
9
12
|
include Http
|
10
13
|
|
@@ -25,39 +28,55 @@ class Cgi
|
|
25
28
|
context.in = inp
|
26
29
|
context.headers = cgi.env
|
27
30
|
|
28
|
-
|
31
|
+
#--
|
32
|
+
# gmosx: only handle nitro requests.
|
33
|
+
#++
|
34
|
+
if context.path !~ /\./
|
35
|
+
# gmosx: QUERY_STRING is sometimes not populated.
|
29
36
|
|
30
|
-
|
31
|
-
|
32
|
-
|
37
|
+
if context.query_string.empty? and context.uri =~ /\?/
|
38
|
+
context.headers['QUERY_STRING'] = context.uri.split('?').last
|
39
|
+
end
|
33
40
|
|
34
|
-
|
35
|
-
|
36
|
-
|
41
|
+
Cgi.parse_params(context)
|
42
|
+
Cgi.parse_cookies(context)
|
43
|
+
context.render(context.path)
|
37
44
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
45
|
+
out.print(Cgi.response_headers(context))
|
46
|
+
|
47
|
+
if context.out.is_a?(IO)
|
48
|
+
while buf = context.out.read(4096)
|
49
|
+
out.write(buf)
|
50
|
+
end
|
51
|
+
else
|
52
|
+
out.print(context.out)
|
43
53
|
end
|
44
|
-
else
|
45
|
-
out.print(context.out)
|
46
54
|
end
|
47
55
|
|
56
|
+
$autoreload_dirty = false
|
57
|
+
|
48
58
|
context.close
|
49
59
|
end
|
50
60
|
|
61
|
+
# push a parameter into the params hash
|
62
|
+
|
63
|
+
def self.structure_param(params, key, val)
|
64
|
+
if key =~ /(.+)\[(.+)\]$/ or key =~ /([^\.]+)\.(.+)$/
|
65
|
+
params[$1] ||= Hash.new
|
66
|
+
params[$1] = structure_param(params[$1], $2, val)
|
67
|
+
elsif key =~ /(.+)\[\]$/
|
68
|
+
params[$1] ||= Array.new
|
69
|
+
params[$1] << val
|
70
|
+
else
|
71
|
+
params[key] = val.nil? ? nil : val
|
72
|
+
end
|
73
|
+
return params
|
74
|
+
end
|
75
|
+
|
51
76
|
# Returns a hash with the pairs from the query
|
52
77
|
# string. The implicit hash construction that is done
|
53
78
|
# in parse_request_params is not done here.
|
54
|
-
|
55
|
-
# Parameters in the form xxx[] are converted
|
56
|
-
# to arrays.
|
57
|
-
#
|
58
|
-
# Use the field.attr or field[attr] notation to pass
|
59
|
-
# compound objects.
|
60
|
-
|
79
|
+
|
61
80
|
def self.parse_query_string(query_string)
|
62
81
|
params = {}
|
63
82
|
|
@@ -69,24 +88,8 @@ class Cgi
|
|
69
88
|
|
70
89
|
key = CGI.unescape(key) unless key.nil?
|
71
90
|
val = CGI.unescape(val) unless val.nil?
|
72
|
-
|
73
|
-
|
74
|
-
# Multiple values, for example a checkbox collection.
|
75
|
-
# Stored as an array.
|
76
|
-
if params.has_key?($1)
|
77
|
-
params[$1] << val
|
78
|
-
else
|
79
|
-
params[$1] = [val]
|
80
|
-
end
|
81
|
-
elsif key =~ /(.*)\[(.*)\]$/ or key =~ /(.*)\.(.*)$/
|
82
|
-
# A compound object with attributes.
|
83
|
-
# Stored as a Hash.
|
84
|
-
params[$1] ||= {}
|
85
|
-
params[$1][$2] = val
|
86
|
-
else
|
87
|
-
# Standard single valued parameter.
|
88
|
-
params[key] = val.nil? ? nil : val
|
89
|
-
end
|
91
|
+
|
92
|
+
params = self.structure_param(params, key, val)
|
90
93
|
end
|
91
94
|
|
92
95
|
return params
|
@@ -105,7 +108,8 @@ class Cgi
|
|
105
108
|
# FIXME: dont precreate?
|
106
109
|
context.cookies = {}
|
107
110
|
|
108
|
-
if env.has_key?('HTTP_COOKIE') or env.has_key?('COOKIE')
|
111
|
+
#if env.has_key?('HTTP_COOKIE') or env.has_key?('COOKIE')
|
112
|
+
if env['HTTP_COOKIE'] or env['COOKIE']
|
109
113
|
(env['HTTP_COOKIE'] or env['COOKIE']).split(/; /).each do |c|
|
110
114
|
key, val = c.split(/=/, 2)
|
111
115
|
|
@@ -175,7 +179,7 @@ class Cgi
|
|
175
179
|
when :get, :head
|
176
180
|
context.params = Cgi.parse_query_string(context.query_string)
|
177
181
|
when :post
|
178
|
-
context.in.binmode
|
182
|
+
context.in.binmode if defined?(context.in.binmode)
|
179
183
|
context.params = Cgi.parse_query_string(context.in.read(context.content_length) || '')
|
180
184
|
end
|
181
185
|
end
|
@@ -192,7 +196,7 @@ class Cgi
|
|
192
196
|
content_length = context.content_length
|
193
197
|
env_table = context.env
|
194
198
|
|
195
|
-
params = Hash.new(
|
199
|
+
params = Hash.new()
|
196
200
|
boundary = "--" + boundary
|
197
201
|
buf = ""
|
198
202
|
|
@@ -277,17 +281,13 @@ class Cgi
|
|
277
281
|
define_method(:content_type) { content_type.dup.taint }
|
278
282
|
|
279
283
|
# gmosx: this hides the performance hit!!
|
280
|
-
define_method(:to_s) { read }
|
284
|
+
define_method(:to_s) { str = read; rewind; return str}
|
281
285
|
end
|
282
286
|
|
283
287
|
/Content-Disposition:.* name="?([^\";]*)"?/ni.match(head)
|
284
288
|
name = $1.dup
|
285
|
-
|
286
|
-
|
287
|
-
params[name] = [params[name]] << body
|
288
|
-
else
|
289
|
-
params[name] = body
|
290
|
-
end
|
289
|
+
|
290
|
+
params = self.structure_param(params, name, body)
|
291
291
|
|
292
292
|
break if buf.size == 0
|
293
293
|
break if content_length === -1
|