]> code.delx.au - cgiproxy/blob - ruby/proxy.rb
27e5538587f02c9218c319fb53352a9cb76d363b
[cgiproxy] / ruby / proxy.rb
1 #!/usr/bin/env ruby
2
3 require 'net/http'
4 require 'net/https'
5 require 'uri'
6
7 class NilClass
8 # Make it easier to check for empty string or nil
9 def empty?; true; end
10 def to_s; ""; end
11 end
12
13
14 def getParams(url)
15 if !ENV["PATH_INFO"].empty?
16 url += ENV["PATH_INFO"]
17 end
18
19 url = URI.parse(url);
20 if !["http", "https"].include? url.scheme
21 raise RuntimeError, "Unsupported scheme: #{url.scheme}"
22 end
23
24 use_ssl = url.scheme == 'https'
25
26 filename = url.path
27 path = url.path
28 if !ENV["QUERY_STRING"].empty?
29 path += "?" + ENV["QUERY_STRING"]
30 end
31
32 return url.host, url.port, use_ssl, filename, path
33 end
34
35 def createRequest(method, path)
36 if method == "GET"
37 req = Net::HTTP::Get.new(path)
38 elsif method == "POST"
39 req = Net::HTTP::Post.new(path)
40 req.body = $stdin.read()
41 else
42 raise RuntimeError, "No support for method: #{method}"
43 end
44 return req
45 end
46
47 def insertHeaders(req, ffHeader)
48 if ffHeader
49 req["X-Forwarded-For"] = ENV["REMOTE_ADDR"]
50 end
51 req["Host"] = ENV["HTTP_HOST"]
52 req["Cookie"] = ENV["HTTP_COOKIE"]
53 req["Referer"] = ENV["HTTP_REFERER"]
54 req["Content-Length"] = ENV["CONTENT_LENGTH"]
55 req["Content-Type"] = ENV["CONTENT_TYPE"]
56 req["User-Agent"] = ENV["HTTP_USER_AGENT"]
57 req["Cache-Control"] = ENV["HTTP_CACHE_CONTROL"]
58 req["Authorization"] = ENV["HTTP_AUTHORIZATION"]
59 req["Accept"] = ENV["HTTP_ACCEPT"]
60 req["Accept-Charset"] = ENV["HTTP_ACCEPT_CHARSET"]
61 req["Accept-Encoding"] = ENV["HTTP_ACCEPT_ENCODING"]
62 req["Accept-Language"] = ENV["HTTP_ACCEPT_LANGUAGE"]
63 end
64
65 def doRequest(req, host, port, use_ssl)
66 # Make the request
67 http = Net::HTTP.new(host, port)
68 http.use_ssl = use_ssl
69 res = http.request(req)
70
71 # Tweak the headers a little
72 res.delete("transfer-encoding")
73 res.delete("transfer-length")
74 res["connection"] = "close"
75
76 return res
77 end
78
79 def printResult(res)
80 if res.code != "200"
81 res["Status"] = "#{res.code} #{res.message}"
82 end
83 res.each_capitalized_name do |key|
84 res.get_fields(key).each do |value|
85 print "#{key}: #{value}\r\n"
86 end
87 end
88 print "\r\n"
89 print res.body
90 end
91
92 def writeFile(res, filename, outputDir)
93 filename = filename.split("/")[-1]
94 File.open("#{outputDir}/#{filename}", 'w') {|f| f.write(res.body) }
95 end
96
97 def debug(msg)
98 File.open("/tmp/debuglog.txt", "a") { |f|
99 f << Time.new.to_s + " " + msg + "\n"
100 }
101 end
102
103 def proxyTo(basePath, ffHeader=True, outputDir=None)
104 host, port, use_ssl, filename, path = getParams(basePath)
105 req = createRequest(ENV["REQUEST_METHOD"], path)
106 insertHeaders(req, ffHeader)
107 res = doRequest(req, host, port, use_ssl)
108 writeFile(res, filename, outputDir)
109 printResult(res)
110 end
111