HTTPServer
Some header fields should not be transferred.
# File webrick/httpproxy.rb, line 85
def do_CONNECT(req, res)
# Proxy Authentication
proxy_auth(req, res)
ua = Thread.current[:WEBrickSocket] # User-Agent
raise HTTPStatus::InternalServerError,
"[BUG] cannot get socket" unless ua
host, port = req.unparsed_uri.split(":", 2)
# Proxy authentication for upstream proxy server
if proxy = proxy_uri(req, res)
proxy_request_line = "CONNECT #{host}:#{port} HTTP/1.0"
if proxy.userinfo
credentials = "Basic " + [proxy.userinfo].pack("m").delete("\n")
end
host, port = proxy.host, proxy.port
end
begin
@logger.debug("CONNECT: upstream proxy is `#{host}:#{port}'.")
os = TCPSocket.new(host, port) # origin server
if proxy
@logger.debug("CONNECT: sending a Request-Line")
os << proxy_request_line << CRLF
@logger.debug("CONNECT: > #{proxy_request_line}")
if credentials
@logger.debug("CONNECT: sending a credentials")
os << "Proxy-Authorization: " << credentials << CRLF
end
os << CRLF
proxy_status_line = os.gets(LF)
@logger.debug("CONNECT: read a Status-Line form the upstream server")
@logger.debug("CONNECT: < #{proxy_status_line}")
if %{^HTTP/\d+\.\d+\s+200\s*} =~ proxy_status_line
while line = os.gets(LF)
break if /\A(#{CRLF}|#{LF})\z/m =~ line
end
else
raise HTTPStatus::BadGateway
end
end
@logger.debug("CONNECT #{host}:#{port}: succeeded")
res.status = HTTPStatus::RC_OK
rescue => ex
@logger.debug("CONNECT #{host}:#{port}: failed `#{ex.message}'")
res.set_error(ex)
raise HTTPStatus::EOFError
ensure
if handler = @config[:ProxyContentHandler]
handler.call(req, res)
end
res.send_response(ua)
access_log(@config, req, res)
# Should clear request-line not to send the sesponse twice.
# see: HTTPServer#run
req.parse(NullReader) rescue nil
end
begin
while fds = IO::select([ua, os])
if fds[0].member?(ua)
buf = ua.sysread(1024);
@logger.debug("CONNECT: #{buf.bytesize} byte from User-Agent")
os.syswrite(buf)
elsif fds[0].member?(os)
buf = os.sysread(1024);
@logger.debug("CONNECT: #{buf.bytesize} byte from #{host}:#{port}")
ua.syswrite(buf)
end
end
rescue => ex
os.close
@logger.debug("CONNECT #{host}:#{port}: closed")
end
raise HTTPStatus::EOFError
end
# File webrick/httpproxy.rb, line 165
def do_GET(req, res)
perform_proxy_request(req, res) do |http, path, header|
http.get(path, header)
end
end
# File webrick/httpproxy.rb, line 171
def do_HEAD(req, res)
perform_proxy_request(req, res) do |http, path, header|
http.head(path, header)
end
end
# File webrick/httpproxy.rb, line 183
def do_OPTIONS(req, res)
res['allow'] = "GET,HEAD,POST,OPTIONS,CONNECT"
end
# File webrick/httpproxy.rb, line 177
def do_POST(req, res)
perform_proxy_request(req, res) do |http, path, header|
http.post(path, req.body || "", header)
end
end
# File webrick/httpproxy.rb, line 53
def proxy_auth(req, res)
if proc = @config[:ProxyAuthProc]
proc.call(req, res)
end
req.header.delete("proxy-authorization")
end
# File webrick/httpproxy.rb, line 65
def proxy_service(req, res)
# Proxy Authentication
proxy_auth(req, res)
begin
self.send("do_#{req.request_method}", req, res)
rescue NoMethodError
raise HTTPStatus::MethodNotAllowed,
"unsupported method `#{req.request_method}'."
rescue => err
logger.debug("#{err.class}: #{err.message}")
raise HTTPStatus::ServiceUnavailable, err.message
end
# Process contents
if handler = @config[:ProxyContentHandler]
handler.call(req, res)
end
end