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