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
 
| 
         @@ -0,0 +1,62 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module JSCommander
         
     | 
| 
      
 2 
     | 
    
         
            +
              class PipeBroker
         
     | 
| 
      
 3 
     | 
    
         
            +
                class PipeQueue
         
     | 
| 
      
 4 
     | 
    
         
            +
                  attr_reader :reader, :writer
         
     | 
| 
      
 5 
     | 
    
         
            +
                  
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def initialize(r, w)
         
     | 
| 
      
 7 
     | 
    
         
            +
                    @reader, @writer = [r, w]
         
     | 
| 
      
 8 
     | 
    
         
            +
                  end
         
     | 
| 
      
 9 
     | 
    
         
            +
                  
         
     | 
| 
      
 10 
     | 
    
         
            +
                  def push(obj)
         
     | 
| 
      
 11 
     | 
    
         
            +
                    data = Marshal.dump(obj)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @writer.write([data.size].pack("N") + data)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
                  
         
     | 
| 
      
 15 
     | 
    
         
            +
                  def pop
         
     | 
| 
      
 16 
     | 
    
         
            +
                    size = @reader.read(4).unpack("N")[0]
         
     | 
| 
      
 17 
     | 
    
         
            +
                    Marshal.load(@reader.read(size))
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
                  
         
     | 
| 
      
 20 
     | 
    
         
            +
                  def close
         
     | 
| 
      
 21 
     | 
    
         
            +
                    @reader.close
         
     | 
| 
      
 22 
     | 
    
         
            +
                    @writer.close
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
              
         
     | 
| 
      
 26 
     | 
    
         
            +
                PipeMessage = Struct.new(:name, :message)
         
     | 
| 
      
 27 
     | 
    
         
            +
                
         
     | 
| 
      
 28 
     | 
    
         
            +
                def initialize(reader, writer)
         
     | 
| 
      
 29 
     | 
    
         
            +
                  @subscribers = {}
         
     | 
| 
      
 30 
     | 
    
         
            +
                  @queue = PipeQueue.new(reader, writer)
         
     | 
| 
      
 31 
     | 
    
         
            +
                  Thread.start do
         
     | 
| 
      
 32 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 33 
     | 
    
         
            +
                      loop do
         
     | 
| 
      
 34 
     | 
    
         
            +
                        pm = @queue.pop
         
     | 
| 
      
 35 
     | 
    
         
            +
                        if @subscribers[pm.name]
         
     | 
| 
      
 36 
     | 
    
         
            +
                          @subscribers[pm.name].each do |proc|
         
     | 
| 
      
 37 
     | 
    
         
            +
                            proc.call pm.message
         
     | 
| 
      
 38 
     | 
    
         
            +
                          end
         
     | 
| 
      
 39 
     | 
    
         
            +
                        end
         
     | 
| 
      
 40 
     | 
    
         
            +
                      end
         
     | 
| 
      
 41 
     | 
    
         
            +
                    rescue Exception
         
     | 
| 
      
 42 
     | 
    
         
            +
                      $stderr.puts $!
         
     | 
| 
      
 43 
     | 
    
         
            +
                    end
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                def subscribe(name, &proc)
         
     | 
| 
      
 48 
     | 
    
         
            +
                  @subscribers[name] ||= []
         
     | 
| 
      
 49 
     | 
    
         
            +
                  @subscribers[name] << proc
         
     | 
| 
      
 50 
     | 
    
         
            +
                  proc
         
     | 
| 
      
 51 
     | 
    
         
            +
                end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                def unsubscribe(name, subscriber)
         
     | 
| 
      
 54 
     | 
    
         
            +
                  sub = @subscribers[name].delete(subscriber)
         
     | 
| 
      
 55 
     | 
    
         
            +
                end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                def send(name, msg)
         
     | 
| 
      
 58 
     | 
    
         
            +
            #      puts "send #{name}, #{msg.inspect}"
         
     | 
| 
      
 59 
     | 
    
         
            +
                  @queue.push(PipeMessage.new(name, msg))
         
     | 
| 
      
 60 
     | 
    
         
            +
                end
         
     | 
| 
      
 61 
     | 
    
         
            +
              end
         
     | 
| 
      
 62 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,224 @@ 
     | 
|
| 
      
 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 
     | 
    
         
            +
            require "jscmd/asynchttpproxy"
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            module WEBrick
         
     | 
| 
      
 15 
     | 
    
         
            +
              class HTTPResponse
         
     | 
| 
      
 16 
     | 
    
         
            +
                alias_method :original_send_body, :send_body
         
     | 
| 
      
 17 
     | 
    
         
            +
                def send_body(socket)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 19 
     | 
    
         
            +
                    original_send_body(socket)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  rescue Errno::ECONNABORTED
         
     | 
| 
      
 21 
     | 
    
         
            +
                    raise Errno::ECONNRESET
         
     | 
| 
      
 22 
     | 
    
         
            +
                  end
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
            end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            module JSCommander
         
     | 
| 
      
 28 
     | 
    
         
            +
              class ProxyServer < WEBrick::AsyncHTTPProxyServer
         
     | 
| 
      
 29 
     | 
    
         
            +
                SCRIPT_DIR = "/_remote_js_proxy/"
         
     | 
| 
      
 30 
     | 
    
         
            +
                
         
     | 
| 
      
 31 
     | 
    
         
            +
                class CommandDispatcher
         
     | 
| 
      
 32 
     | 
    
         
            +
                  class CLIENT_ABORTED < StandardError; end
         
     | 
| 
      
 33 
     | 
    
         
            +
                  class SHUTDOWN < StandardError; end
         
     | 
| 
      
 34 
     | 
    
         
            +
                  
         
     | 
