rubysl-webrick 1.0.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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.travis.yml +8 -0
- data/Gemfile +4 -0
- data/LICENSE +25 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/lib/rubysl/webrick.rb +2 -0
- data/lib/rubysl/webrick/version.rb +5 -0
- data/lib/rubysl/webrick/webrick.rb +29 -0
- data/lib/webrick.rb +1 -0
- data/lib/webrick/accesslog.rb +67 -0
- data/lib/webrick/cgi.rb +257 -0
- data/lib/webrick/compat.rb +15 -0
- data/lib/webrick/config.rb +97 -0
- data/lib/webrick/cookie.rb +110 -0
- data/lib/webrick/htmlutils.rb +25 -0
- data/lib/webrick/httpauth.rb +45 -0
- data/lib/webrick/httpauth/authenticator.rb +79 -0
- data/lib/webrick/httpauth/basicauth.rb +65 -0
- data/lib/webrick/httpauth/digestauth.rb +343 -0
- data/lib/webrick/httpauth/htdigest.rb +91 -0
- data/lib/webrick/httpauth/htgroup.rb +61 -0
- data/lib/webrick/httpauth/htpasswd.rb +83 -0
- data/lib/webrick/httpauth/userdb.rb +29 -0
- data/lib/webrick/httpproxy.rb +254 -0
- data/lib/webrick/httprequest.rb +365 -0
- data/lib/webrick/httpresponse.rb +327 -0
- data/lib/webrick/https.rb +63 -0
- data/lib/webrick/httpserver.rb +210 -0
- data/lib/webrick/httpservlet.rb +22 -0
- data/lib/webrick/httpservlet/abstract.rb +71 -0
- data/lib/webrick/httpservlet/cgi_runner.rb +45 -0
- data/lib/webrick/httpservlet/cgihandler.rb +104 -0
- data/lib/webrick/httpservlet/erbhandler.rb +54 -0
- data/lib/webrick/httpservlet/filehandler.rb +398 -0
- data/lib/webrick/httpservlet/prochandler.rb +33 -0
- data/lib/webrick/httpstatus.rb +126 -0
- data/lib/webrick/httputils.rb +391 -0
- data/lib/webrick/httpversion.rb +49 -0
- data/lib/webrick/log.rb +88 -0
- data/lib/webrick/server.rb +200 -0
- data/lib/webrick/ssl.rb +126 -0
- data/lib/webrick/utils.rb +100 -0
- data/lib/webrick/version.rb +13 -0
- data/rubysl-webrick.gemspec +23 -0
- metadata +145 -0
@@ -0,0 +1,63 @@
|
|
1
|
+
#
|
2
|
+
# https.rb -- SSL/TLS enhancement for HTTPServer
|
3
|
+
#
|
4
|
+
# Author: IPR -- Internet Programming with Ruby -- writers
|
5
|
+
# Copyright (c) 2001 GOTOU Yuuzou
|
6
|
+
# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
|
7
|
+
# reserved.
|
8
|
+
#
|
9
|
+
# $IPR: https.rb,v 1.15 2003/07/22 19:20:42 gotoyuzo Exp $
|
10
|
+
|
11
|
+
require 'webrick/ssl'
|
12
|
+
|
13
|
+
module WEBrick
|
14
|
+
module Config
|
15
|
+
HTTP.update(SSL)
|
16
|
+
end
|
17
|
+
|
18
|
+
class HTTPRequest
|
19
|
+
attr_reader :cipher, :server_cert, :client_cert
|
20
|
+
|
21
|
+
alias orig_parse parse
|
22
|
+
|
23
|
+
def parse(socket=nil)
|
24
|
+
if socket.respond_to?(:cert)
|
25
|
+
@server_cert = socket.cert || @config[:SSLCertificate]
|
26
|
+
@client_cert = socket.peer_cert
|
27
|
+
@client_cert_chain = socket.peer_cert_chain
|
28
|
+
@cipher = socket.cipher
|
29
|
+
end
|
30
|
+
orig_parse(socket)
|
31
|
+
end
|
32
|
+
|
33
|
+
alias orig_parse_uri parse_uri
|
34
|
+
|
35
|
+
def parse_uri(str, scheme="https")
|
36
|
+
if @server_cert
|
37
|
+
return orig_parse_uri(str, scheme)
|
38
|
+
end
|
39
|
+
return orig_parse_uri(str)
|
40
|
+
end
|
41
|
+
|
42
|
+
alias orig_meta_vars meta_vars
|
43
|
+
|
44
|
+
def meta_vars
|
45
|
+
meta = orig_meta_vars
|
46
|
+
if @server_cert
|
47
|
+
meta["HTTPS"] = "on"
|
48
|
+
meta["SSL_SERVER_CERT"] = @server_cert.to_pem
|
49
|
+
meta["SSL_CLIENT_CERT"] = @client_cert ? @client_cert.to_pem : ""
|
50
|
+
if @client_cert_chain
|
51
|
+
@client_cert_chain.each_with_index{|cert, i|
|
52
|
+
meta["SSL_CLIENT_CERT_CHAIN_#{i}"] = cert.to_pem
|
53
|
+
}
|
54
|
+
end
|
55
|
+
meta["SSL_CIPHER"] = @cipher[0]
|
56
|
+
meta["SSL_PROTOCOL"] = @cipher[1]
|
57
|
+
meta["SSL_CIPHER_USEKEYSIZE"] = @cipher[2].to_s
|
58
|
+
meta["SSL_CIPHER_ALGKEYSIZE"] = @cipher[3].to_s
|
59
|
+
end
|
60
|
+
meta
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,210 @@
|
|
1
|
+
#
|
2
|
+
# httpserver.rb -- HTTPServer Class
|
3
|
+
#
|
4
|
+
# Author: IPR -- Internet Programming with Ruby -- writers
|
5
|
+
# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
|
6
|
+
# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
|
7
|
+
# reserved.
|
8
|
+
#
|
9
|
+
# $IPR: httpserver.rb,v 1.63 2002/10/01 17:16:32 gotoyuzo Exp $
|
10
|
+
|
11
|
+
require 'webrick/server'
|
12
|
+
require 'webrick/httputils'
|
13
|
+
require 'webrick/httpstatus'
|
14
|
+
require 'webrick/httprequest'
|
15
|
+
require 'webrick/httpresponse'
|
16
|
+
require 'webrick/httpservlet'
|
17
|
+
require 'webrick/accesslog'
|
18
|
+
|
19
|
+
module WEBrick
|
20
|
+
class HTTPServerError < ServerError; end
|
21
|
+
|
22
|
+
class HTTPServer < ::WEBrick::GenericServer
|
23
|
+
def initialize(config={}, default=Config::HTTP)
|
24
|
+
super
|
25
|
+
@http_version = HTTPVersion::convert(@config[:HTTPVersion])
|
26
|
+
|
27
|
+
@mount_tab = MountTable.new
|
28
|
+
if @config[:DocumentRoot]
|
29
|
+
mount("/", HTTPServlet::FileHandler, @config[:DocumentRoot],
|
30
|
+
@config[:DocumentRootOptions])
|
31
|
+
end
|
32
|
+
|
33
|
+
unless @config[:AccessLog]
|
34
|
+
@config[:AccessLog] = [
|
35
|
+
[ $stderr, AccessLog::COMMON_LOG_FORMAT ],
|
36
|
+
[ $stderr, AccessLog::REFERER_LOG_FORMAT ]
|
37
|
+
]
|
38
|
+
end
|
39
|
+
|
40
|
+
@virtual_hosts = Array.new
|
41
|
+
end
|
42
|
+
|
43
|
+
def run(sock)
|
44
|
+
while true
|
45
|
+
res = HTTPResponse.new(@config)
|
46
|
+
req = HTTPRequest.new(@config)
|
47
|
+
server = self
|
48
|
+
begin
|
49
|
+
timeout = @config[:RequestTimeout]
|
50
|
+
while timeout > 0
|
51
|
+
break if IO.select([sock], nil, nil, 0.5)
|
52
|
+
timeout = 0 if @status != :Running
|
53
|
+
timeout -= 0.5
|
54
|
+
end
|
55
|
+
raise HTTPStatus::EOFError if timeout <= 0 || sock.eof?
|
56
|
+
req.parse(sock)
|
57
|
+
res.request_method = req.request_method
|
58
|
+
res.request_uri = req.request_uri
|
59
|
+
res.request_http_version = req.http_version
|
60
|
+
res.keep_alive = req.keep_alive?
|
61
|
+
server = lookup_server(req) || self
|
62
|
+
if callback = server[:RequestCallback] || server[:RequestHandler]
|
63
|
+
callback.call(req, res)
|
64
|
+
end
|
65
|
+
server.service(req, res)
|
66
|
+
rescue HTTPStatus::EOFError, HTTPStatus::RequestTimeout => ex
|
67
|
+
res.set_error(ex)
|
68
|
+
rescue HTTPStatus::Error => ex
|
69
|
+
@logger.error(ex.message)
|
70
|
+
res.set_error(ex)
|
71
|
+
rescue HTTPStatus::Status => ex
|
72
|
+
res.status = ex.code
|
73
|
+
rescue StandardError => ex
|
74
|
+
@logger.error(ex)
|
75
|
+
res.set_error(ex, true)
|
76
|
+
ensure
|
77
|
+
if req.request_line
|
78
|
+
req.fixup()
|
79
|
+
res.send_response(sock)
|
80
|
+
server.access_log(@config, req, res)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
break if @http_version < "1.1"
|
84
|
+
break unless req.keep_alive?
|
85
|
+
break unless res.keep_alive?
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def service(req, res)
|
90
|
+
if req.unparsed_uri == "*"
|
91
|
+
if req.request_method == "OPTIONS"
|
92
|
+
do_OPTIONS(req, res)
|
93
|
+
raise HTTPStatus::OK
|
94
|
+
end
|
95
|
+
raise HTTPStatus::NotFound, "`#{req.unparsed_uri}' not found."
|
96
|
+
end
|
97
|
+
|
98
|
+
servlet, options, script_name, path_info = search_servlet(req.path)
|
99
|
+
raise HTTPStatus::NotFound, "`#{req.path}' not found." unless servlet
|
100
|
+
req.script_name = script_name
|
101
|
+
req.path_info = path_info
|
102
|
+
si = servlet.get_instance(self, *options)
|
103
|
+
@logger.debug(format("%s is invoked.", si.class.name))
|
104
|
+
si.service(req, res)
|
105
|
+
end
|
106
|
+
|
107
|
+
def do_OPTIONS(req, res)
|
108
|
+
res["allow"] = "GET,HEAD,POST,OPTIONS"
|
109
|
+
end
|
110
|
+
|
111
|
+
def mount(dir, servlet, *options)
|
112
|
+
@logger.debug(sprintf("%s is mounted on %s.", servlet.inspect, dir))
|
113
|
+
@mount_tab[dir] = [ servlet, options ]
|
114
|
+
end
|
115
|
+
|
116
|
+
def mount_proc(dir, proc=nil, &block)
|
117
|
+
proc ||= block
|
118
|
+
raise HTTPServerError, "must pass a proc or block" unless proc
|
119
|
+
mount(dir, HTTPServlet::ProcHandler.new(proc))
|
120
|
+
end
|
121
|
+
|
122
|
+
def unmount(dir)
|
123
|
+
@logger.debug(sprintf("unmount %s.", dir))
|
124
|
+
@mount_tab.delete(dir)
|
125
|
+
end
|
126
|
+
alias umount unmount
|
127
|
+
|
128
|
+
def search_servlet(path)
|
129
|
+
script_name, path_info = @mount_tab.scan(path)
|
130
|
+
servlet, options = @mount_tab[script_name]
|
131
|
+
if servlet
|
132
|
+
[ servlet, options, script_name, path_info ]
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def virtual_host(server)
|
137
|
+
@virtual_hosts << server
|
138
|
+
@virtual_hosts = @virtual_hosts.sort_by{|s|
|
139
|
+
num = 0
|
140
|
+
num -= 4 if s[:BindAddress]
|
141
|
+
num -= 2 if s[:Port]
|
142
|
+
num -= 1 if s[:ServerName]
|
143
|
+
num
|
144
|
+
}
|
145
|
+
end
|
146
|
+
|
147
|
+
def lookup_server(req)
|
148
|
+
@virtual_hosts.find{|s|
|
149
|
+
(s[:BindAddress].nil? || req.addr[3] == s[:BindAddress]) &&
|
150
|
+
(s[:Port].nil? || req.port == s[:Port]) &&
|
151
|
+
((s[:ServerName].nil? || req.host == s[:ServerName]) ||
|
152
|
+
(!s[:ServerAlias].nil? && s[:ServerAlias].find{|h| h === req.host}))
|
153
|
+
}
|
154
|
+
end
|
155
|
+
|
156
|
+
def access_log(config, req, res)
|
157
|
+
param = AccessLog::setup_params(config, req, res)
|
158
|
+
@config[:AccessLog].each{|logger, fmt|
|
159
|
+
logger << AccessLog::format(fmt+"\n", param)
|
160
|
+
}
|
161
|
+
end
|
162
|
+
|
163
|
+
class MountTable
|
164
|
+
def initialize
|
165
|
+
@tab = Hash.new
|
166
|
+
compile
|
167
|
+
end
|
168
|
+
|
169
|
+
def [](dir)
|
170
|
+
dir = normalize(dir)
|
171
|
+
@tab[dir]
|
172
|
+
end
|
173
|
+
|
174
|
+
def []=(dir, val)
|
175
|
+
dir = normalize(dir)
|
176
|
+
@tab[dir] = val
|
177
|
+
compile
|
178
|
+
val
|
179
|
+
end
|
180
|
+
|
181
|
+
def delete(dir)
|
182
|
+
dir = normalize(dir)
|
183
|
+
res = @tab.delete(dir)
|
184
|
+
compile
|
185
|
+
res
|
186
|
+
end
|
187
|
+
|
188
|
+
def scan(path)
|
189
|
+
@scanner =~ path
|
190
|
+
[ $&, $' ]
|
191
|
+
end
|
192
|
+
|
193
|
+
private
|
194
|
+
|
195
|
+
def compile
|
196
|
+
k = @tab.keys
|
197
|
+
k.sort!
|
198
|
+
k.reverse!
|
199
|
+
k.collect!{|path| Regexp.escape(path) }
|
200
|
+
@scanner = Regexp.new("^(" + k.join("|") +")(?=/|$)")
|
201
|
+
end
|
202
|
+
|
203
|
+
def normalize(dir)
|
204
|
+
ret = dir ? dir.dup : ""
|
205
|
+
ret.sub!(%r|/+$|, "")
|
206
|
+
ret
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#
|
2
|
+
# httpservlet.rb -- HTTPServlet Utility File
|
3
|
+
#
|
4
|
+
# Author: IPR -- Internet Programming with Ruby -- writers
|
5
|
+
# Copyright (c) 2000, 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
|
6
|
+
# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
|
7
|
+
# reserved.
|
8
|
+
#
|
9
|
+
# $IPR: httpservlet.rb,v 1.21 2003/02/23 12:24:46 gotoyuzo Exp $
|
10
|
+
|
11
|
+
require 'webrick/httpservlet/abstract'
|
12
|
+
require 'webrick/httpservlet/filehandler'
|
13
|
+
require 'webrick/httpservlet/cgihandler'
|
14
|
+
require 'webrick/httpservlet/erbhandler'
|
15
|
+
require 'webrick/httpservlet/prochandler'
|
16
|
+
|
17
|
+
module WEBrick
|
18
|
+
module HTTPServlet
|
19
|
+
FileHandler.add_handler("cgi", CGIHandler)
|
20
|
+
FileHandler.add_handler("rhtml", ERBHandler)
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
#
|
2
|
+
# httpservlet.rb -- HTTPServlet Module
|
3
|
+
#
|
4
|
+
# Author: IPR -- Internet Programming with Ruby -- writers
|
5
|
+
# Copyright (c) 2000 TAKAHASHI Masayoshi, GOTOU Yuuzou
|
6
|
+
# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
|
7
|
+
# reserved.
|
8
|
+
#
|
9
|
+
# $IPR: abstract.rb,v 1.24 2003/07/11 11:16:46 gotoyuzo Exp $
|
10
|
+
|
11
|
+
require 'thread'
|
12
|
+
|
13
|
+
require 'webrick/htmlutils'
|
14
|
+
require 'webrick/httputils'
|
15
|
+
require 'webrick/httpstatus'
|
16
|
+
|
17
|
+
module WEBrick
|
18
|
+
module HTTPServlet
|
19
|
+
class HTTPServletError < StandardError; end
|
20
|
+
|
21
|
+
class AbstractServlet
|
22
|
+
def self.get_instance(config, *options)
|
23
|
+
self.new(config, *options)
|
24
|
+
end
|
25
|
+
|
26
|
+
def initialize(server, *options)
|
27
|
+
@server = @config = server
|
28
|
+
@logger = @server[:Logger]
|
29
|
+
@options = options
|
30
|
+
end
|
31
|
+
|
32
|
+
def service(req, res)
|
33
|
+
method_name = "do_" + req.request_method.gsub(/-/, "_")
|
34
|
+
if respond_to?(method_name)
|
35
|
+
__send__(method_name, req, res)
|
36
|
+
else
|
37
|
+
raise HTTPStatus::MethodNotAllowed,
|
38
|
+
"unsupported method `#{req.request_method}'."
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def do_GET(req, res)
|
43
|
+
raise HTTPStatus::NotFound, "not found."
|
44
|
+
end
|
45
|
+
|
46
|
+
def do_HEAD(req, res)
|
47
|
+
do_GET(req, res)
|
48
|
+
end
|
49
|
+
|
50
|
+
def do_OPTIONS(req, res)
|
51
|
+
m = self.methods.grep(/^do_[A-Z]+$/)
|
52
|
+
m.collect!{|i| i.sub(/do_/, "") }
|
53
|
+
m.sort!
|
54
|
+
res["allow"] = m.join(",")
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def redirect_to_directory_uri(req, res)
|
60
|
+
if req.path[-1] != ?/
|
61
|
+
location = req.path + "/"
|
62
|
+
if req.query_string && req.query_string.size > 0
|
63
|
+
location << "?" << req.query_string
|
64
|
+
end
|
65
|
+
res.set_redirect(HTTPStatus::MovedPermanently, location)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
#
|
2
|
+
# cgi_runner.rb -- CGI launcher.
|
3
|
+
#
|
4
|
+
# Author: IPR -- Internet Programming with Ruby -- writers
|
5
|
+
# Copyright (c) 2000 TAKAHASHI Masayoshi, GOTOU YUUZOU
|
6
|
+
# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
|
7
|
+
# reserved.
|
8
|
+
#
|
9
|
+
# $IPR: cgi_runner.rb,v 1.9 2002/09/25 11:33:15 gotoyuzo Exp $
|
10
|
+
|
11
|
+
def sysread(io, size)
|
12
|
+
buf = ""
|
13
|
+
while size > 0
|
14
|
+
tmp = io.sysread(size)
|
15
|
+
buf << tmp
|
16
|
+
size -= tmp.size
|
17
|
+
end
|
18
|
+
return buf
|
19
|
+
end
|
20
|
+
|
21
|
+
STDIN.binmode
|
22
|
+
|
23
|
+
buf = ""
|
24
|
+
len = sysread(STDIN, 8).to_i
|
25
|
+
out = sysread(STDIN, len)
|
26
|
+
STDOUT.reopen(open(out, "w"))
|
27
|
+
|
28
|
+
len = sysread(STDIN, 8).to_i
|
29
|
+
err = sysread(STDIN, len)
|
30
|
+
STDERR.reopen(open(err, "w"))
|
31
|
+
|
32
|
+
len = sysread(STDIN, 8).to_i
|
33
|
+
dump = sysread(STDIN, len)
|
34
|
+
hash = Marshal.restore(dump)
|
35
|
+
ENV.keys.each{|name| ENV.delete(name) }
|
36
|
+
hash.each{|k, v| ENV[k] = v if v }
|
37
|
+
|
38
|
+
dir = File::dirname(ENV["SCRIPT_FILENAME"])
|
39
|
+
Dir::chdir dir
|
40
|
+
|
41
|
+
if interpreter = ARGV[0]
|
42
|
+
exec(interpreter, ENV["SCRIPT_FILENAME"])
|
43
|
+
# NOTREACHED
|
44
|
+
end
|
45
|
+
exec ENV["SCRIPT_FILENAME"]
|
@@ -0,0 +1,104 @@
|
|
1
|
+
#
|
2
|
+
# cgihandler.rb -- CGIHandler Class
|
3
|
+
#
|
4
|
+
# Author: IPR -- Internet Programming with Ruby -- writers
|
5
|
+
# Copyright (c) 2001 TAKAHASHI Masayoshi, GOTOU Yuuzou
|
6
|
+
# Copyright (c) 2002 Internet Programming with Ruby writers. All rights
|
7
|
+
# reserved.
|
8
|
+
#
|
9
|
+
# $IPR: cgihandler.rb,v 1.27 2003/03/21 19:56:01 gotoyuzo Exp $
|
10
|
+
|
11
|
+
require 'rbconfig'
|
12
|
+
require 'tempfile'
|
13
|
+
require 'webrick/config'
|
14
|
+
require 'webrick/httpservlet/abstract'
|
15
|
+
|
16
|
+
module WEBrick
|
17
|
+
module HTTPServlet
|
18
|
+
|
19
|
+
class CGIHandler < AbstractServlet
|
20
|
+
Ruby = File::join(::Config::CONFIG['bindir'],
|
21
|
+
::Config::CONFIG['ruby_install_name'])
|
22
|
+
Ruby << ::Config::CONFIG['EXEEXT']
|
23
|
+
CGIRunner = "\"#{Ruby}\" \"#{Config::LIBDIR}/httpservlet/cgi_runner.rb\""
|
24
|
+
|
25
|
+
def initialize(server, name)
|
26
|
+
super
|
27
|
+
@script_filename = name
|
28
|
+
@tempdir = server[:TempDir]
|
29
|
+
@cgicmd = "#{CGIRunner} #{server[:CGIInterpreter]}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def do_GET(req, res)
|
33
|
+
data = nil
|
34
|
+
status = -1
|
35
|
+
|
36
|
+
cgi_in = IO::popen(@cgicmd, "wb")
|
37
|
+
cgi_out = Tempfile.new("webrick.cgiout.", @tempdir)
|
38
|
+
cgi_err = Tempfile.new("webrick.cgierr.", @tempdir)
|
39
|
+
begin
|
40
|
+
cgi_in.sync = true
|
41
|
+
meta = req.meta_vars
|
42
|
+
meta["SCRIPT_FILENAME"] = @script_filename
|
43
|
+
meta["PATH"] = @config[:CGIPathEnv]
|
44
|
+
if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
|
45
|
+
meta["SystemRoot"] = ENV["SystemRoot"]
|
46
|
+
end
|
47
|
+
dump = Marshal.dump(meta)
|
48
|
+
|
49
|
+
cgi_in.write("%8d" % cgi_out.path.size)
|
50
|
+
cgi_in.write(cgi_out.path)
|
51
|
+
cgi_in.write("%8d" % cgi_err.path.size)
|
52
|
+
cgi_in.write(cgi_err.path)
|
53
|
+
cgi_in.write("%8d" % dump.size)
|
54
|
+
cgi_in.write(dump)
|
55
|
+
|
56
|
+
if req.body and req.body.size > 0
|
57
|
+
cgi_in.write(req.body)
|
58
|
+
end
|
59
|
+
ensure
|
60
|
+
cgi_in.close
|
61
|
+
status = $?.exitstatus
|
62
|
+
sleep 0.1 if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
|
63
|
+
data = cgi_out.read
|
64
|
+
cgi_out.close(true)
|
65
|
+
if errmsg = cgi_err.read
|
66
|
+
if errmsg.size > 0
|
67
|
+
@logger.error("CGIHandler: #{@script_filename}:\n" + errmsg)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
cgi_err.close(true)
|
71
|
+
end
|
72
|
+
|
73
|
+
if status != 0
|
74
|
+
@logger.error("CGIHandler: #{@script_filename} exit with #{status}")
|
75
|
+
end
|
76
|
+
|
77
|
+
data = "" unless data
|
78
|
+
raw_header, body = data.split(/^[\xd\xa]+/on, 2)
|
79
|
+
raise HTTPStatus::InternalServerError,
|
80
|
+
"Premature end of script headers: #{@script_filename}" if body.nil?
|
81
|
+
|
82
|
+
begin
|
83
|
+
header = HTTPUtils::parse_header(raw_header)
|
84
|
+
if /^(\d+)/ =~ header['status'][0]
|
85
|
+
res.status = $1.to_i
|
86
|
+
header.delete('status')
|
87
|
+
end
|
88
|
+
if header.has_key?('set-cookie')
|
89
|
+
header['set-cookie'].each{|k|
|
90
|
+
res.cookies << Cookie.parse_set_cookie(k)
|
91
|
+
}
|
92
|
+
header.delete('set-cookie')
|
93
|
+
end
|
94
|
+
header.each{|key, val| res[key] = val.join(", ") }
|
95
|
+
rescue => ex
|
96
|
+
raise HTTPStatus::InternalServerError, ex.message
|
97
|
+
end
|
98
|
+
res.body = body
|
99
|
+
end
|
100
|
+
alias do_POST do_GET
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
end
|