source: extensions/gsdl-video/trunk/installed/cmdline/lib/ruby/1.8/webrick/cgi.rb@ 18425

Last change on this file since 18425 was 18425, checked in by davidb, 15 years ago

Video extension to Greenstone

File size: 6.9 KB
Line 
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: cgi.rb 11708 2007-02-12 23:01:19Z shyouhei $
9
10require "webrick/httprequest"
11require "webrick/httpresponse"
12require "webrick/config"
13require "stringio"
14
15module 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 => ex
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 add_header("CONTENT_TYPE", "Content-Type")
170 add_header("CONTENT_LENGTH", "Content-length")
171 @env.each_key{|name|
172 if /^HTTP_(.*)/ =~ name
173 add_header(name, $1.gsub(/_/, "-"))
174 end
175 }
176 end
177
178 def add_header(envname, hdrname)
179 if value = @env[envname]
180 unless value.empty?
181 @header_part << hdrname << ": " << value << CRLF
182 end
183 end
184 end
185
186 def input
187 @header_part.eof? ? @body_part : @header_part
188 end
189
190 public
191
192 def peeraddr
193 [nil, @remote_port, @remote_host, @remote_addr]
194 end
195
196 def addr
197 [nil, @server_port, @server_name, @server_addr]
198 end
199
200 def gets(eol=LF)
201 input.gets(eol)
202 end
203
204 def read(size=nil)
205 input.read(size)
206 end
207
208 def each
209 input.each{|line| yield(line) }
210 end
211
212 def <<(data)
213 @out_port << data
214 end
215
216 def cert
217 return nil unless defined?(OpenSSL)
218 if pem = @env["SSL_SERVER_CERT"]
219 OpenSSL::X509::Certificate.new(pem) unless pem.empty?
220 end
221 end
222
223 def peer_cert
224 return nil unless defined?(OpenSSL)
225 if pem = @env["SSL_CLIENT_CERT"]
226 OpenSSL::X509::Certificate.new(pem) unless pem.empty?
227 end
228 end
229
230 def peer_cert_chain
231 return nil unless defined?(OpenSSL)
232 if @env["SSL_CLIENT_CERT_CHAIN_0"]
233 keys = @env.keys
234 certs = keys.sort.collect{|k|
235 if /^SSL_CLIENT_CERT_CHAIN_\d+$/ =~ k
236 if pem = @env[k]
237 OpenSSL::X509::Certificate.new(pem) unless pem.empty?
238 end
239 end
240 }
241 certs.compact
242 end
243 end
244
245 def cipher
246 return nil unless defined?(OpenSSL)
247 if cipher = @env["SSL_CIPHER"]
248 ret = [ cipher ]
249 ret << @env["SSL_PROTOCOL"]
250 ret << @env["SSL_CIPHER_USEKEYSIZE"]
251 ret << @env["SSL_CIPHER_ALGKEYSIZE"]
252 ret
253 end
254 end
255 end
256 end
257end
Note: See TracBrowser for help on using the repository browser.