]> code.delx.au - cgiproxy/blobdiff - ruby/proxy.rb
proxy.rb fixes
[cgiproxy] / ruby / proxy.rb
old mode 100755 (executable)
new mode 100644 (file)
index 21a92f4..bef8602
@@ -1,6 +1,7 @@
 #!/usr/bin/env ruby
 
 require 'net/http'
+require 'net/https'
 require 'uri'
 
 class NilClass
@@ -10,25 +11,35 @@ class NilClass
 end
 
 
-def getParams(url)
+def get_params(url)
        if !ENV["PATH_INFO"].empty?
                url += ENV["PATH_INFO"]
        end
 
        url = URI.parse(url);
-       if url.scheme != "http"
+       if !["http", "https"].include? url.scheme
                raise RuntimeError, "Unsupported scheme: #{url.scheme}"
        end
 
+       use_ssl = url.scheme == 'https'
+
+       filename = url.path.split("/")[-1]
        path = url.path
        if !ENV["QUERY_STRING"].empty?
                path += "?" + ENV["QUERY_STRING"]
        end
 
-       return url.host, url.port, path
+       return url.host, url.port, use_ssl, filename, path
+end
+
+def add_header(req, env_key, header_key)
+       value = ENV[env_key]
+       if !value.empty?
+               req[header_key] = value
+       end
 end
 
-def createRequest(method, path)
+def create_request(method, path, ff_header)
        if method == "GET"
                req = Net::HTTP::Get.new(path)
        elsif method == "POST"
@@ -37,50 +48,53 @@ def createRequest(method, path)
        else
                raise RuntimeError, "No support for method: #{method}"
        end
-       return req
-end
 
-def insertHeaders(req)
-       req["X-Forwarded-For"] = ENV["REMOTE_ADDR"]
-       req["Host"] = ENV["HTTP_HOST"]
-       req["Cookie"] = ENV["HTTP_COOKIE"]
-       req["Referer"] = ENV["HTTP_REFERER"]
-       req["Content-Length"] = ENV["CONTENT_LENGTH"]
-       req["Content-Type"] = ENV["CONTENT_TYPE"]
-       req["User-Agent"] = ENV["HTTP_USER_AGENT"]
-       req["Cache-Control"] = ENV["HTTP_CACHE_CONTROL"]
-       req["Authorization"] = ENV["HTTP_AUTHORIZATION"]
-       req["Accept"] = ENV["HTTP_ACCEPT"]
-       req["Accept-Charset"] = ENV["HTTP_ACCEPT_CHARSET"]
-       req["Accept-Encoding"] = ENV["HTTP_ACCEPT_ENCODING"]
-       req["Accept-Language"] = ENV["HTTP_ACCEPT_LANGUAGE"]
+       if ff_header
+               add_header(req, "REMOTE_ADDR", "X-Forwarded-For")
+       end
+       add_header(req, "HTTP_HOST", "Host")
+       add_header(req, "HTTP_COOKIE", "Cookie")
+       add_header(req, "HTTP_REFERER", "Referer")
+       add_header(req, "CONTENT_LENGTH", "Content-Length")
+       add_header(req, "CONTENT_TYPE", "Content-Type")
+       add_header(req, "HTTP_USER_AGENT", "User-Agent")
+       add_header(req, "HTTP_CACHE_CONTROL", "Cache-Control")
+       add_header(req, "HTTP_AUTHORIZATION", "Authorization")
+       add_header(req, "HTTP_ACCEPT", "Accept")
+       add_header(req, "HTTP_ACCEPT_CHARSET", "Accept-Charset")
+       add_header(req, "HTTP_ACCEPT_ENCODING", "Accept-Encoding")
+       add_header(req, "HTTP_ACCEPT_LANGUAGE", "Accept-Language")
+
+       return req
 end
 
-def doRequest(req, host, port)
+def do_proxy(req, host, port, use_ssl, filename, output_dir)
        # Make the request
-       res = Net::HTTP.start(host, port) do |http|
-               http.request(req)
-       end
+       http = Net::HTTP.new(host, port)
+       http.use_ssl = use_ssl
+       res = http.request req do |res|
 
-       # Tweak the headers a little
-       res.delete("transfer-encoding")
-       res.delete("transfer-length")
-       res["connection"] = "close"
-
-       return res
-end
+               if res.code != "200"
+                       res["Status"] = "#{res.code} #{res.message}"
+               end
+               res.each_capitalized_name do |key|
+                       res.get_fields(key).each do |value|
+                               $stdout.write "#{key}: #{value}\r\n"
+                       end
+               end
+               $stdout.write "\r\n"
 
-def printResult(res)
-       if res.code != "200"
-               res["Status"] = "#{res.code} #{res.message}"
-       end
-       res.each_capitalized_name do |key|
-               res.get_fields(key).each do |value|
-                       print "#{key}: #{value}\r\n"
+               out = nil
+               if output_dir
+                       out = File.open("#{output_dir}/#{filename}", 'w')
+               end
+               res.read_body do |chunk|
+                       $stdout.write chunk
+                       if out
+                               out.write chunk
+                       end
                end
        end
-       print "\r\n"
-       print res.body
 end
 
 def debug(msg)
@@ -89,11 +103,9 @@ def debug(msg)
        }
 end
 
-def proxyTo(basePath)
-       host, port, path = getParams(basePath)
-       req = createRequest(ENV["REQUEST_METHOD"], path)
-       insertHeaders(req)
-       res = doRequest(req, host, port)
-       printResult(res)
+def proxy_to(base_path, ff_header=True, output_dir=nil)
+       host, port, use_ssl, filename, path = get_params(base_path)
+       req = create_request(ENV["REQUEST_METHOD"], path, ff_header)
+       do_proxy(req, host, port, use_ssl, filename, output_dir)
 end