webrick 1.3.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of webrick might be problematic. Click here for more details.

Files changed (63) hide show
  1. data/README.txt +21 -0
  2. data/lib/webrick.rb +227 -0
  3. data/lib/webrick/accesslog.rb +151 -0
  4. data/lib/webrick/cgi.rb +260 -0
  5. data/lib/webrick/compat.rb +35 -0
  6. data/lib/webrick/config.rb +121 -0
  7. data/lib/webrick/cookie.rb +110 -0
  8. data/lib/webrick/htmlutils.rb +28 -0
  9. data/lib/webrick/httpauth.rb +95 -0
  10. data/lib/webrick/httpauth/authenticator.rb +112 -0
  11. data/lib/webrick/httpauth/basicauth.rb +108 -0
  12. data/lib/webrick/httpauth/digestauth.rb +392 -0
  13. data/lib/webrick/httpauth/htdigest.rb +128 -0
  14. data/lib/webrick/httpauth/htgroup.rb +93 -0
  15. data/lib/webrick/httpauth/htpasswd.rb +121 -0
  16. data/lib/webrick/httpauth/userdb.rb +52 -0
  17. data/lib/webrick/httpproxy.rb +305 -0
  18. data/lib/webrick/httprequest.rb +461 -0
  19. data/lib/webrick/httpresponse.rb +399 -0
  20. data/lib/webrick/https.rb +64 -0
  21. data/lib/webrick/httpserver.rb +264 -0
  22. data/lib/webrick/httpservlet.rb +22 -0
  23. data/lib/webrick/httpservlet/abstract.rb +153 -0
  24. data/lib/webrick/httpservlet/cgi_runner.rb +46 -0
  25. data/lib/webrick/httpservlet/cgihandler.rb +108 -0
  26. data/lib/webrick/httpservlet/erbhandler.rb +87 -0
  27. data/lib/webrick/httpservlet/filehandler.rb +470 -0
  28. data/lib/webrick/httpservlet/prochandler.rb +33 -0
  29. data/lib/webrick/httpstatus.rb +184 -0
  30. data/lib/webrick/httputils.rb +394 -0
  31. data/lib/webrick/httpversion.rb +49 -0
  32. data/lib/webrick/log.rb +136 -0
  33. data/lib/webrick/server.rb +218 -0
  34. data/lib/webrick/ssl.rb +127 -0
  35. data/lib/webrick/utils.rb +241 -0
  36. data/lib/webrick/version.rb +13 -0
  37. data/sample/webrick/demo-app.rb +66 -0
  38. data/sample/webrick/demo-multipart.cgi +12 -0
  39. data/sample/webrick/demo-servlet.rb +6 -0
  40. data/sample/webrick/demo-urlencoded.cgi +12 -0
  41. data/sample/webrick/hello.cgi +11 -0
  42. data/sample/webrick/hello.rb +8 -0
  43. data/sample/webrick/httpd.rb +23 -0
  44. data/sample/webrick/httpproxy.rb +25 -0
  45. data/sample/webrick/httpsd.rb +33 -0
  46. data/test/openssl/utils.rb +313 -0
  47. data/test/ruby/envutil.rb +208 -0
  48. data/test/webrick/test_cgi.rb +134 -0
  49. data/test/webrick/test_cookie.rb +131 -0
  50. data/test/webrick/test_filehandler.rb +285 -0
  51. data/test/webrick/test_httpauth.rb +167 -0
  52. data/test/webrick/test_httpproxy.rb +282 -0
  53. data/test/webrick/test_httprequest.rb +411 -0
  54. data/test/webrick/test_httpresponse.rb +49 -0
  55. data/test/webrick/test_httpserver.rb +305 -0
  56. data/test/webrick/test_httputils.rb +96 -0
  57. data/test/webrick/test_httpversion.rb +40 -0
  58. data/test/webrick/test_server.rb +67 -0
  59. data/test/webrick/test_utils.rb +64 -0
  60. data/test/webrick/utils.rb +58 -0
  61. data/test/webrick/webrick.cgi +36 -0
  62. data/test/webrick/webrick_long_filename.cgi +36 -0
  63. metadata +106 -0
