forked from vtss/json-rpc-util
-
Notifications
You must be signed in to change notification settings - Fork 0
/
proxy
executable file
·152 lines (122 loc) · 4.58 KB
/
proxy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#!/usr/bin/env ruby
require "uri"
require 'logger'
require 'webrick'
require 'optparse'
require "net/http"
require 'net/http/digest_auth'
require 'pp'
$options = {}
OptionParser.new do |opts|
opts.banner = """Usage: proxy [OPTIONS]
The proxy scripts implements a simple web server that can serve static content
from a global HTML folder, and forward requests to /json_spec and /json_rpc to a
specified address.
The purpose of this is to allow web development for the JSON-RPC interface on a
normal PC without having to upload new conetent to the device at every
iteration.
"""
opts.on("-d", "--dut ADDRESS", "Address to forward json requests to") do |v|
$options[:dut] = v
end
opts.on("-u", "--dut-username USERNAME", "Username to use when authenticating") do |v|
$options[:user] = v
end
opts.on("-p", "--dut-password PASSWORD", "Password to use when authenticating") do |v|
$options[:pass] = v
end
opts.on("-l", "--listin-port PORT", "TCP port to listen on") do |v|
$options[:port] = v.to_i
end
opts.on("-r", "--html-root ", "Folder to serve static HTML from") do |v|
$options[:root] = v
end
opts.on("--ssl", "Use ssl/https connection") do
$options[:ssl] = true
end
opts.on_tail("-h", "--help", "Show this message") do
puts opts
exit
end
end.parse!
if $options[:dut].nil?
puts "No dut specified. Please add '--dut ADDRESS'"
exit
end
$options[:port] = 8000 if $options[:port].nil?
$options[:pass] = "" if $options[:pass].nil?
$options[:user] = "admin" if $options[:admin].nil?
$options[:root] = "~/public_html" if $options[:root].nil?
$options[:ssl] = false if $options[:ssl].nil?
$l = Logger.new(STDOUT)
$l.level = Logger::INFO
logger_webbrick = Logger.new(STDOUT)
logger_webbrick.level = Logger::WARN
root = File.expand_path $options[:root]
server = WEBrick::HTTPServer.new :Port => $options[:port], :DocumentRoot => root, :AccessLog => [], :Logger => logger_webbrick, :BindAddress => "0.0.0.0"
def forward req, res
r = nil
headers = {}
req.header.each do |k, v|
headers[k] = v.join(", ") unless ["content-Length", "connection", "authorization", "host", "referer"].include?(k.downcase)
end
case req.request_method
when "GET"
r = Net::HTTPGenericRequest.new("GET", false, true, req.path, headers)
$l.info("REQUEST GET: #{req.path}")
when "POST"
r = Net::HTTPGenericRequest.new("POST", true, true, req.path, headers)
r.body = req.body
$l.info("REQUEST POST: #{req.path} -- #{r.body}")
else
raise "Not implemented"
end
http = nil
if $options[:ssl]
uri = URI.parse "https://#{$options[:dut]}"
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = $options[:ssl]
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
else
uri = URI.parse "http://#{$options[:dut]}"
http = Net::HTTP.new(uri.host, uri.port)
end
r.basic_auth $options[:user], $options[:pass]
response = http.request(r);
if response['www-authenticate']
uri = URI.parse "http://#{$options[:dut]}#{r.path}"
uri.user = 'admin'
uri.password = ''
digest_auth = Net::HTTP::DigestAuth.new
auth = digest_auth.auth_header(uri, response['www-authenticate'], req.request_method)
r.delete('Authorization')
r.add_field 'Authorization', auth
response = http.request(r);
end
response.each_header do |k, v|
res[k] = v unless ["Content-Length", "Connection", "Authorization"].include?(k)
end
res.status = response.code
res.request_http_version = response.http_version
case req.request_method
when "GET"
res.body = response.body
$l.info("RESPONSE GET: #{res.body}")
when "POST"
res.body = response.body
$l.info("RESPONSE POST: #{res.body}")
else
raise "Not implemented"
end
end
server.mount_proc '/json_rpc' do |req, res| forward(req, res) end
server.mount_proc '/json_spec' do |req, res| forward(req, res) end
server.mount_proc '/navbar.htm' do |req, res| forward(req, res) end
server.mount_proc '/lib/config.js' do |req, res| forward(req, res) end
server.mount_proc '/lib/navbarupdate.js' do |req, res| forward(req, res) end
server.mount_proc '/config' do |req, res| forward(req, res) end
server.mount_proc '/stat' do |req, res| forward(req, res) end
trap 'INT' do server.shutdown end
trap 'TERM' do server.shutdown end
$l.info "Starting HTML server on port #{$options[:port]}, forwarding to DUT at: #{$options[:dut]}, static html in: #{$options[:root]}"
server.start