Extended maintenance of Ruby 1.9.3 ended on February 23, 2015. Read more
HTTPServer
An HTTP Proxy server which proxies GET, HEAD and POST requests.
Some header fields should not be transferred.
Proxy server configurations. The proxy server handles the following configuration items in addition to those supported by HTTPServer:
Called with a request and response to authorize a request
Appended to the via header
The proxy server’s URI
Called with a request and resopnse and allows modification of the response
Sets the proxy timeouts to 30 seconds for open and 60 seconds for read operations
# File webrick/httpproxy.rb, line 54 def initialize(config={}, default=Config::HTTP) super(config, default) c = @config @via = "#{c[:HTTPVersion]} #{c[:ServerName]}:#{c[:Port]}" end
# File webrick/httpproxy.rb, line 102 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 %r{^HTTP/\d+\.\d+\s+200\s*} =~ proxy_status_line while line = os.gets(LF) break if /\A(#{CRLF}|#{LF})\z/om =~ 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 182 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 188 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 200 def do_OPTIONS(req, res) res['allow'] = "GET,HEAD,POST,OPTIONS,CONNECT" end
# File webrick/httpproxy.rb, line 194 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 70 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 82 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
Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.
If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.
If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.
If you want to help improve the Ruby documentation, please visit Documenting-ruby.org.