| 
      
 35 
     | 
    
         
            +
                  def initialize(server, command_queue)
         
     | 
| 
      
 36 
     | 
    
         
            +
                    @client_mutex = Mutex.new
         
     | 
| 
      
 37 
     | 
    
         
            +
                    @client_ready = ConditionVariable.new
         
     | 
| 
      
 38 
     | 
    
         
            +
                    @clients = []
         
     | 
| 
      
 39 
     | 
    
         
            +
                    @thread = Thread.start do
         
     | 
| 
      
 40 
     | 
    
         
            +
                      while server.status != :Shutdown
         
     | 
| 
      
 41 
     | 
    
         
            +
                        command = command_queue.pop
         
     | 
| 
      
 42 
     | 
    
         
            +
                        @client_mutex.synchronize do
         
     | 
| 
      
 43 
     | 
    
         
            +
                          while @clients.empty?
         
     | 
| 
      
 44 
     | 
    
         
            +
                            @client_ready.wait(@client_mutex)
         
     | 
| 
      
 45 
     | 
    
         
            +
                          end
         
     | 
| 
      
 46 
     | 
    
         
            +
                          @clients.first.push_command(command)
         
     | 
| 
      
 47 
     | 
    
         
            +
                        end
         
     | 
| 
      
 48 
     | 
    
         
            +
                      end
         
     | 
| 
      
 49 
     | 
    
         
            +
                    end
         
     | 
| 
      
 50 
     | 
    
         
            +
                  end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                  def shutdown
         
     | 
| 
      
 53 
     | 
    
         
            +
                    @clients.each do |client|
         
     | 
| 
      
 54 
     | 
    
         
            +
                      client.push_command SHUTDOWN
         
     | 
| 
      
 55 
     | 
    
         
            +
                    end
         
     | 
| 
      
 56 
     | 
    
         
            +
                  end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                  def format_clients
         
     | 
| 
      
 59 
     | 
    
         
            +
                    @clients.map{|c|"[#{c.hostname}]"}.join(",")
         
     | 
| 
      
 60 
     | 
    
         
            +
                  end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                  def new_client(req, &block)
         
     | 
| 
      
 63 
     | 
    
         
            +
                    client = Client.new(req)
         
     | 
| 
      
 64 
     | 
    
         
            +
                    @client_mutex.synchronize do
         
     | 
| 
      
 65 
     | 
    
         
            +
                      @clients << client
         
     | 
| 
      
 66 
     | 
    
         
            +
                      @client_ready.signal
         
     | 
| 
      
 67 
     | 
    
         
            +
                    end
         
     | 
| 
      
 68 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 69 
     | 
    
         
            +
                      yield client
         
     | 
| 
      
 70 
     | 
    
         
            +
                    ensure
         
     | 
| 
      
 71 
     | 
    
         
            +
                      @client_mutex.synchronize do
         
     | 
| 
      
 72 
     | 
    
         
            +
                        @clients.delete(client)
         
     | 
| 
      
 73 
     | 
    
         
            +
                      end
         
     | 
| 
      
 74 
     | 
    
         
            +
                    end
         
     | 
| 
      
 75 
     | 
    
         
            +
                  end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                  class Client
         
     | 
| 
      
 78 
     | 
    
         
            +
                    def initialize(req)
         
     | 
| 
      
 79 
     | 
    
         
            +
                      @request = req
         
     | 
| 
      
 80 
     | 
    
         
            +
                      @queue = Queue.new
         
     | 
| 
      
 81 
     | 
    
         
            +
                      req_socket = req.instance_eval{@socket}
         
     | 
| 
      
 82 
     | 
    
         
            +
                      @thread = Thread.start do
         
     | 
| 
      
 83 
     | 
    
         
            +
                        sleep 1 until req_socket.eof?
         
     | 
| 
      
 84 
     | 
    
         
            +
                        @queue.push CLIENT_ABORTED
         
     | 
| 
      
 85 
     | 
    
         
            +
                      end
         
     | 
| 
      
 86 
     | 
    
         
            +
                    end
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                    def hostname
         
     | 
| 
      
 89 
     | 
    
         
            +
                      uri = @request.header["referer"].to_s
         
     | 
