jscmd 0.0.2 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +8 -0
- data/Manifest.txt +11 -3
- data/Rakefile +1 -1
- data/bin/jscmd +326 -21
- data/examples/get_title.pl +22 -0
- data/lib/jscmd/agent.js +41 -19
- data/lib/jscmd/asynchttpproxy.rb +40 -4
- data/lib/jscmd/inprocessbroker.rb +31 -0
- data/lib/jscmd/message.rb +42 -0
- data/lib/jscmd/pipebroker.rb +62 -0
- data/lib/jscmd/proxyserver.rb +224 -0
- data/lib/jscmd/shell.rb +201 -0
- data/lib/jscmd/stompproxy.rb +36 -0
- data/lib/jscmd/urlforwarder.rb +43 -0
- data/lib/jscmd/version.rb +2 -2
- data/lib/jscmd.rb +14 -1
- data/test/test_helper.rb +4 -2
- data/test/{test_jscmd.rb → test_proxyserver.rb} +40 -46
- data/test/test_shell.rb +56 -0
- metadata +34 -8
- data/lib/jscmd/jscommander.rb +0 -339
@@ -1,42 +1,38 @@
|
|
1
|
-
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
2
|
|
3
|
-
$proxy_stdin, $proxy_stdin_writer = IO.pipe
|
4
|
-
$proxy_stdout_reader, $proxy_stdout = IO.pipe
|
5
|
-
|
6
|
-
$shell_pid = fork do
|
7
|
-
at_exit {} # prevent TestRunner from running
|
8
|
-
$stdin.reopen($proxy_stdin)
|
9
|
-
$stdout.reopen($proxy_stdout)
|
10
|
-
require File.dirname(__FILE__) + '/test_helper.rb'
|
11
|
-
server = JSCommander::Broker.new(:Port => $port, :AccessLog => [])
|
12
|
-
server.start
|
13
|
-
end
|
14
|
-
|
15
|
-
require "net/http"
|
16
3
|
require "open-uri"
|
17
|
-
require "test/unit"
|
18
|
-
require "zlib"
|
19
4
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
5
|
+
class TestProxyServer < Test::Unit::TestCase
|
6
|
+
PORT = 19000
|
7
|
+
|
8
|
+
def setup
|
9
|
+
unless $jscmd_proxy
|
10
|
+
$jscmd_broker = JSCommander::InProcessBroker.new
|
11
|
+
$jscmd_proxy = JSCommander::ProxyServer.new($jscmd_broker,
|
12
|
+
:Port => PORT, :AccessLog => [], :ProxyVia => nil)
|
13
|
+
Thread.start { $jscmd_proxy.start }
|
14
|
+
60.times do
|
15
|
+
begin
|
16
|
+
Net::HTTP.get("localhost", "/", PORT)
|
17
|
+
break
|
18
|
+
rescue Exception => e
|
19
|
+
end
|
20
|
+
puts "waiting..."
|
21
|
+
sleep 0.5
|
22
|
+
end
|
23
|
+
end
|
24
|
+
@proxy = $jscmd_proxy
|
25
|
+
@broker = $jscmd_broker
|
26
26
|
end
|
27
|
-
puts "waiting..."
|
28
|
-
sleep 0.5
|
29
|
-
end
|
30
27
|
|
31
|
-
class TestJscmd < Test::Unit::TestCase
|
32
28
|
def test_proxy
|
33
|
-
open("http://www.google.co.jp/", :proxy => "http://localhost:#{
|
29
|
+
open("http://www.google.co.jp/", :proxy => "http://localhost:#{PORT}/") do |f|
|
34
30
|
assert_match %r{/_remote_js_proxy/agent.js}, f.read
|
35
31
|
end
|
36
32
|
end
|
37
|
-
|
33
|
+
|
38
34
|
def test_proxy_with_gzip_compression
|
39
|
-
body = Net::HTTP.start("www.google.co.jp", 80, "localhost",
|
35
|
+
body = Net::HTTP.start("www.google.co.jp", 80, "localhost", PORT) do |h|
|
40
36
|
res = h.get("/",
|
41
37
|
"Accept-Encoding" => "gzip",
|
42
38
|
"User-Agent" => "Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; ja-JP-mac; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3")
|
@@ -47,28 +43,32 @@ class TestJscmd < Test::Unit::TestCase
|
|
47
43
|
end
|
48
44
|
|
49
45
|
def test_get_script
|
50
|
-
open("http://www.google.com/_remote_js_proxy/agent.js", :proxy => "http://localhost:#{
|
46
|
+
open("http://www.google.com/_remote_js_proxy/agent.js", :proxy => "http://localhost:#{PORT}/") do |f|
|
51
47
|
assert_equal File.read("lib/jscmd/agent.js"), f.read
|
52
48
|
end
|
53
49
|
end
|
54
50
|
|
55
51
|
def test_poll_and_get_command
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
assert_equal "Ewindow", f.read
|
52
|
+
@broker.send "commands", JSCommander::Message.new("window", :type => "eval")
|
53
|
+
open("http://www.google.com/_remote_js_proxy/poll", :proxy => "http://localhost:#{PORT}/") do |f|
|
54
|
+
assert_equal "window", f.read
|
60
55
|
end
|
61
56
|
end
|
62
|
-
|
57
|
+
|
63
58
|
def test_poll_and_post_value
|
64
59
|
begin
|
60
|
+
q = Queue.new
|
61
|
+
s = @broker.subscribe("events") do |msg|
|
62
|
+
q.push msg.body
|
63
|
+
end
|
65
64
|
body = nil
|
66
65
|
t = Thread.start do
|
67
66
|
# browser thread
|
68
67
|
begin
|
69
|
-
Net::HTTP.start("www.google.com", 80, "localhost",
|
68
|
+
Net::HTTP.start("www.google.com", 80, "localhost", PORT) do |h|
|
70
69
|
# (1) send value from browser to shell
|
71
|
-
body = h.post("/_remote_js_proxy/poll", "
|
70
|
+
body = h.post("/_remote_js_proxy/poll", "abc",
|
71
|
+
"X-JSCmd-Type" => "value",
|
72
72
|
"Content-Type" => "application/x-www-form-urlencoded").body
|
73
73
|
# (4) received another command and long-poll terminates
|
74
74
|
end
|
@@ -76,19 +76,13 @@ class TestJscmd < Test::Unit::TestCase
|
|
76
76
|
p e
|
77
77
|
end
|
78
78
|
end
|
79
|
-
assert_match(/(sleep|run)/, t.status)
|
80
79
|
# (2) read value sent from browser
|
81
|
-
assert_equal "abc
|
82
|
-
assert_match(/(sleep|run)/, t.status)
|
80
|
+
assert_equal "abc", q.pop
|
83
81
|
ensure
|
84
82
|
# (3) send another command to finish long-poll in browser
|
85
|
-
|
83
|
+
@broker.send("commands", JSCommander::Message.new("document", :type => "eval"))
|
86
84
|
t.join
|
87
|
-
assert_equal "
|
85
|
+
assert_equal "document", body
|
88
86
|
end
|
89
87
|
end
|
90
88
|
end
|
91
|
-
|
92
|
-
END { Process.kill "TERM", $shell_pid; Process.waitall }
|
93
|
-
|
94
|
-
exit Test::Unit::AutoRunner.run
|
data/test/test_shell.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
|
3
|
+
class TestShell < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@broker = JSCommander::InProcessBroker.new
|
6
|
+
@shell = JSCommander::Shell.new(@broker)
|
7
|
+
@output_reader, output = IO.pipe
|
8
|
+
input, @input_writer = IO.pipe
|
9
|
+
console = JSCommander::Shell::SimpleConsole.new(input)
|
10
|
+
@shell.instance_variable_set(:@console, console)
|
11
|
+
@shell.instance_variable_set(:@output, output)
|
12
|
+
def @shell.puts(msg)
|
13
|
+
@output.puts msg
|
14
|
+
end
|
15
|
+
@thread = Thread.start do
|
16
|
+
begin
|
17
|
+
@shell.run
|
18
|
+
rescue Exception
|
19
|
+
p $!
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def teardown
|
25
|
+
@input_writer.close
|
26
|
+
@thread.join
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_complete_property
|
30
|
+
@broker.subscribe("commands") do |msg|
|
31
|
+
assert_equal "this", msg.body
|
32
|
+
assert_equal "properties", msg.attributes["type"]
|
33
|
+
id = msg.attributes["id"]
|
34
|
+
@broker.send("events", JSCommander::Message.new("alert,abc,def", :type => "value",
|
35
|
+
"in-reply-to" => id))
|
36
|
+
end
|
37
|
+
assert_equal %w(alert abc), @shell.complete_property("a")
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_run
|
41
|
+
q = Queue.new
|
42
|
+
@broker.subscribe("commands") do |msg|
|
43
|
+
q.push msg
|
44
|
+
end
|
45
|
+
assert q.empty?
|
46
|
+
|
47
|
+
@input_writer.puts "window"
|
48
|
+
msg = q.pop
|
49
|
+
assert_equal "window", msg.body
|
50
|
+
id = msg.attributes["id"]
|
51
|
+
|
52
|
+
@broker.send("events", JSCommander::Message.new("foobar", :type => "value",
|
53
|
+
"in-reply-to" => id))
|
54
|
+
assert_equal "foobar\n", @output_reader.readline
|
55
|
+
end
|
56
|
+
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.2
|
|
3
3
|
specification_version: 1
|
4
4
|
name: jscmd
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.0
|
7
|
-
date: 2007-05-
|
6
|
+
version: 0.1.0
|
7
|
+
date: 2007-05-13 00:00:00 +09:00
|
8
8
|
summary: JavaScript console for any browser
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -37,17 +37,26 @@ files:
|
|
37
37
|
- Rakefile
|
38
38
|
- bin/jscmd
|
39
39
|
- lib/jscmd.rb
|
40
|
-
- lib/jscmd/version.rb
|
41
|
-
- lib/jscmd/jscommander.rb
|
42
40
|
- lib/jscmd/asynchttpproxy.rb
|
41
|
+
- lib/jscmd/inprocessbroker.rb
|
42
|
+
- lib/jscmd/message.rb
|
43
|
+
- lib/jscmd/pipebroker.rb
|
44
|
+
- lib/jscmd/proxyserver.rb
|
45
|
+
- lib/jscmd/shell.rb
|
46
|
+
- lib/jscmd/stompproxy.rb
|
47
|
+
- lib/jscmd/urlforwarder.rb
|
48
|
+
- lib/jscmd/version.rb
|
43
49
|
- lib/jscmd/agent.js
|
44
50
|
- scripts/txt2html
|
45
51
|
- setup.rb
|
46
52
|
- test/test_helper.rb
|
47
|
-
- test/
|
53
|
+
- test/test_proxyserver.rb
|
54
|
+
- test/test_shell.rb
|
55
|
+
- examples/get_title.pl
|
48
56
|
test_files:
|
49
57
|
- test/test_helper.rb
|
50
|
-
- test/
|
58
|
+
- test/test_proxyserver.rb
|
59
|
+
- test/test_shell.rb
|
51
60
|
rdoc_options: []
|
52
61
|
|
53
62
|
extra_rdoc_files: []
|
@@ -58,5 +67,22 @@ extensions: []
|
|
58
67
|
|
59
68
|
requirements: []
|
60
69
|
|
61
|
-
dependencies:
|
62
|
-
|
70
|
+
dependencies:
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: stomp
|
73
|
+
version_requirement:
|
74
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: 1.0.5
|
79
|
+
version:
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: stompserver
|
82
|
+
version_requirement:
|
83
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: 0.9.7
|
88
|
+
version:
|
data/lib/jscmd/jscommander.rb
DELETED
@@ -1,339 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# jscommander.rb: Remote JavaScript Console
|
3
|
-
#
|
4
|
-
# Copyright 2007 Shinya Kasatani
|
5
|
-
#
|
6
|
-
|
7
|
-
require 'uri'
|
8
|
-
require 'thread'
|
9
|
-
require 'webrick'
|
10
|
-
require 'zlib'
|
11
|
-
|
12
|
-
module JSCommander
|
13
|
-
SCRIPT_DIR = "/_remote_js_proxy/"
|
14
|
-
|
15
|
-
class PipeQueue
|
16
|
-
attr_reader :reader, :writer
|
17
|
-
|
18
|
-
def initialize
|
19
|
-
@reader, @writer = IO.pipe
|
20
|
-
end
|
21
|
-
|
22
|
-
def push(obj)
|
23
|
-
data = Marshal.dump(obj)
|
24
|
-
@writer.write([data.size].pack("N") + data)
|
25
|
-
end
|
26
|
-
|
27
|
-
def pop
|
28
|
-
size = @reader.read(4).unpack("N")[0]
|
29
|
-
Marshal.load(@reader.read(size))
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
# types are: V: value, E: error, A: active message from proxy
|
34
|
-
Message = Struct.new(:value, :type, :clients)
|
35
|
-
|
36
|
-
class Broker
|
37
|
-
attr_reader :cmd_queue, :msg_queue
|
38
|
-
|
39
|
-
def initialize(opts = {})
|
40
|
-
@cmd_queue = PipeQueue.new
|
41
|
-
@msg_queue = PipeQueue.new
|
42
|
-
@proxy = ProxyServer.new(self, opts)
|
43
|
-
@shell = Shell.new(self)
|
44
|
-
end
|
45
|
-
|
46
|
-
def start
|
47
|
-
@proxy_pid = fork do
|
48
|
-
begin
|
49
|
-
Signal.trap('INT') {}
|
50
|
-
Signal.trap('TERM') { @proxy.shutdown }
|
51
|
-
IO.for_fd(0).close
|
52
|
-
@proxy.start
|
53
|
-
rescue Exception => e
|
54
|
-
p e
|
55
|
-
end
|
56
|
-
end
|
57
|
-
Signal.trap("TERM") { shutdown }
|
58
|
-
@shell.run # @shell.run should block
|
59
|
-
end
|
60
|
-
|
61
|
-
def shutdown
|
62
|
-
$stderr.puts "shutdown"
|
63
|
-
Process.kill "TERM", @proxy_pid
|
64
|
-
Process.waitall
|
65
|
-
exit(0)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
class Shell
|
70
|
-
class SimpleConsole
|
71
|
-
def show_banner
|
72
|
-
end
|
73
|
-
|
74
|
-
def readline
|
75
|
-
line = $stdin.readline
|
76
|
-
line.chomp! if line
|
77
|
-
line
|
78
|
-
end
|
79
|
-
|
80
|
-
def close
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
class ReadlineConsole
|
85
|
-
HISTORY_PATH = "~/.jscmd_history"
|
86
|
-
|
87
|
-
def history_path
|
88
|
-
File.expand_path(HISTORY_PATH)
|
89
|
-
end
|
90
|
-
|
91
|
-
def initialize(shell)
|
92
|
-
@shell = shell
|
93
|
-
require 'readline'
|
94
|
-
if File.exist?(history_path)
|
95
|
-
hist = File.readlines(history_path).map{|line| line.chomp}
|
96
|
-
Readline::HISTORY.push(*hist)
|
97
|
-
end
|
98
|
-
Readline.basic_word_break_characters = " \t\n\\`@><=;|&{([+-*/%"
|
99
|
-
Readline.completion_append_character = nil
|
100
|
-
Readline.completion_proc = proc do |word|
|
101
|
-
if word =~ /\.$/
|
102
|
-
@shell.object_props($`).map{|name| word + name}
|
103
|
-
elsif word =~ /\.([^.]+)$/
|
104
|
-
prefix = $1
|
105
|
-
parent = $`
|
106
|
-
props = @shell.object_props(parent)
|
107
|
-
props.select{|name|name[0...(prefix.size)] == prefix}.map{|name| "#{parent}.#{name}"}
|
108
|
-
else
|
109
|
-
props = @shell.object_props("this")
|
110
|
-
prefix = word
|
111
|
-
props.select{|name|name[0...(prefix.size)] == prefix}
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
def show_banner
|
117
|
-
puts "Press Ctrl+D to exit."
|
118
|
-
end
|
119
|
-
|
120
|
-
def close
|
121
|
-
open(history_path, "ab") do |f|
|
122
|
-
Readline::HISTORY.each{|line| f.puts(line)}
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
def readline
|
127
|
-
line = Readline.readline("#{@shell.clients}> ", true)
|
128
|
-
Readline::HISTORY.pop if /^\s*$/ =~ line
|
129
|
-
line
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
def console
|
134
|
-
@console ||= $stdin.tty? ? ReadlineConsole.new(self) : SimpleConsole.new
|
135
|
-
end
|
136
|
-
|
137
|
-
attr_reader :clients
|
138
|
-
|
139
|
-
def initialize(broker)
|
140
|
-
@broker = broker
|
141
|
-
@clients = nil
|
142
|
-
@msg_lock = Mutex.new
|
143
|
-
end
|
144
|
-
|
145
|
-
def send_script(line, &handler)
|
146
|
-
@msg_lock.synchronize do
|
147
|
-
@broker.cmd_queue.push(line)
|
148
|
-
yield read_msg
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
def read_msg
|
153
|
-
msg = @broker.msg_queue.pop
|
154
|
-
# p msg
|
155
|
-
@clients = msg.clients
|
156
|
-
msg
|
157
|
-
end
|
158
|
-
|
159
|
-
def object_props(object)
|
160
|
-
send_script("P" + object) do |r|
|
161
|
-
if r.type == "V" && r.value
|
162
|
-
r.value.split(/,/)
|
163
|
-
else
|
164
|
-
[]
|
165
|
-
end
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
def run
|
170
|
-
# read and print messages in background
|
171
|
-
Thread.start do
|
172
|
-
while IO.select([@broker.msg_queue.reader], nil, nil, nil)
|
173
|
-
@msg_lock.synchronize do
|
174
|
-
if IO.select([@broker.msg_queue.reader], nil, nil, 0)
|
175
|
-
msg = read_msg
|
176
|
-
puts msg.value || ""
|
177
|
-
Process.kill "INT", $$ # interrupt readline
|
178
|
-
end
|
179
|
-
end
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
console.show_banner
|
184
|
-
|
185
|
-
begin
|
186
|
-
loop do
|
187
|
-
break unless line = console.readline
|
188
|
-
send_script("E" + line) do |msg|
|
189
|
-
puts msg.value if msg.value
|
190
|
-
end
|
191
|
-
end
|
192
|
-
rescue Interrupt
|
193
|
-
retry
|
194
|
-
rescue SystemExit
|
195
|
-
return
|
196
|
-
rescue Exception => e
|
197
|
-
$stderr.puts "#{e.inspect} at:\n#{e.backtrace.join("\n")}"
|
198
|
-
ensure
|
199
|
-
begin
|
200
|
-
console.close
|
201
|
-
rescue Exception => e
|
202
|
-
$stderr.puts "failed to close console: #{e.inspect}"
|
203
|
-
end
|
204
|
-
end
|
205
|
-
@broker.shutdown
|
206
|
-
end
|
207
|
-
end
|
208
|
-
|
209
|
-
class ProxyServer < WEBrick::AsyncHTTPProxyServer
|
210
|
-
def initialize(broker, args = {})
|
211
|
-
@broker = broker
|
212
|
-
@cmd_queue = PipeQueue.new
|
213
|
-
@clients = []
|
214
|
-
super({:ProxyContentHandler => method(:handle_content).to_proc}.merge(args))
|
215
|
-
end
|
216
|
-
|
217
|
-
def start
|
218
|
-
Thread.start do
|
219
|
-
sleep 1
|
220
|
-
begin
|
221
|
-
poll_cmd_queue
|
222
|
-
rescue Exception => e
|
223
|
-
p e
|
224
|
-
end
|
225
|
-
end
|
226
|
-
super
|
227
|
-
end
|
228
|
-
|
229
|
-
def service(req, res)
|
230
|
-
if req.path == "#{SCRIPT_DIR}agent.js"
|
231
|
-
res.content_type = "application/x-javascript"
|
232
|
-
res.body = File.read(File.join(File.dirname(__FILE__), "agent.js"))
|
233
|
-
elsif req.path == "#{SCRIPT_DIR}poll"
|
234
|
-
serve_script(req, res)
|
235
|
-
else
|
236
|
-
if req.header["accept-encoding"] && !req.header["accept-encoding"].empty?
|
237
|
-
if req.header["accept-encoding"].first.split(/,/).include?("gzip")
|
238
|
-
req.header["accept-encoding"] = ["gzip"]
|
239
|
-
else
|
240
|
-
req.header.delete "accept-encoding"
|
241
|
-
end
|
242
|
-
end
|
243
|
-
super
|
244
|
-
end
|
245
|
-
end
|
246
|
-
|
247
|
-
def format_clients
|
248
|
-
@clients.map{|c|"[#{URI.parse(c.header["referer"].to_s).host}]"}.join(",")
|
249
|
-
end
|
250
|
-
|
251
|
-
def poll_cmd_queue
|
252
|
-
while @status == :Running
|
253
|
-
cmd = @broker.cmd_queue.pop
|
254
|
-
cmd_line = cmd[1...(cmd.size)]
|
255
|
-
if cmd_line.strip.empty?
|
256
|
-
@broker.msg_queue.push(Message.new(nil, "V", format_clients))
|
257
|
-
else
|
258
|
-
@cmd_queue.push(cmd)
|
259
|
-
end
|
260
|
-
end
|
261
|
-
end
|
262
|
-
|
263
|
-
def serve_script(req, res)
|
264
|
-
# puts "serve:#{req.body}"
|
265
|
-
@clients << req
|
266
|
-
if req.body && req.body =~ /^(\+?)([VE])/
|
267
|
-
more = $1 == '+'
|
268
|
-
type = $2
|
269
|
-
# V: value
|
270
|
-
# E: error
|
271
|
-
@broker.msg_queue.push Message.new(URI.decode($'), type, format_clients)
|
272
|
-
if more
|
273
|
-
res.content_type = "text/plain"
|
274
|
-
res.body = ''
|
275
|
-
return
|
276
|
-
end
|
277
|
-
else
|
278
|
-
# empty message - maybe a new client connected?
|
279
|
-
@broker.msg_queue.push Message.new(nil, "A", format_clients)
|
280
|
-
end
|
281
|
-
while @status == :Running
|
282
|
-
req_socket = req.instance_eval{@socket}
|
283
|
-
sockets = [req_socket, @cmd_queue.reader]
|
284
|
-
if @clients.first != req
|
285
|
-
# don't poll cmd_queue if this is request is not the first one
|
286
|
-
sockets.pop
|
287
|
-
end
|
288
|
-
r = IO.select(sockets, nil, nil, 1)
|
289
|
-
if r
|
290
|
-
if r[0].include?(@cmd_queue.reader)
|
291
|
-
line = @cmd_queue.pop
|
292
|
-
res.content_type = "text/plain"
|
293
|
-
res.body = line
|
294
|
-
return
|
295
|
-
elsif r[0].include?(req_socket)
|
296
|
-
@clients.delete(req); req = nil
|
297
|
-
@broker.msg_queue.push(Message.new("aborted", "A", format_clients))
|
298
|
-
raise WEBrick::HTTPStatus::EOFError
|
299
|
-
end
|
300
|
-
end
|
301
|
-
end
|
302
|
-
# server is shutting down
|
303
|
-
raise WEBrick::HTTPStatus::EOFError
|
304
|
-
ensure
|
305
|
-
@clients.delete(req) if req
|
306
|
-
end
|
307
|
-
|
308
|
-
def handle_content(req, res)
|
309
|
-
# $stderr.puts "handle_content:type=#{res.content_type}, status=#{res.status}, encoding=#{res.header["content-encoding"]}"
|
310
|
-
if res.content_type =~ %r{^text/html} && res.status == 200
|
311
|
-
res.flush_body
|
312
|
-
# we cannot always trust content_type, so check if the content looks like html
|
313
|
-
body = res.body
|
314
|
-
if res.header["content-encoding"] == "gzip"
|
315
|
-
body = Zlib::GzipReader.new(StringIO.new(body)).read
|
316
|
-
end
|
317
|
-
if body =~ /^\s*</
|
318
|
-
body = body.dup
|
319
|
-
# puts "injecting javascript"
|
320
|
-
script_tag = '<script type="text/javascript" src="/_remote_js_proxy/agent.js"></script>'
|
321
|
-
unless body.sub!(%r{<head( .*?)?>}i){|s|s+script_tag}
|
322
|
-
body = script_tag + body
|
323
|
-
end
|
324
|
-
if res.header["content-encoding"] == "gzip"
|
325
|
-
io = StringIO.new
|
326
|
-
writer = Zlib::GzipWriter.new(io)
|
327
|
-
writer.write(body)
|
328
|
-
writer.close
|
329
|
-
res.body = io.string
|
330
|
-
else
|
331
|
-
res.body = body
|
332
|
-
end
|
333
|
-
res.content_length = res.body.size if res.content_length
|
334
|
-
end
|
335
|
-
end
|
336
|
-
end
|
337
|
-
end
|
338
|
-
end
|
339
|
-
|