@@ -0,0 +1,21 @@
1
+ = WEB server toolkit.
2
+
3
+ WEBrick is an HTTP server toolkit that can be configured as an HTTPS server,
4
+ a proxy server, and a virtual-host server. WEBrick features complete
5
+ logging of both server operations and HTTP access. WEBrick supports both
6
+ basic and digest authentication in addition to algorithms not in RFC 2617.
7
+
8
+ A WEBrick servers can be composed of multiple WEBrick servers or servlets to
9
+ provide differing behavior on a per-host or per-path basis. WEBrick
10
+ includes servlets for handling CGI scripts, ERb pages, ruby blocks and
11
+ directory listings.
12
+
13
+ WEBrick also includes tools for daemonizing a process and starting a process
14
+ at a higher privilege level and dropping permissions.
15
+
16
+ == Copyright
17
+
18
+ Author: IPR -- Internet Programming with Ruby -- writers
19
+
20
+ Copyright (c) 2000 TAKAHASHI Masayoshi, GOTOU YUUZOU
21
+ Copyright (c) 2002 Internet Programming with Ruby writers. All rights reserved.
@@ -0,0 +1,227 @@
1
+ ##
2
+ # = WEB server toolkit.
3
+ #
4
+ # WEBrick is an HTTP server toolkit that can be configured as an HTTPS server,
5
+ # a proxy server, and a virtual-host server. WEBrick features complete
6
+ # logging of both server operations and HTTP access. WEBrick supports both
7
+ # basic and digest authentication in addition to algorithms not in RFC 2617.
8
+ #
9
+ # A WEBrick servers can be composed of multiple WEBrick servers or servlets to
10
+ # provide differing behavior on a per-host or per-path basis. WEBrick
11
+ # includes servlets for handling CGI scripts, ERb pages, ruby blocks and
12
+ # directory listings.
13
+ #
14
+ # WEBrick also includes tools for daemonizing a process and starting a process
15
+ # at a higher privilege level and dropping permissions.
16
+ #
17
+ # == Starting an HTTP server
18
+ #
19
+ # To create a new WEBrick::HTTPServer that will listen to connections on port
20
+ # 8000 and serve documents from the current user's public_html folder:
21
+ #
22
+ # require 'webrick'
23
+ #
24
+ # root = File.expand_path '~/public_html'
25
+ # server = WEBrick::HTTPServer.new :Port => 8000, :DocumentRoot => root
26
+ #
27
+ # To run the server you will need to provide a suitable shutdown hook as
28
+ # starting the server blocks the current thread:
29
+ #
30
+ # trap 'INT' do server.shutdown end
31
+ #
32
+ # server.start
33
+ #
34
+ # == Custom Behavior
35
+ #
36
+ # The easiest way to have a server perform custom operations is through
37
+ # WEBrick::HTTPServer#mount_proc. The block given will be called with a
38
+ # WEBrick::HTTPRequest with request info and a WEBrick::HTTPResponse which
39
+ # must be filled in appropriately:
40
+ #
41
+ # server.mount_proc '/' do |req, res|
42
+ # res.body = 'Hello, world!'
43
+ # end
44
+ #
45
+ # Remember that <tt>server.mount_proc</tt> must <tt>server.start</tt>.
46
+ #
47
+ # == Servlets
48
+ #
49
+ # Advanced custom behavior can be obtained through mounting a subclass of
50
+ # WEBrick::HTTPServlet::AbstractServlet. Servlets provide more modularity
51
+ # when writing an HTTP server than mount_proc allows. Here is a simple
52
+ # servlet:
53
+ #
54
+ # class Simple < WEBrick::HTTPServlet::AbstractServlet
55
+ # def do_GET request, response
56
+ # status, content_type, body = do_stuff_with request
57
+ #
58
+ # response.status = 200
59
+ # response['Content-Type'] = 'text/plain'
60
+ # response.body = 'Hello, World!'
61
+ # end
62
+ # end
63
+ #
64
+ # To initialize the servlet you mount it on the server:
65
+ #
66
+ # server.mount '/simple', Simple
67
+ #
68
+ # See WEBrick::HTTPServlet::AbstractServlet for more details.
69
+ #
70
+ # == Virtual Hosts
71
+ #
72
+ # A server can act as a virtual host for multiple host names. After creating
73
+ # the listening host, additional hosts that do not listen can be created and
74
+ # attached as virtual hosts:
75
+ #
76
+ # server = WEBrick::HTTPServer.new # ...
77
+ #
78
+ # vhost = WEBrick::HTTPServer.new :ServerName => 'vhost.example',
79
+ # :DoNotListen => true, # ...
80
+ # vhost.mount '/', ...
81
+ #
82
+ # server.virtual_host vhost
83
+ #
84
+ # If no +:DocumentRoot+ is provided and no servlets or procs are mounted on the
85
+ # main server it will return 404 for all URLs.
86
+ #
87
+ # == HTTPS
88
+ #
89
+ # To create an HTTPS server you only need to enable SSL and provide an SSL
90
+ # certificate name:
91
+ #
92
+ # require 'webrick'
93
+ # require 'webrick/https'
94
+ #
95
+ # cert_name = [
96
+ # %w[CN localhost],
97
+ # ]
98
+ #
99
+ # server = WEBrick::HTTPServer.new(:Port => 8000,
100
+ # :SSLEnable => true,
101
+ # :SSLCertName => cert_name)
102
+ #
103
+ # This will start the server with a self-generated self-signed certificate.
104
+ # The certificate will be changed every time the server is restarted.
105
+ #
106
+ # To create a server with a pre-determined key and certificate you can provide
107
+ # them:
108
+ #
109
+ # require 'webrick'
110
+ # require 'webrick/https'
111
+ # require 'openssl'
112
+ #
113
+ # cert = OpenSSL::X509::Certificate.new File.read '/path/to/cert.pem'
114
+ # pkey = OpenSSL::PKey::RSA.new File.read '/path/to/pkey.pem'
115
+ #
116
+ # server = WEBrick::HTTPServer.new(:Port => 8000,
117
+ # :SSLEnable => true,
118
+ # :SSLCertificate => cert,
119
+ # :SSLPrivateKey => pkey)
120
+ #
121
+ # == Proxy Server
122
+ #
123
+ # WEBrick can act as a proxy server:
124
+ #
125
+ # require 'webrick'
126
+ # require 'webrick/httpproxy'
127
+ #
128
+ # proxy = WEBrick::HTTPProxyServer.new :Port => 8000
129
+ #
130
+ # trap 'INT' do proxy.shutdown end
131
+ #
132
+ # Proxies may modifier the content of the response through the
133
+ # +:ProxyContentHandler+ callback which will be invoked with the request and
134
+ # respone after the remote content has been fetched.
135
+ #
136
+ # == Basic and Digest authentication
137
+ #
138
+ # WEBrick provides both Basic and Digest authentication for regular and proxy
139
+ # servers. See WEBrick::HTTPAuth, WEBrick::HTTPAuth::BasicAuth and
140
+ # WEBrick::HTTPAuth::DigestAuth.
141
+ #
142
+ # == WEBrick as a Production Web Server
143
+ #
144
+ # WEBrick can be run as a production server for small loads.
145
+ #
146
+ # === Daemonizing
147
+ #
148
+ # To start a WEBrick server as a daemon simple run WEBrick::Daemon.start
149
+ # before starting the server.
150
+ #
151
+ # === Dropping Permissions
152
+ #
153
+ # WEBrick can be started as one user to gain permission to bind to port 80 or
154
+ # 443 for serving HTTP or HTTPS traffic then can drop these permissions for
155
+ # regular operation. To listen on all interfaces for HTTP traffic:
156
+ #
157
+ # sockets = WEBrick::Utils.create_listeners nil, 80
158
+ #
159
+ # Then drop privileges:
160
+ #
161
+ # WEBrick::Utils.su 'www'
162
+ #
163
+ # Then create a server that does not listen by default:
164
+ #
165
+ # server = WEBrick::HTTPServer.new :DoNotListen => true, # ...
166
+ #
167
+ # Then overwrite the listening sockets with the port 80 sockets:
168
+ #
169
+ # server.listeners.replace sockets
170
+ #
171
+ # === Logging
172
+ #
173
+ # WEBrick can separately log server operations and end-user access. For
174
+ # server operations:
175
+ #
176
+ # log_file = File.open '/var/log/webrick.log', 'a+'
177
+ # log = WEBrick::Log.new log_file
178
+ #
179
+ # For user access logging:
180
+ #
181
+ # access_log = [
182
+ # [log_file, WEBrick::AccessLog::COMBINED_LOG_FORMAT],
183
+ # ]
184
+ #
185
+ # server = WEBrick::HTTPServer.new :Logger => log, :AccessLog => access_log
186
+ #
187
+ # See WEBrick::AccessLog for further log formats.
188
+ #
189
+ # === Log Rotation
190
+ #
191
+ # To rotate logs in WEBrick on a HUP signal (like syslogd can send), open the
192
+ # log file in 'a+' mode (as above) and trap 'HUP' to reopen the log file:
193
+ #
194
+ # trap 'HUP' do log_file.reopen '/path/to/webrick.log', 'a+'
195
+ #
196
+ # == Copyright
197
+ #
198
+ # Author: IPR -- Internet Programming with Ruby -- writers
199
+ #
200
+ # Copyright (c) 2000 TAKAHASHI Masayoshi, GOTOU YUUZOU
201
+ # Copyright (c) 2002 Internet Programming with Ruby writers. All rights
202
+ # reserved.
203
+ #--
204
+ # $IPR: webrick.rb,v 1.12 2002/10/01 17:16:31 gotoyuzo Exp $
205
+
206
+ module WEBrick
207
+ end
208
+
209
+ require 'webrick/compat.rb'
210
+
211
+ require 'webrick/version.rb'
212
+ require 'webrick/config.rb'
213
+ require 'webrick/log.rb'
214
+ require 'webrick/server.rb'
215
+ require 'webrick/utils.rb'
216
+ require 'webrick/accesslog'
217
+
218
+ require 'webrick/htmlutils.rb'
219
+ require 'webrick/httputils.rb'
220
+ require 'webrick/cookie.rb'
221
+ require 'webrick/httpversion.rb'
222
+ require 'webrick/httpstatus.rb'
223
+ require 'webrick/httprequest.rb'
224
+ require 'webrick/httpresponse.rb'
225
+ require 'webrick/httpserver.rb'
226
+ require 'webrick/httpservlet.rb'
227
+ require 'webrick/httpauth.rb'
@@ -0,0 +1,151 @@
1
+ #--
2
+ # accesslog.rb -- Access log handling utilities
3
+ #
4
+ # Author: IPR -- Internet Programming with Ruby -- writers
5
+ # Copyright (c) 2002 keita yamaguchi
6
+ # Copyright (c) 2002 Internet Programming with Ruby writers
7
+ #
8
+ # $IPR: accesslog.rb,v 1.1 2002/10/01 17:16:32 gotoyuzo Exp $
9
+
10
+ module WEBrick
11
+
12
+ ##
13
+ # AccessLog provides logging to various files in various formats.
14
+ #
15
+ # Multiple logs may be written to at the same time:
16
+ #
17
+ # access_log = [
18
+ # [$stderr, WEBrick::AccessLog::COMMON_LOG_FORMAT],
19
+ # [$stderr, WEBrick::AccessLog::REFERER_LOG_FORMAT],
20
+ # ]
21
+ #
22
+ # server = WEBrick::HTTPServer.new :AccessLog => access_log
23
+ #
24
+ # Custom log formats may be defined. WEBrick::AccessLog provides a subset
25
+ # of the formatting from Apache's mod_log_config
26
+ # http://httpd.apache.org/docs/mod/mod_log_config.html#formats. See
27
+ # AccessLog::setup_params for a list of supported options
28
+
29
+ module AccessLog
30
+
31
+ ##
32
+ # Raised if a parameter such as %e, %i, %o or %n is used without fetching
33
+ # a specific field.
34
+
35
+ class AccessLogError < StandardError; end
36
+
37
+ ##
38
+ # The Common Log Format's time format
39
+
40
+ CLF_TIME_FORMAT = "[%d/%b/%Y:%H:%M:%S %Z]"
41
+
42
+ ##
43
+ # Common Log Format
44
+
45
+ COMMON_LOG_FORMAT = "%h %l %u %t \"%r\" %s %b"
46
+
47
+ ##
48
+ # Short alias for Common Log Format
49
+
50
+ CLF = COMMON_LOG_FORMAT
51
+
52
+ ##
53
+ # Referer Log Format
54
+
55
+ REFERER_LOG_FORMAT = "%{Referer}i -> %U"
56
+
57
+ ##
58
+ # User-Agent Log Format
59
+
60
+ AGENT_LOG_FORMAT = "%{User-Agent}i"
61
+
62
+ ##
63
+ # Combined Log Format
64
+
65
+ COMBINED_LOG_FORMAT = "#{CLF} \"%{Referer}i\" \"%{User-agent}i\""
66
+
67
+ module_function
68
+
69
+ # This format specification is a subset of mod_log_config of Apache:
70
+ #
71
+ # %a:: Remote IP address
72
+ # %b:: Total response size
73
+ # %e{variable}:: Given variable in ENV
74
+ # %f:: Response filename
75
+ # %h:: Remote host name
76
+ # %{header}i:: Given request header
77
+ # %l:: Remote logname, always "-"
78
+ # %m:: Request method
79
+ # %{attr}n:: Given request attribute from <tt>req.attributes</tt>
80
+ # %{header}o:: Given response header
81
+ # %p:: Server's request port
82
+ # %{format}p:: The canonical port of the server serving the request or the
83
+ # actual port or the client's actual port. Valid formats are
84
+ # canonical, local or remote.
85
+ # %q:: Request query string
86
+ # %r:: First line of the request
87
+ # %s:: Request status
88
+ # %t:: Time the request was recieved
89
+ # %T:: Time taken to process the request
90
+ # %u:: Remote user from auth
91
+ # %U:: Unparsed URI
92
+ # %%:: Literal %
93
+
94
+ def setup_params(config, req, res)
95
+ params = Hash.new("")
96
+ params["a"] = req.peeraddr[3]
97
+ params["b"] = res.sent_size
98
+ params["e"] = ENV
99
+ params["f"] = res.filename || ""
100
+ params["h"] = req.peeraddr[2]
101
+ params["i"] = req
102
+ params["l"] = "-"
103
+ params["m"] = req.request_method
104
+ params["n"] = req.attributes
105
+ params["o"] = res
106
+ params["p"] = req.port
107
+ params["q"] = req.query_string
108
+ params["r"] = req.request_line.sub(/\x0d?\x0a\z/o, '')
109
+ params["s"] = res.status # won't support "%>s"
110
+ params["t"] = req.request_time
111
+ params["T"] = Time.now - req.request_time
112
+ params["u"] = req.user || "-"
113
+ params["U"] = req.unparsed_uri
114
+ params["v"] = config[:ServerName]
115
+ params
116
+ end
117
+
118
+ def format(format_string, params)
119
+ format_string.gsub(/\%(?:\{(.*?)\})?>?([a-zA-Z%])/){
120
+ param, spec = $1, $2
121
+ case spec[0]
122
+ when ?e, ?i, ?n, ?o
123
+ raise AccessLogError,
124
+ "parameter is required for \"#{spec}\"" unless param
125
+ (param = params[spec][param]) ? escape(param) : "-"
126
+ when ?t
127
+ params[spec].strftime(param || CLF_TIME_FORMAT)
128
+ when ?p
129
+ case param
130
+ when 'remote'
131
+ escape(params["i"].peeraddr[1].to_s)
132
+ else
133
+ escape(params["p"].to_s)
134
+ end
135
+ when ?%
136
+ "%"
137
+ else
138
+ escape(params[spec].to_s)
139
+ end
140
+ }
141
+ end
142
+
143
+ def escape(data)
144
+ if data.tainted?
145
+ data.gsub(/[[:cntrl:]\\]+/) {$&.dump[1...-1]}.untaint
146
+ else
147
+ data
148
+ end
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,260 @@
1
+ #
2
+ # cgi.rb -- Yet another CGI library
3
+ #
4
+ # Author: IPR -- Internet Programming with Ruby -- writers
5
+ # Copyright (c) 2003 Internet Programming with Ruby writers. All rights
6
+ # reserved.
7
+ #
8
+ # $Id$
9
+
10
+ require "webrick/httprequest"
11
+ require "webrick/httpresponse"
12
+ require "webrick/config"
13
+ require "stringio"
14
+
15
+ module WEBrick
16
+ class CGI
17
+ CGIError = Class.new(StandardError)
18
+
19
+ attr_reader :config, :logger
20
+
21
+ def initialize(*args)
22
+ if defined?(MOD_RUBY)
23
+ unless ENV.has_key?("GATEWAY_INTERFACE")
24
+ Apache.request.setup_cgi_env
25
+ end
26
+ end
27
+ if %r{HTTP/(\d+\.\d+)} =~ ENV["SERVER_PROTOCOL"]
28
+ httpv = $1
29
+ end
30
+ @config = WEBrick::Config::HTTP.dup.update(
31
+ :ServerSoftware => ENV["SERVER_SOFTWARE"] || "null",
32
+ :HTTPVersion => HTTPVersion.new(httpv || "1.0"),
33
+ :RunOnCGI => true, # to detect if it runs on CGI.
34
+ :NPH => false # set true to run as NPH script.
35
+ )
36
+ if config = args.shift
37
+ @config.update(config)
38
+ end
39
+ @config[:Logger] ||= WEBrick::BasicLog.new($stderr)
40
+ @logger = @config[:Logger]
41
+ @options = args
42
+ end
43
+
44
+ def [](key)
45
+ @config[key]
46
+ end
47
+
48
+ def start(env=ENV, stdin=$stdin, stdout=$stdout)
49
+ sock = WEBrick::CGI::Socket.new(@config, env, stdin, stdout)
50
+ req = HTTPRequest.new(@config)
51
+ res = HTTPResponse.new(@config)
52
+ unless @config[:NPH] or defined?(MOD_RUBY)
53
+ def res.setup_header
54
+ unless @header["status"]
55
+ phrase = HTTPStatus::reason_phrase(@status)
56
+ @header["status"] = "#{@status} #{phrase}"
57
+ end
58
+ super
59
+ end
60
+ def res.status_line
61
+ ""
62
+ end
63
+ end
64
+
65
+ begin
66
+ req.parse(sock)
67
+ req.script_name = (env["SCRIPT_NAME"] || File.expand_path($0)).dup
68
+ req.path_info = (env["PATH_INFO"] || "").dup
69
+ req.query_string = env["QUERY_STRING"]
70
+ req.user = env["REMOTE_USER"]
71
+ res.request_method = req.request_method
72
+ res.request_uri = req.request_uri
73
+ res.request_http_version = req.http_version
74
+ res.keep_alive = req.keep_alive?
75
+ self.service(req, res)
76
+ rescue HTTPStatus::Error => ex
77
+ res.set_error(ex)
78
+ rescue HTTPStatus::Status => ex
79
+ res.status = ex.code
80
+ rescue Exception => ex
81
+ @logger.error(ex)
82
+ res.set_error(ex, true)
83
+ ensure
84
+ req.fixup
85
+ if defined?(MOD_RUBY)
86
+ res.setup_header
87
+ Apache.request.status_line = "#{res.status} #{res.reason_phrase}"
88
+ Apache.request.status = res.status
89
+ table = Apache.request.headers_out
90
+ res.header.each{|key, val|
91
+ case key
92
+ when /^content-encoding$/i
93
+ Apache::request.content_encoding = val
94
+ when /^content-type$/i
95
+ Apache::request.content_type = val
96
+ else
97
+ table[key] = val.to_s
98
+ end
99
+ }
100
+ res.cookies.each{|cookie|
101
+ table.add("Set-Cookie", cookie.to_s)
102
+ }
103
+ Apache.request.send_http_header
104
+ res.send_body(sock)
105
+ else
106
+ res.send_response(sock)
107
+ end
108
+ end
109
+ end
110
+
111
+ def service(req, res)
112
+ method_name = "do_" + req.request_method.gsub(/-/, "_")
113
+ if respond_to?(method_name)
114
+ __send__(method_name, req, res)
115
+ else
116
+ raise HTTPStatus::MethodNotAllowed,
117
+ "unsupported method `#{req.request_method}'."
118
+ end
119
+ end
120
+
121
+ class Socket
122
+ include Enumerable
123
+
124
+ private
125
+
126
+ def initialize(config, env, stdin, stdout)
127
+ @config = config
128
+ @env = env
129
+ @header_part = StringIO.new
130
+ @body_part = stdin
131
+ @out_port = stdout
132
+ @out_port.binmode
133
+
134
+ @server_addr = @env["SERVER_ADDR"] || "0.0.0.0"
135
+ @server_name = @env["SERVER_NAME"]
136
+ @server_port = @env["SERVER_PORT"]
137
+ @remote_addr = @env["REMOTE_ADDR"]
138
+ @remote_host = @env["REMOTE_HOST"] || @remote_addr
139
+ @remote_port = @env["REMOTE_PORT"] || 0
140
+
141
+ begin
142
+ @header_part << request_line << CRLF
143
+ setup_header
144
+ @header_part << CRLF
145
+ @header_part.rewind
146
+ rescue Exception
147
+ raise CGIError, "invalid CGI environment"
148
+ end
149
+ end
150
+
151
+ def request_line
152
+ meth = @env["REQUEST_METHOD"] || "GET"
153
+ unless url = @env["REQUEST_URI"]
154
+ url = (@env["SCRIPT_NAME"] || File.expand_path($0)).dup
155
+ url << @env["PATH_INFO"].to_s
156
+ url = WEBrick::HTTPUtils.escape_path(url)
157
+ if query_string = @env["QUERY_STRING"]
158
+ unless query_string.empty?
159
+ url << "?" << query_string
160
+ end
161
+ end
162
+ end
163
+ # we cannot get real HTTP version of client ;)
164
+ httpv = @config[:HTTPVersion]
165
+ return "#{meth} #{url} HTTP/#{httpv}"
166
+ end
167
+
168
+ def setup_header
169
+ @env.each{|key, value|
170
+ case key
171
+ when "CONTENT_TYPE", "CONTENT_LENGTH"
172
+ add_header(key.gsub(/_/, "-"), value)
173
+ when /^HTTP_(.*)/
174
+ add_header($1.gsub(/_/, "-"), value)
175
+ end
176
+ }
177
+ end
178
+
179
+ def add_header(hdrname, value)
180
+ unless value.empty?
181
+ @header_part << hdrname << ": " << value << CRLF
182
+ end
183
+ end
184
+
185
+ def input
186
+ @header_part.eof? ? @body_part : @header_part
187
+ end
188
+
189
+ public
190
+
191
+ def peeraddr
192
+ [nil, @remote_port, @remote_host, @remote_addr]
193
+ end
194
+
195
+ def addr
196
+ [nil, @server_port, @server_name, @server_addr]
197
+ end
198
+
199
+ def gets(eol=LF, size=nil)
200
+ input.gets(eol, size)
201
+ end
202
+
203
+ def read(size=nil)
204
+ input.read(size)
205
+ end
206
+
207
+ def each
208
+ input.each{|line| yield(line) }
209
+ end
210
+
211
+ def eof?
212
+ input.eof?
213
+ end
214
+
215
+ def <<(data)
216
+ @out_port << data
217
+ end
218
+
219
+ def cert
220
+ return nil unless defined?(OpenSSL)
221
+ if pem = @env["SSL_SERVER_CERT"]
222
+ OpenSSL::X509::Certificate.new(pem) unless pem.empty?
223
+ end
224
+ end
225
+
226
+ def peer_cert
227
+ return nil unless defined?(OpenSSL)
228
+ if pem = @env["SSL_CLIENT_CERT"]
229
+ OpenSSL::X509::Certificate.new(pem) unless pem.empty?
230
+ end
231
+ end
232
+
233
+ def peer_cert_chain
234
+ return nil unless defined?(OpenSSL)
235
+ if @env["SSL_CLIENT_CERT_CHAIN_0"]
236
+ keys = @env.keys
237
+ certs = keys.sort.collect{|k|
238
+ if /^SSL_CLIENT_CERT_CHAIN_\d+$/ =~ k
239
+ if pem = @env[k]
240
+ OpenSSL::X509::Certificate.new(pem) unless pem.empty?
241
+ end
242
+ end
243
+ }
244
+ certs.compact
245
+ end
246
+ end
247
+
248
+ def cipher
249
+ return nil unless defined?(OpenSSL)
250
+ if cipher = @env["SSL_CIPHER"]
251
+ ret = [ cipher ]
252
+ ret << @env["SSL_PROTOCOL"]
253
+ ret << @env["SSL_CIPHER_USEKEYSIZE"]
254
+ ret << @env["SSL_CIPHER_ALGKEYSIZE"]
255
+ ret
256
+ end
257
+ end
258
+ end
259
+ end
260
+ end