| 
      
 90 
     | 
    
         
            +
                      if uri =~ %r{^\w+://([^/]+)}
         
     | 
| 
      
 91 
     | 
    
         
            +
                        $1
         
     | 
| 
      
 92 
     | 
    
         
            +
                      else
         
     | 
| 
      
 93 
     | 
    
         
            +
                        uri
         
     | 
| 
      
 94 
     | 
    
         
            +
                      end
         
     | 
| 
      
 95 
     | 
    
         
            +
                    end
         
     | 
| 
      
 96 
     | 
    
         
            +
                    
         
     | 
| 
      
 97 
     | 
    
         
            +
                    def push_command(command)
         
     | 
| 
      
 98 
     | 
    
         
            +
                      @queue.push(command)
         
     | 
| 
      
 99 
     | 
    
         
            +
                    end
         
     | 
| 
      
 100 
     | 
    
         
            +
                    
         
     | 
| 
      
 101 
     | 
    
         
            +
                    def pop_command
         
     | 
| 
      
 102 
     | 
    
         
            +
                      r = @queue.pop
         
     | 
| 
      
 103 
     | 
    
         
            +
                      # thread is automatically stopped if r == CLIENT_ABORTED
         
     | 
| 
      
 104 
     | 
    
         
            +
                      if r != CLIENT_ABORTED
         
     | 
| 
      
 105 
     | 
    
         
            +
                        @thread.kill
         
     | 
| 
      
 106 
     | 
    
         
            +
                      end
         
     | 
| 
      
 107 
     | 
    
         
            +
                      r
         
     | 
| 
      
 108 
     | 
    
         
            +
                    end
         
     | 
| 
      
 109 
     | 
    
         
            +
                  end
         
     | 
| 
      
 110 
     | 
    
         
            +
                end
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
                def initialize(broker, args = {})
         
     | 
| 
      
 113 
     | 
    
         
            +
                  @broker = broker
         
     | 
| 
      
 114 
     | 
    
         
            +
                  @commands = Queue.new
         
     | 
| 
      
 115 
     | 
    
         
            +
                  @command_dispatcher = CommandDispatcher.new(self, @commands)
         
     | 
| 
      
 116 
     | 
    
         
            +
                  @broker.subscribe("commands") do |msg|
         
     | 
| 
      
 117 
     | 
    
         
            +
                    if msg.attributes["type"] == "ping"
         
     | 
| 
      
 118 
     | 
    
         
            +
                      @broker.send("events", Message.new(nil, 
         
     | 
| 
      
 119 
     | 
    
         
            +
                                                         :type => "pong", 
         
     | 
| 
      
 120 
     | 
    
         
            +
                                                         :clients => @command_dispatcher.format_clients,
         
     | 
| 
      
 121 
     | 
    
         
            +
                                                         "in-reply-to" => msg.attributes["id"]))
         
     | 
| 
      
 122 
     | 
    
         
            +
                    else
         
     | 
| 
      
 123 
     | 
    
         
            +
                      @commands.push(msg)
         
     | 
| 
      
 124 
     | 
    
         
            +
                    end
         
     | 
| 
      
 125 
     | 
    
         
            +
                  end
         
     | 
| 
      
 126 
     | 
    
         
            +
                  @clients = []
         
     | 
| 
      
 127 
     | 
    
         
            +
                  super({:ProxyContentHandler => method(:handle_content).to_proc}.merge(args))
         
     | 
| 
      
 128 
     | 
    
         
            +
                end
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
                def service(req, res)
         
     | 
| 
      
 131 
     | 
    
         
            +
                  if req.path == "#{SCRIPT_DIR}agent.js"
         
     | 
| 
      
 132 
     | 
    
         
            +
                    res.content_type = "application/x-javascript"
         
     | 
| 
      
 133 
     | 
    
         
            +
                    res.body = File.read(File.join(File.dirname(__FILE__), "agent.js"))
         
     | 
| 
      
 134 
     | 
    
         
            +
                  elsif req.path == "#{SCRIPT_DIR}poll"
         
     | 
| 
      
 135 
     | 
    
         
            +
                    serve_script(req, res)
         
     | 
| 
      
 136 
     | 
    
         
            +
                  else
         
     | 
| 
      
 137 
     | 
    
         
            +
                    if req.header["accept-encoding"] && !req.header["accept-encoding"].empty?
         
     | 
| 
      
 138 
     | 
    
         
            +
                      if req.header["accept-encoding"].first.split(/,/).include?("gzip")
         
     | 
| 
      
 139 
     | 
    
         
            +
                        req.header["accept-encoding"] = ["gzip"]
         
     | 
| 
      
 140 
     | 
    
         
            +
                      else
         
     | 
| 
      
 141 
     | 
    
         
            +
                        req.header.delete "accept-encoding"
         
     | 
| 
      
 142 
     | 
    
         
            +
                      end
         
     | 
| 
      
 143 
     | 
    
         
            +
                    end
         
     | 
| 
      
 144 
     | 
    
         
            +
                    super
         
     | 
| 
      
 145 
     | 
    
         
            +
                  end
         
     | 
| 
      
 146 
     | 
    
         
            +
                end
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
                def shutdown
         
     | 
| 
      
 149 
     | 
    
         
            +
                  @command_dispatcher.shutdown
         
     | 
| 
      
 150 
     | 
    
         
            +
                  super
         
     | 
| 
      
 151 
     | 
    
         
            +
                end
         
     | 
| 
      
 152 
     | 
    
         
            +
             
     | 
| 
      
 153 
     | 
    
         
            +
                def serve_script(req, res)
         
     | 
| 
      
 154 
     | 
    
         
            +
                  # puts "serve:#{req.body}"
         
     | 
| 
      
 155 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 156 
     | 
    
         
            +
                    @command_dispatcher.new_client(req) do |client|
         
     | 
| 
      
 157 
     | 
    
         
            +
                      type = req.header["x-jscmd-type"].first
         
     | 
| 
      
 158 
     | 
    
         
            +
                      if type && type != "connect"
         
     | 
| 
      
 159 
     | 
    
         
            +
                        @broker.send("events", Message.new(URI.decode(req.body), 
         
     | 
| 
      
 160 
     | 
    
         
            +
                                                           :type => type,
         
     | 
| 
      
 161 
     | 
    
         
            +
                                                           :clients => @command_dispatcher.format_clients,
         
     | 
| 
      
 162 
     | 
    
         
            +
                                                           "in-reply-to" => req.header["x-jscmd-in-reply-to"].first))
         
     | 
| 
      
 163 
     | 
    
         
            +
                        if "true" == req.header["x-jscmd-more"].first
         
     | 
| 
      
 164 
     | 
    
         
            +
                          # immediately send empty response to wait for another event
         
     | 
| 
      
 165 
     | 
    
         
            +
                          res.content_type = "text/plain"
         
     | 
| 
      
 166 
     | 
    
         
            +
                          res.body = ''
         
     | 
| 
      
 167 
     | 
    
         
            +
                          return
         
     | 
| 
      
 168 
     | 
    
         
            +
                        end
         
     | 
| 
      
 169 
     | 
    
         
            +
                      else
         
     | 
| 
      
 170 
     | 
    
         
            +
                        # new connection
         
     | 
| 
      
 171 
     | 
    
         
            +
                        @broker.send("events", Message.new(nil, :type => "connect",
         
     | 
| 
      
 172 
     | 
    
         
            +
                                                           :clients => @command_dispatcher.format_clients))
         
     | 
| 
      
 173 
     | 
    
         
            +
                      end
         
     | 
| 
      
 174 
     | 
    
         
            +
                      
         
     | 
| 
      
 175 
     | 
    
         
            +
                      command = client.pop_command
         
     | 
| 
      
 176 
     | 
    
         
            +
                      if command.is_a?(Class) # exception class
         
     | 
| 
      
 177 
     | 
    
         
            +
                        raise command
         
     | 
| 
      
 178 
     | 
    
         
            +
                      end
         
     | 
| 
      
 179 
     | 
    
         
            +
                      res.content_type = "text/plain"
         
     | 
| 
      
 180 
     | 
    
         
            +
                      res.header["X-JSCmd-Command-Id"] = command.attributes["id"]
         
     | 
| 
      
 181 
     | 
    
         
            +
                      res.header["X-JSCmd-Type"] = command.attributes["type"]
         
     | 
| 
      
 182 
     | 
    
         
            +
                      res.body = command.body
         
     | 
| 
      
 183 
     | 
    
         
            +
                    end
         
     | 
| 
      
 184 
     | 
    
         
            +
                  rescue CommandDispatcher::CLIENT_ABORTED
         
     | 
| 
      
 185 
     | 
    
         
            +
                    @broker.send("events", Message.new(nil, :type => "abort",
         
     | 
| 
      
 186 
     | 
    
         
            +
                                                       :clients => @command_dispatcher.format_clients))
         
     | 
| 
      
 187 
     | 
    
         
            +
                    raise WEBrick::HTTPStatus::EOFError
         
     | 
| 
      
 188 
     | 
    
         
            +
                  rescue CommandDispatcher::SHUTDOWN
         
     | 
| 
      
 189 
     | 
    
         
            +
                    raise WEBrick::HTTPStatus::EOFError
         
     | 
| 
      
 190 
     | 
    
         
            +
                  end
         
     | 
| 
      
 191 
     | 
    
         
            +
                end
         
     | 
| 
      
 192 
     | 
    
         
            +
             
     | 
| 
      
 193 
     | 
    
         
            +
                def handle_content(req, res)
         
     | 
| 
      
 194 
     | 
    
         
            +
                  # $stderr.puts "handle_content:type=#{res.content_type}, status=#{res.status}, encoding=#{res.header["content-encoding"]}"
         
     | 
| 
      
 195 
     | 
    
         
            +
                  if res.content_type =~ %r{^text/html} && res.status == 200
         
     | 
| 
      
 196 
     | 
    
         
            +
                    res.flush_body
         
     | 
| 
      
 197 
     | 
    
         
            +
                    # we cannot always trust content_type, so check if the content looks like html
         
     | 
| 
      
 198 
     | 
    
         
            +
                    body = res.body
         
     | 
| 
      
 199 
     | 
    
         
            +
                    if res.header["content-encoding"] == "gzip"
         
     | 
| 
      
 200 
     | 
    
         
            +
                      body = Zlib::GzipReader.new(StringIO.new(body)).read
         
     | 
| 
      
 201 
     | 
    
         
            +
                    end
         
     | 
| 
      
 202 
     | 
    
         
            +
                    if body =~ /^\s*</
         
     | 
| 
      
 203 
     | 
    
         
            +
                      body = body.dup
         
     | 
| 
      
 204 
     | 
    
         
            +
                      # puts "injecting javascript"
         
     | 
| 
      
 205 
     | 
    
         
            +
                      script_tag = '<script type="text/javascript" src="/_remote_js_proxy/agent.js"></script>'
         
     | 
| 
      
 206 
     | 
    
         
            +
                      unless body.sub!(%r{<head( .*?)?>}i){|s|s+script_tag}
         
     | 
| 
      
 207 
     | 
    
         
            +
                        body = script_tag + body
         
     | 
| 
      
 208 
     | 
    
         
            +
                      end
         
     | 
| 
      
 209 
     | 
    
         
            +
                      if res.header["content-encoding"] == "gzip"
         
     | 
| 
      
 210 
     | 
    
         
            +
                        io = StringIO.new
         
     | 
| 
      
 211 
     | 
    
         
            +
                        writer = Zlib::GzipWriter.new(io)
         
     | 
| 
      
 212 
     | 
    
         
            +
                        writer.write(body)
         
     | 
| 
      
 213 
     | 
    
         
            +
                        writer.close
         
     | 
| 
      
 214 
     | 
    
         
            +
                        res.body = io.string
         
     | 
| 
      
 215 
     | 
    
         
            +
                      else
         
     | 
| 
      
 216 
     | 
    
         
            +
                        res.body = body
         
     | 
| 
      
 217 
     | 
    
         
            +
                      end
         
     | 
| 
      
 218 
     | 
    
         
            +
                      res.content_length = res.body.size if res.content_length
         
     | 
| 
      
 219 
     | 
    
         
            +
                    end
         
     | 
| 
      
 220 
     | 
    
         
            +
                  end
         
     | 
| 
      
 221 
     | 
    
         
            +
                end
         
     | 
| 
      
 222 
     | 
    
         
            +
              end
         
     | 
| 
      
 223 
     | 
    
         
            +
            end
         
     | 
| 
      
 224 
     | 
    
         
            +
             
     | 
    
        data/lib/jscmd/shell.rb
    ADDED
    
    | 
         @@ -0,0 +1,201 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            begin
         
     | 
| 
      
 2 
     | 
    
         
            +
              require "readline"
         
     | 
| 
      
 3 
     | 
    
         
            +
            rescue LoadError
         
     | 
| 
      
 4 
     | 
    
         
            +
            end
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            module JSCommander
         
     | 
| 
      
 7 
     | 
    
         
            +
              class Shell
         
     | 
| 
      
 8 
     | 
    
         
            +
                class SimpleConsole
         
     | 
| 
      
 9 
     | 
    
         
            +
                  def initialize(input = $stdin)
         
     | 
| 
      
 10 
     | 
    
         
            +
                    @input = input
         
     | 
| 
      
 11 
     | 
    
         
            +
                  end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                  def show_banner
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  def readline
         
     | 
| 
      
 17 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 18 
     | 
    
         
            +
                      line = @input.readline
         
     | 
| 
      
 19 
     | 
    
         
            +
                      line.chomp! if line
         
     | 
| 
      
 20 
     | 
    
         
            +
                      line
         
     | 
| 
      
 21 
     | 
    
         
            +
                    rescue EOFError
         
     | 
| 
      
 22 
     | 
    
         
            +
                      nil
         
     | 
| 
      
 23 
     | 
    
         
            +
                    end
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
                  
         
     | 
| 
      
 26 
     | 
    
         
            +
                  def close
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
                
         
     | 
| 
      
 30 
     | 
    
         
            +
                class ReadlineConsole
         
     | 
| 
      
 31 
     | 
    
         
            +
                  HISTORY_FILE = ".jscmd_history"
         
     | 
| 
      
 32 
     | 
    
         
            +
                  MAX_HISTORY = 200
         
     | 
| 
      
 33 
     | 
    
         
            +
                  
         
     | 
| 
      
 34 
     | 
    
         
            +
                  def history_path
         
     | 
| 
      
 35 
     | 
    
         
            +
                    File.join(ENV['HOME'] || ENV['USERPROFILE'], HISTORY_FILE)
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                  def initialize(shell)
         
     | 
| 
      
 39 
     | 
    
         
            +
                    @shell = shell
         
     | 
| 
      
 40 
     | 
    
         
            +
                    if File.exist?(history_path)
         
     | 
| 
      
 41 
     | 
    
         
            +
                      hist = File.readlines(history_path).map{|line| line.chomp}
         
     | 
| 
      
 42 
     | 
    
         
            +
                      Readline::HISTORY.push(*hist)
         
     | 
| 
      
 43 
     | 
    
         
            +
                    end
         
     | 
| 
      
 44 
     | 
    
         
            +
                    if Readline.methods.include?("basic_word_break_characters=")
         
     | 
| 
      
 45 
     | 
    
         
            +
                      Readline.basic_word_break_characters = " \t\n\\`@><=;|&{([+-*/%"
         
     | 
| 
      
 46 
     | 
    
         
            +
                    end
         
     | 
| 
      
 47 
     | 
    
         
            +
                    Readline.completion_append_character = nil
         
     | 
| 
      
 48 
     | 
    
         
            +
                    Readline.completion_proc = @shell.method(:complete_property).to_proc
         
     | 
| 
      
 49 
     | 
    
         
            +
                  end
         
     | 
| 
      
 50 
     | 
    
         
            +
                  
         
     | 
| 
      
 51 
     | 
    
         
            +
                  def show_banner
         
     | 
| 
      
 52 
     | 
    
         
            +
                    $stderr.puts "Press Ctrl+D to exit."
         
     | 
| 
      
 53 
     | 
    
         
            +
                  end
         
     | 
| 
      
 54 
     | 
    
         
            +
                  
         
     | 
| 
      
 55 
     | 
    
         
            +
                  def close
         
     | 
| 
      
 56 
     | 
    
         
            +
                    open(history_path, "wb") do |f|
         
     | 
| 
      
 57 
     | 
    
         
            +
                      history = Readline::HISTORY.to_a
         
     | 
| 
      
 58 
     | 
    
         
            +
                      if history.size > MAX_HISTORY
         
     | 
| 
      
 59 
     | 
    
         
            +
                        history = history[history.size - MAX_HISTORY, MAX_HISTORY]
         
     | 
| 
      
 60 
     | 
    
         
            +
                      end
         
     | 
| 
      
 61 
     | 
    
         
            +
                      history.each{|line| f.puts(line)}
         
     | 
| 
      
 62 
     | 
    
         
            +
                    end
         
     | 
| 
      
 63 
     | 
    
         
            +
                  end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                  def readline
         
     | 
| 
      
 66 
     | 
    
         
            +
                    line = Readline.readline("#{@shell.clients}> ", true)
         
     | 
| 
      
 67 
     | 
    
         
            +
                    Readline::HISTORY.pop if /^\s*$/ =~ line
         
     | 
| 
      
 68 
     | 
    
         
            +
                    line
         
     | 
| 
      
 69 
     | 
    
         
            +
                  end
         
     | 
| 
      
 70 
     | 
    
         
            +
                end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                def console
         
     | 
| 
      
 73 
     | 
    
         
            +
                  @console ||= $stdin.tty? ? ReadlineConsole.new(self) : SimpleConsole.new
         
     | 
| 
      
 74 
     | 
    
         
            +
                  # @console ||= SimpleConsole.new
         
     | 
| 
      
 75 
     | 
    
         
            +
                end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                attr_reader :clients
         
     | 
| 
      
 78 
     | 
    
         
            +
                
         
     | 
| 
      
 79 
     | 
    
         
            +
                def initialize(broker)
         
     | 
| 
      
 80 
     | 
    
         
            +
                  @broker = broker
         
     | 
| 
      
 81 
     | 
    
         
            +
                  @clients = nil
         
     | 
| 
      
 82 
     | 
    
         
            +
                  @msg_lock = Mutex.new
         
     | 
| 
      
 83 
     | 
    
         
            +
                  @wait_for_event = {}
         
     | 
| 
      
 84 
     | 
    
         
            +
                end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                def generate_id
         
     | 
| 
      
 87 
     | 
    
         
            +
                  Array.new(16){rand(62)}.pack("C*").tr("\x00-\x3d", "A-Za-z0-9")
         
     | 
| 
      
 88 
     | 
    
         
            +
                end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                def send_script(line, type, &handler)
         
     | 
| 
      
 91 
     | 
    
         
            +
                  queue = Queue.new
         
     | 
| 
      
 92 
     | 
    
         
            +
                  @msg_lock.synchronize do
         
     | 
| 
      
 93 
     | 
    
         
            +
                    id = generate_id
         
     | 
| 
      
 94 
     | 
    
         
            +
                    @broker.send "commands", Message.new(line, 
         
     | 
| 
      
 95 
     | 
    
         
            +
                                                         :type => type, 
         
     | 
| 
      
 96 
     | 
    
         
            +
                                                         :id => id)
         
     | 
| 
      
 97 
     | 
    
         
            +
                    # wait until it gets response
         
     | 
| 
      
 98 
     | 
    
         
            +
                    @wait_for_event[id] = [queue, proc{|msg| yield msg}]
         
     | 
| 
      
 99 
     | 
    
         
            +
                  end
         
     | 
| 
      
 100 
     | 
    
         
            +
                  queue.pop
         
     | 
| 
      
 101 
     | 
    
         
            +
                end
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
                def object_props(object)
         
     | 
| 
      
 104 
     | 
    
         
            +
                  send_script(object, "properties") do |msg|
         
     | 
| 
      
 105 
     | 
    
         
            +
                    if msg.attributes["type"] == "value" && msg.body
         
     | 
| 
      
 106 
     | 
    
         
            +
                      msg.body.split(/,/)
         
     | 
| 
      
 107 
     | 
    
         
            +
                    else
         
     | 
| 
      
 108 
     | 
    
         
            +
                      []
         
     | 
| 
      
 109 
     | 
    
         
            +
                    end
         
     | 
| 
      
 110 
     | 
    
         
            +
                  end
         
     | 
| 
      
 111 
     | 
    
         
            +
                end
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
                def complete_property(word)
         
     | 
| 
      
 114 
     | 
    
         
            +
                  if word =~ /\.$/
         
     | 
| 
      
 115 
     | 
    
         
            +
                    object_props($`).map{|name| word + name}
         
     | 
| 
      
 116 
     | 
    
         
            +
                  elsif word =~ /\.([^.]+)$/
         
     | 
| 
      
 117 
     | 
    
         
            +
                    prefix = $1
         
     | 
| 
      
 118 
     | 
    
         
            +
                    parent = $`
         
     | 
| 
      
 119 
     | 
    
         
            +
                    props = object_props(parent)
         
     | 
| 
      
 120 
     | 
    
         
            +
                    props.select{|name|name[0...(prefix.size)] == prefix}.map{|name| "#{parent}.#{name}"}
         
     | 
| 
      
 121 
     | 
    
         
            +
                  else
         
     | 
| 
      
 122 
     | 
    
         
            +
                    props = object_props("this")
         
     | 
| 
      
 123 
     | 
    
         
            +
                    prefix = word
         
     | 
| 
      
 124 
     | 
    
         
            +
                    props.select{|name|name[0...(prefix.size)] == prefix}
         
     | 
| 
      
 125 
     | 
    
         
            +
                  end
         
     | 
| 
      
 126 
     | 
    
         
            +
                end
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
                def run
         
     | 
| 
      
 129 
     | 
    
         
            +
                  console.show_banner
         
     | 
| 
      
 130 
     | 
    
         
            +
                  
         
     | 
| 
      
 131 
     | 
    
         
            +
                  main_thread = Thread.current
         
     | 
| 
      
 132 
     | 
    
         
            +
                  
         
     | 
| 
      
 133 
     | 
    
         
            +
                  @broker.subscribe("events") do |msg|
         
     | 
| 
      
 134 
     | 
    
         
            +
                    id = msg.attributes["in-reply-to"]
         
     | 
| 
      
 135 
     | 
    
         
            +
                    type = msg.attributes["type"]
         
     | 
| 
      
 136 
     | 
    
         
            +
                    @clients = msg.attributes["clients"]
         
     | 
| 
      
 137 
     | 
    
         
            +
                    if id
         
     | 
| 
      
 138 
     | 
    
         
            +
                      @msg_lock.synchronize do
         
     | 
| 
      
 139 
     | 
    
         
            +
                        handler = @wait_for_event.delete(id)
         
     | 
| 
      
 140 
     | 
    
         
            +
                        if handler
         
     | 
| 
      
 141 
     | 
    
         
            +
                          queue, proc = handler
         
     | 
| 
      
 142 
     | 
    
         
            +
                          queue.push(proc.call(msg))
         
     | 
| 
      
 143 
     | 
    
         
            +
                        end
         
     | 
| 
      
 144 
     | 
    
         
            +
                      end
         
     | 
| 
      
 145 
     | 
    
         
            +
                      msg = nil
         
     | 
| 
      
 146 
     | 
    
         
            +
                    elsif "abort" == type
         
     | 
| 
      
 147 
     | 
    
         
            +
                      @msg_lock.synchronize do
         
     | 
| 
      
 148 
     | 
    
         
            +
                        handler =  @wait_for_event.values.first
         
     | 
| 
      
 149 
     | 
    
         
            +
                        if handler
         
     | 
| 
      
 150 
     | 
    
         
            +
                          queue, proc = handler
         
     | 
| 
      
 151 
     | 
    
         
            +
                          queue.push(nil)
         
     | 
| 
      
 152 
     | 
    
         
            +
                        end
         
     | 
| 
      
 153 
     | 
    
         
            +
                      end
         
     | 
| 
      
 154 
     | 
    
         
            +
                    end
         
     | 
| 
      
 155 
     | 
    
         
            +
                    unless msg.nil?
         
     | 
| 
      
 156 
     | 
    
         
            +
                      case type
         
     | 
| 
      
 157 
     | 
    
         
            +
                      when "value", "error"
         
     | 
| 
      
 158 
     | 
    
         
            +
                        puts msg.body
         
     | 
| 
      
 159 
     | 
    
         
            +
                      when "abort"
         
     | 
| 
      
 160 
     | 
    
         
            +
                        puts "aborted"
         
     | 
| 
      
 161 
     | 
    
         
            +
                      when "connect"
         
     | 
| 
      
 162 
     | 
    
         
            +
                        puts
         
     | 
| 
      
 163 
     | 
    
         
            +
                      end
         
     | 
| 
      
 164 
     | 
    
         
            +
                      if Process.methods.include?("kill")
         
     | 
| 
      
 165 
     | 
    
         
            +
                        Process.kill "INT", $$  # interrupt readline
         
     | 
| 
      
 166 
     | 
    
         
            +
                      else
         
     | 
| 
      
 167 
     | 
    
         
            +
                        # JRuby
         
     | 
| 
      
 168 
     | 
    
         
            +
                        main_thread.raise Interrupt
         
     | 
| 
      
 169 
     | 
    
         
            +
                      end
         
     | 
| 
      
 170 
     | 
    
         
            +
                    end
         
     | 
| 
      
 171 
     | 
    
         
            +
                  end
         
     | 
| 
      
 172 
     | 
    
         
            +
                  
         
     | 
| 
      
 173 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 174 
     | 
    
         
            +
                    loop do
         
     | 
| 
      
 175 
     | 
    
         
            +
                      break unless line = console.readline
         
     | 
| 
      
 176 
     | 
    
         
            +
                      if line.chomp == ''
         
     | 
| 
      
 177 
     | 
    
         
            +
                        send_script(nil, "ping") {}
         
     | 
| 
      
 178 
     | 
    
         
            +
                      else
         
     | 
| 
      
 179 
     | 
    
         
            +
                        send_script(line, "eval") do |msg|
         
     | 
| 
      
 180 
     | 
    
         
            +
                          puts msg.body
         
     | 
| 
      
 181 
     | 
    
         
            +
                        end
         
     | 
| 
      
 182 
     | 
    
         
            +
                      end
         
     | 
| 
      
 183 
     | 
    
         
            +
                    end
         
     | 
| 
      
 184 
     | 
    
         
            +
                    $stderr.puts "Exiting shell..."
         
     | 
| 
      
 185 
     | 
    
         
            +
                  rescue Interrupt
         
     | 
| 
      
 186 
     | 
    
         
            +
                    # $stderr.puts "int"
         
     | 
| 
      
 187 
     | 
    
         
            +
                    retry
         
     | 
| 
      
 188 
     | 
    
         
            +
                  rescue SystemExit
         
     | 
| 
      
 189 
     | 
    
         
            +
                    return
         
     | 
| 
      
 190 
     | 
    
         
            +
                  rescue Exception => e
         
     | 
| 
      
 191 
     | 
    
         
            +
                    $stderr.puts "#{e.inspect} at:\n#{e.backtrace.join("\n")}"
         
     | 
| 
      
 192 
     | 
    
         
            +
                  ensure
         
     | 
| 
      
 193 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 194 
     | 
    
         
            +
                      console.close
         
     | 
| 
      
 195 
     | 
    
         
            +
                    rescue Exception => e
         
     | 
| 
      
 196 
     | 
    
         
            +
                      $stderr.puts "failed to close console: #{e.inspect}"
         
     | 
| 
      
 197 
     | 
    
         
            +
                    end
         
     | 
| 
      
 198 
     | 
    
         
            +
                  end
         
     | 
| 
      
 199 
     | 
    
         
            +
                end
         
     | 
| 
      
 200 
     | 
    
         
            +
              end
         
     | 
| 
      
 201 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,36 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module JSCommander
         
     | 
| 
      
 2 
     | 
    
         
            +
              # This broker proxy should be instantiated in each process.
         
     | 
| 
      
 3 
     | 
    
         
            +
              class StompProxy
         
     | 
| 
      
 4 
     | 
    
         
            +
                def initialize(url = nil)
         
     | 
| 
      
 5 
     | 
    
         
            +
                  require "stomp"
         
     | 
| 
      
 6 
     | 
    
         
            +
                  
         
     | 
| 
      
 7 
     | 
    
         
            +
                  url = "stomp://localhost:61613/" if url.nil?
         
     | 
| 
      
 8 
     | 
    
         
            +
                  @stomp = Stomp::Client.new(url)
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                def subscribe(name, &proc)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @stomp.subscribe("/topic/#{name}") do |msg|
         
     | 
| 
      
 13 
     | 
    
         
            +
                    attributes = {}
         
     | 
| 
      
 14 
     | 
    
         
            +
                    msg.headers.each do |key, value|
         
     | 
| 
      
 15 
     | 
    
         
            +
                      if key =~ /^jscmd\.(.*)/
         
     | 
| 
      
 16 
     | 
    
         
            +
                        attributes[$1] = value
         
     | 
| 
      
 17 
     | 
    
         
            +
                      end
         
     | 
| 
      
 18 
     | 
    
         
            +
                    end
         
     | 
| 
      
 19 
     | 
    
         
            +
                    proc.call(Message.new(msg.body, attributes))
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
                  proc
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                def unsubscribe(name, subscriber)
         
     | 
| 
      
 25 
     | 
    
         
            +
                  @stomp.unsubscribe("/topic/#{name}")
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                def send(name, msg)
         
     | 
| 
      
 29 
     | 
    
         
            +
                  headers = {}
         
     | 
| 
      
 30 
     | 
    
         
            +
                  msg.attributes.each do |key, value|
         
     | 
| 
      
 31 
     | 
    
         
            +
                    headers["jscmd." + key] = value
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
                  @stomp.send("/topic/#{name}", msg.body || "", headers)
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
              end
         
     | 
| 
      
 36 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,43 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "cgi"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module JSCommander
         
     | 
| 
      
 4 
     | 
    
         
            +
              class URLForwarder < WEBrick::HTTPServer
         
     | 
| 
      
 5 
     | 
    
         
            +
                def initialize(broker, args)
         
     | 
| 
      
 6 
     | 
    
         
            +
                  @broker = broker
         
     | 
| 
      
 7 
     | 
    
         
            +
                  super(args)
         
     | 
| 
      
 8 
     | 
    
         
            +
                  mount_proc("/send/", method(:forward_url).to_proc)
         
     | 
| 
      
 9 
     | 
    
         
            +
                  mount_proc("/", method(:show_bookmarklet).to_proc)
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                def show_bookmarklet(req, res)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  res.content_type = "text/html"
         
     | 
| 
      
 14 
     | 
    
         
            +
                  res.body = <<EOS
         
     | 
| 
      
 15 
     | 
    
         
            +
            <html>
         
     | 
| 
      
 16 
     | 
    
         
            +
            <head>
         
     | 
| 
      
 17 
     | 
    
         
            +
            <title>Bookmarklet for forwarding URL</title>
         
     | 
| 
      
 18 
     | 
    
         
            +
            <script type="text/javascript">
         
     | 
| 
      
 19 
     | 
    
         
            +
            function setBrowserName(name) {
         
     | 
| 
      
 20 
     | 
    
         
            +
              var link = document.getElementById("link");
         
     | 
| 
      
 21 
     | 
    
         
            +
              link.removeChild(link.firstChild);
         
     | 
| 
      
 22 
     | 
    
         
            +
              link.appendChild(document.createTextNode("Open with " + name));
         
     | 
| 
      
 23 
     | 
    
         
            +
            }
         
     | 
| 
      
 24 
     | 
    
         
            +
            </script>
         
     | 
| 
      
 25 
     | 
    
         
            +
            </head>
         
     | 
| 
      
 26 
     | 
    
         
            +
            <body>
         
     | 
| 
      
 27 
     | 
    
         
            +
            <form onsubmit="return false">Enter the name of another browser: <input type="text" value="Wii" oninput="setBrowserName(this.value)"/></form>
         
     | 
| 
      
 28 
     | 
    
         
            +
            <p>Drag the following link to your bookmarks toolbar.</p>
         
     | 
| 
      
 29 
     | 
    
         
            +
            <p><a id="link" href="javascript:void(window.open('http://localhost:#{@config[:Port]}/send/'+escape(location.href)))">Open with Wii</a></p>
         
     | 
| 
      
 30 
     | 
    
         
            +
            </body>
         
     | 
| 
      
 31 
     | 
    
         
            +
            EOS
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
                
         
     | 
| 
      
 34 
     | 
    
         
            +
                def forward_url(req, res)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  uri = CGI.unescape(req.unparsed_uri.sub(%r{^/send/}, ""))
         
     | 
| 
      
 36 
     | 
    
         
            +
                  puts "opening " + uri
         
     | 
| 
      
 37 
     | 
    
         
            +
                  line = "(function() { var c = location.href; var l = '#{uri.gsub(/\\/, "\\\\").gsub("'", "\\'")}'; location.href = l; if (l.replace(/#.*$/,'') == c.replace(/#.*$/,'')) location.reload(); })()"
         
     | 
| 
      
 38 
     | 
    
         
            +
                  @broker.send("commands", Message.new(line, :type => "eval"))
         
     | 
| 
      
 39 
     | 
    
         
            +
                  res.content_type = "text/html"
         
     | 
| 
      
 40 
     | 
    
         
            +
                  res.body = '<html><head><script type="text/javascript">window.close()</script></head></html>'
         
     | 
| 
      
 41 
     | 
    
         
            +
                end   
         
     | 
| 
      
 42 
     | 
    
         
            +
              end
         
     | 
| 
      
 43 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/jscmd/version.rb
    CHANGED
    
    
    
        data/lib/jscmd.rb
    CHANGED
    
    | 
         @@ -1 +1,14 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            Dir[File.join(File.dirname(__FILE__), 'jscmd/**/*.rb')].sort.each { |lib| require lib }
         
     | 
| 
      
 1 
     | 
    
         
            +
            # Dir[File.join(File.dirname(__FILE__), 'jscmd/**/*.rb')].sort.each { |lib| require lib }
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # message
         
     | 
| 
      
 4 
     | 
    
         
            +
            require "jscmd/message"
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            # brokers
         
     | 
| 
      
 7 
     | 
    
         
            +
            require "jscmd/inprocessbroker"
         
     | 
| 
      
 8 
     | 
    
         
            +
            require "jscmd/pipebroker"
         
     | 
| 
      
 9 
     | 
    
         
            +
            require "jscmd/stompproxy"
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            # clients
         
     | 
| 
      
 12 
     | 
    
         
            +
            require "jscmd/proxyserver"
         
     | 
| 
      
 13 
     | 
    
         
            +
            require "jscmd/shell"
         
     | 
| 
      
 14 
     | 
    
         
            +
            require "jscmd/urlforwarder"
         
     | 
    
        data/test/test_helper.rb
    CHANGED