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
 
    
        data/History.txt
    CHANGED
    
    | 
         @@ -1,3 +1,11 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            = *SVN*
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            * Refactored everything
         
     | 
| 
      
 4 
     | 
    
         
            +
            * Now acts as Stomp client
         
     | 
| 
      
 5 
     | 
    
         
            +
            * Embedded Stomp Server
         
     | 
| 
      
 6 
     | 
    
         
            +
            * Now works in JRuby (partially, using threads) and mswin32 (using stompserver)
         
     | 
| 
      
 7 
     | 
    
         
            +
            * Added URLForwarder that adds a bookmarklet that sends the URL of the current page to another browser
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
       1 
9 
     | 
    
         
             
            = 0.0.2 2007-05-08
         
     | 
| 
       2 
10 
     | 
    
         | 
| 
       3 
11 
     | 
    
         
             
            * Fixed potential file descriptor leak
         
     | 
    
        data/Manifest.txt
    CHANGED
    
    | 
         @@ -6,11 +6,19 @@ README.txt 
     | 
|
| 
       6 
6 
     | 
    
         
             
            Rakefile
         
     | 
| 
       7 
7 
     | 
    
         
             
            bin/jscmd
         
     | 
| 
       8 
8 
     | 
    
         
             
            lib/jscmd.rb
         
     | 
| 
       9 
     | 
    
         
            -
            lib/jscmd/version.rb
         
     | 
| 
       10 
     | 
    
         
            -
            lib/jscmd/jscommander.rb
         
     | 
| 
       11 
9 
     | 
    
         
             
            lib/jscmd/asynchttpproxy.rb
         
     | 
| 
      
 10 
     | 
    
         
            +
            lib/jscmd/inprocessbroker.rb
         
     | 
| 
      
 11 
     | 
    
         
            +
            lib/jscmd/message.rb
         
     | 
| 
      
 12 
     | 
    
         
            +
            lib/jscmd/pipebroker.rb
         
     | 
| 
      
 13 
     | 
    
         
            +
            lib/jscmd/proxyserver.rb
         
     | 
| 
      
 14 
     | 
    
         
            +
            lib/jscmd/shell.rb
         
     | 
| 
      
 15 
     | 
    
         
            +
            lib/jscmd/stompproxy.rb
         
     | 
| 
      
 16 
     | 
    
         
            +
            lib/jscmd/urlforwarder.rb
         
     | 
| 
      
 17 
     | 
    
         
            +
            lib/jscmd/version.rb
         
     | 
| 
       12 
18 
     | 
    
         
             
            lib/jscmd/agent.js
         
     | 
| 
       13 
19 
     | 
    
         
             
            scripts/txt2html
         
     | 
| 
       14 
20 
     | 
    
         
             
            setup.rb
         
     | 
| 
       15 
21 
     | 
    
         
             
            test/test_helper.rb
         
     | 
| 
       16 
     | 
    
         
            -
            test/ 
     | 
| 
      
 22 
     | 
    
         
            +
            test/test_proxyserver.rb
         
     | 
| 
      
 23 
     | 
    
         
            +
            test/test_shell.rb
         
     | 
| 
      
 24 
     | 
    
         
            +
            examples/get_title.pl
         
     | 
    
        data/Rakefile
    CHANGED
    
    | 
         @@ -49,7 +49,7 @@ hoe = Hoe.new(GEM_NAME, VERS) do |p| 
     | 
|
| 
       49 
49 
     | 
    
         | 
| 
       50 
50 
     | 
    
         
             
              # == Optional
         
     | 
| 
       51 
51 
     | 
    
         
             
              p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
         
     | 
| 
       52 
     | 
    
         
            -
               
     | 
| 
      
 52 
     | 
    
         
            +
              p.extra_deps = [['stomp', '>= 1.0.5'], ['stompserver', '>= 0.9.7']]     # An array of rubygem dependencies [name, version], e.g. [ ['active_support', '>= 1.3.1'] ]
         
     | 
| 
       53 
53 
     | 
    
         
             
              #p.spec_extras = {}    # A hash of extra values to set in the gemspec.
         
     | 
| 
       54 
54 
     | 
    
         
             
            end
         
     | 
| 
       55 
55 
     | 
    
         | 
    
        data/bin/jscmd
    CHANGED
    
    | 
         @@ -1,4 +1,4 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
             
     | 
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            begin
         
     | 
| 
       4 
4 
     | 
    
         
             
              require 'rubygems'
         
     | 
| 
         @@ -13,32 +13,337 @@ end 
     | 
|
| 
       13 
13 
     | 
    
         
             
            require 'jscmd'
         
     | 
| 
       14 
14 
     | 
    
         
             
            require 'optparse'
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
               
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
      
 16 
     | 
    
         
            +
            module JSCommander
         
     | 
| 
      
 17 
     | 
    
         
            +
              class CommandLine
         
     | 
| 
      
 18 
     | 
    
         
            +
                OPTIONS = {
         
     | 
| 
      
 19 
     | 
    
         
            +
                  :port => 9000,
         
     | 
| 
      
 20 
     | 
    
         
            +
                  :bind => "0.0.0.0",
         
     | 
| 
      
 21 
     | 
    
         
            +
                  :uport => 9001,
         
     | 
| 
      
 22 
     | 
    
         
            +
                  :ubind => "localhost",
         
     | 
| 
      
 23 
     | 
    
         
            +
                  :sport => 61613,
         
     | 
| 
      
 24 
     | 
    
         
            +
                  :sbind => "localhost",
         
     | 
| 
      
 25 
     | 
    
         
            +
                  :sjournal => ".stompserver",
         
     | 
| 
      
 26 
     | 
    
         
            +
                  :connect_to => "stomp://localhost:61613/",
         
     | 
| 
      
 27 
     | 
    
         
            +
                }
         
     | 
| 
      
 28 
     | 
    
         
            +
                MANDATORY_OPTIONS = %w()
         
     | 
| 
      
 29 
     | 
    
         
            +
                
         
     | 
| 
      
 30 
     | 
    
         
            +
                def initialize
         
     | 
| 
      
 31 
     | 
    
         
            +
                  
         
     | 
| 
      
 32 
     | 
    
         
            +
                  parser = OptionParser.new do |opts|
         
     | 
| 
      
 33 
     | 
    
         
            +
                    opts.banner = <<BANNER
         
     | 
| 
       23 
34 
     | 
    
         
             
            JS Commander: Remote JavaScript Console
         
     | 
| 
       24 
35 
     | 
    
         | 
| 
       25 
36 
     | 
    
         
             
            Usage: #{File.basename($0)} [options]
         
     | 
| 
       26 
37 
     | 
    
         | 
| 
      
 38 
     | 
    
         
            +
            If no options were specified, jscmd starts up Shell and Proxy Server with internal broker.
         
     | 
| 
       27 
39 
     | 
    
         
             
            Options are:
         
     | 
| 
       28 
40 
     | 
    
         
             
            BANNER
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
      
 41 
     | 
    
         
            +
                    opts.separator ""
         
     | 
| 
      
 42 
     | 
    
         
            +
                    opts.on("-c", "--console", 
         
     | 
| 
      
 43 
     | 
    
         
            +
                            "Startup console") { |OPTIONS[:console]| }
         
     | 
| 
      
 44 
     | 
    
         
            +
                    opts.on("-x", "--proxy", 
         
     | 
| 
      
 45 
     | 
    
         
            +
                            "Startup proxy server") { |OPTIONS[:proxy]| }
         
     | 
| 
      
 46 
     | 
    
         
            +
                    opts.on("-p", "--port=PORT", Integer,
         
     | 
| 
      
 47 
     | 
    
         
            +
                            "Bind proxy server on specified TCP port. (default: 9000)") { |OPTIONS[:port]| }
         
     | 
| 
      
 48 
     | 
    
         
            +
                    opts.on("-b", "--bind=ADDRESS", String,
         
     | 
| 
      
 49 
     | 
    
         
            +
                            "Bind proxy server on specified IP address. (default: 0.0.0.0)") { |OPTIONS[:bind]| }
         
     | 
| 
      
 50 
     | 
    
         
            +
                    opts.on("-u", "--url-forwarder", 
         
     | 
| 
      
 51 
     | 
    
         
            +
                            "Startup URL forwarder") { |OPTIONS[:url_forwarder]| }
         
     | 
| 
      
 52 
     | 
    
         
            +
                    opts.on("--uport=PORT", Integer,
         
     | 
| 
      
 53 
     | 
    
         
            +
                            "Bind URL forwarder on specified TCP port. (default: 9001)") { |OPTIONS[:uport]| }
         
     | 
| 
      
 54 
     | 
    
         
            +
                    opts.on("--ubind=ADDRESS", String,
         
     | 
| 
      
 55 
     | 
    
         
            +
                            "Bind URL forwarder on specified IP address. (default: localhost)") { |OPTIONS[:ubind]| }
         
     | 
| 
      
 56 
     | 
    
         
            +
                    opts.on("-S", "--server",
         
     | 
| 
      
 57 
     | 
    
         
            +
                            "Startup embedded Stomp server") { |v| OPTIONS[:server] = v || true }
         
     | 
| 
      
 58 
     | 
    
         
            +
                    opts.on("--sport=PORT", Integer,
         
     | 
| 
      
 59 
     | 
    
         
            +
                            "Bind Stomp server on specified TCP port. (default: 61613)") { |OPTIONS[:sport]| }
         
     | 
| 
      
 60 
     | 
    
         
            +
                    opts.on("--sbind=ADDRESS", String,
         
     | 
| 
      
 61 
     | 
    
         
            +
                            "Bind Stomp server on specified IP address. (default: localhost)") { |OPTIONS[:sbind]| }
         
     | 
| 
      
 62 
     | 
    
         
            +
                    opts.on("--sjournal=DIR", String,
         
     | 
| 
      
 63 
     | 
    
         
            +
                            "Specify journal directory of Stomp server. (default: ./.stompserver)") { |OPTIONS[:sjournal]| }
         
     | 
| 
      
 64 
     | 
    
         
            +
                    opts.on("-C", "--client", String,
         
     | 
| 
      
 65 
     | 
    
         
            +
                            "Acts as Stomp client.") {|OPTIONS[:client]|}
         
     | 
| 
      
 66 
     | 
    
         
            +
                    opts.on("--connect-to=URL", String,
         
     | 
| 
      
 67 
     | 
    
         
            +
                            "Specify URL of Stomp server in stomp://[user:pass@]host:port/ format.",
         
     | 
| 
      
 68 
     | 
    
         
            +
                            "(default: stomp://localhost:61613/)") { |OPTIONS[:connect_to]| }
         
     | 
| 
      
 69 
     | 
    
         
            +
                    opts.on("--debug-proxy", 
         
     | 
| 
      
 70 
     | 
    
         
            +
                            "Enable debugging in proxy server.") { |OPTIONS[:debug_proxy]| }
         
     | 
| 
      
 71 
     | 
    
         
            +
                    opts.on("--debug-msg=[LOGFILE]", 
         
     | 
| 
      
 72 
     | 
    
         
            +
                            "Print messages that are being sent.") { |OPTIONS[:debug_msg]| }
         
     | 
| 
      
 73 
     | 
    
         
            +
                    opts.on("--never-fork", 
         
     | 
| 
      
 74 
     | 
    
         
            +
                            "Never fork - use threads only (experimental).") { |OPTIONS[:never_fork]| }
         
     | 
| 
      
 75 
     | 
    
         
            +
                    opts.on("-h", "--help",
         
     | 
| 
      
 76 
     | 
    
         
            +
                            "Show this help message.") { puts opts; exit }
         
     | 
| 
      
 77 
     | 
    
         
            +
                    opts.parse!(ARGV)
         
     | 
| 
      
 78 
     | 
    
         
            +
                    
         
     | 
| 
      
 79 
     | 
    
         
            +
                    if MANDATORY_OPTIONS && MANDATORY_OPTIONS.find { |option| OPTIONS[option.to_sym].nil? }
         
     | 
| 
      
 80 
     | 
    
         
            +
                      puts opts; exit
         
     | 
| 
      
 81 
     | 
    
         
            +
                    end
         
     | 
| 
      
 82 
     | 
    
         
            +
                  end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                  unless [:console, :proxy, :server, :url_forwarder].any?{|o| OPTIONS[o]}
         
     | 
| 
      
 85 
     | 
    
         
            +
                    # default is -xc if no processes were specified
         
     | 
| 
      
 86 
     | 
    
         
            +
                    OPTIONS[:console] = true
         
     | 
| 
      
 87 
     | 
    
         
            +
                    OPTIONS[:proxy] = true
         
     | 
| 
      
 88 
     | 
    
         
            +
                    if windows?
         
     | 
| 
      
 89 
     | 
    
         
            +
                      OPTIONS[:server] = true
         
     | 
| 
      
 90 
     | 
    
         
            +
                    end
         
     | 
| 
      
 91 
     | 
    
         
            +
                  end
         
     | 
| 
      
 92 
     | 
    
         
            +
            #      puts "options: #{encode_options.join(' ')}"
         
     | 
| 
      
 93 
     | 
    
         
            +
                  
         
     | 
| 
      
 94 
     | 
    
         
            +
                  @child_pid = nil
         
     | 
| 
      
 95 
     | 
    
         
            +
                  @threads = []
         
     | 
| 
      
 96 
     | 
    
         
            +
                  
         
     | 
| 
      
 97 
     | 
    
         
            +
                  use_stomp = OPTIONS[:server] || OPTIONS[:client]
         
     | 
| 
      
 98 
     | 
    
         
            +
                  unless never_fork?
         
     | 
| 
      
 99 
     | 
    
         
            +
                    use_stomp ||= !OPTIONS[:console] || !OPTIONS[:proxy] || OPTIONS[:url_forwarder]
         
     | 
| 
      
 100 
     | 
    
         
            +
                  end
         
     | 
| 
      
 101 
     | 
    
         
            +
                  
         
     | 
| 
      
 102 
     | 
    
         
            +
                  if use_stomp
         
     | 
| 
      
 103 
     | 
    
         
            +
                    # use stomp broker
         
     | 
| 
      
 104 
     | 
    
         
            +
                    startup_processes { StompProxy.new(OPTIONS[:connect_to]) }
         
     | 
| 
      
 105 
     | 
    
         
            +
                  else
         
     | 
| 
      
 106 
     | 
    
         
            +
                    # use internal broker
         
     | 
| 
      
 107 
     | 
    
         
            +
                    if !never_fork?
         
     | 
| 
      
 108 
     | 
    
         
            +
                      r1, w1 = IO.pipe
         
     | 
| 
      
 109 
     | 
    
         
            +
                      r2, w2 = IO.pipe
         
     | 
| 
      
 110 
     | 
    
         
            +
                      pid = $$
         
     | 
| 
      
 111 
     | 
    
         
            +
                      startup_processes do
         
     | 
| 
      
 112 
     | 
    
         
            +
                        if pid == $$
         
     | 
| 
      
 113 
     | 
    
         
            +
                          PipeBroker.new(r2, w1)
         
     | 
| 
      
 114 
     | 
    
         
            +
                        else
         
     | 
| 
      
 115 
     | 
    
         
            +
                          PipeBroker.new(r1, w2)
         
     | 
| 
      
 116 
     | 
    
         
            +
                        end
         
     | 
| 
      
 117 
     | 
    
         
            +
                      end
         
     | 
| 
      
 118 
     | 
    
         
            +
                    else
         
     | 
| 
      
 119 
     | 
    
         
            +
                      $stderr.puts "Starting up in multi-threaded mode"
         
     | 
| 
      
 120 
     | 
    
         
            +
                      # JRuby
         
     | 
| 
      
 121 
     | 
    
         
            +
                      broker = InProcessBroker.new
         
     | 
| 
      
 122 
     | 
    
         
            +
                      startup_processes { broker }
         
     | 
| 
      
 123 
     | 
    
         
            +
                    end
         
     | 
| 
      
 124 
     | 
    
         
            +
                  end
         
     | 
| 
      
 125 
     | 
    
         
            +
                end
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
                def startup_non_console_processes(&broker_factory)
         
     | 
| 
      
 128 
     | 
    
         
            +
                  if OPTIONS[:server]
         
     | 
| 
      
 129 
     | 
    
         
            +
                    t = StompServerLauncher.new
         
     | 
| 
      
 130 
     | 
    
         
            +
                    t.start
         
     | 
| 
      
 131 
     | 
    
         
            +
                    @threads << t
         
     | 
| 
      
 132 
     | 
    
         
            +
                  end
         
     | 
| 
      
 133 
     | 
    
         
            +
                  if OPTIONS[:proxy]
         
     | 
| 
      
 134 
     | 
    
         
            +
                    t = ProxyLauncher.new(broker_factory.call)
         
     | 
| 
      
 135 
     | 
    
         
            +
                    t.start
         
     | 
| 
      
 136 
     | 
    
         
            +
                    @threads << t
         
     | 
| 
      
 137 
     | 
    
         
            +
                  end
         
     | 
| 
      
 138 
     | 
    
         
            +
                  if OPTIONS[:url_forwarder]
         
     | 
| 
      
 139 
     | 
    
         
            +
                    t = URLForwarderLauncher.new(broker_factory.call)
         
     | 
| 
      
 140 
     | 
    
         
            +
                    t.start
         
     | 
| 
      
 141 
     | 
    
         
            +
                    @threads << t
         
     | 
| 
      
 142 
     | 
    
         
            +
                  end
         
     | 
| 
      
 143 
     | 
    
         
            +
                end
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
                def stop_threads
         
     | 
| 
      
 146 
     | 
    
         
            +
                  @threads.reverse.each do |t|
         
     | 
| 
      
 147 
     | 
    
         
            +
                    t.shutdown
         
     | 
| 
      
 148 
     | 
    
         
            +
                  end
         
     | 
| 
      
 149 
     | 
    
         
            +
                end
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
                def join_threads
         
     | 
| 
      
 152 
     | 
    
         
            +
                  @threads.reverse.each do |t|
         
     | 
| 
      
 153 
     | 
    
         
            +
                    t.thread.join
         
     | 
| 
      
 154 
     | 
    
         
            +
                  end
         
     | 
| 
      
 155 
     | 
    
         
            +
                end
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
      
 157 
     | 
    
         
            +
                def encode_options
         
     | 
| 
      
 158 
     | 
    
         
            +
                  options = []
         
     | 
| 
      
 159 
     | 
    
         
            +
                  OPTIONS.each do |key, value|
         
     | 
| 
      
 160 
     | 
    
         
            +
                    option = "--#{key.to_s.gsub(/_/, "-")}"
         
     | 
| 
      
 161 
     | 
    
         
            +
                    case value
         
     | 
| 
      
 162 
     | 
    
         
            +
                    when true
         
     | 
| 
      
 163 
     | 
    
         
            +
                      options << option
         
     | 
| 
      
 164 
     | 
    
         
            +
                    when String, Integer
         
     | 
| 
      
 165 
     | 
    
         
            +
                      options << "#{option}=#{value}"
         
     | 
| 
      
 166 
     | 
    
         
            +
                    end
         
     | 
| 
      
 167 
     | 
    
         
            +
                  end
         
     | 
| 
      
 168 
     | 
    
         
            +
                  options
         
     | 
| 
      
 169 
     | 
    
         
            +
                end
         
     | 
| 
      
 170 
     | 
    
         
            +
             
     | 
| 
      
 171 
     | 
    
         
            +
                def startup_processes(&broker_factory)
         
     | 
| 
      
 172 
     | 
    
         
            +
                  if OPTIONS[:debug_msg]
         
     | 
| 
      
 173 
     | 
    
         
            +
                    case OPTIONS[:debug_msg]
         
     | 
| 
      
 174 
     | 
    
         
            +
                    when String
         
     | 
| 
      
 175 
     | 
    
         
            +
                      $debug_msg_file = open(OPTIONS[:debug_msg], "a")
         
     | 
| 
      
 176 
     | 
    
         
            +
                    else
         
     | 
| 
      
 177 
     | 
    
         
            +
                      $debug_msg_file = $stderr
         
     | 
| 
      
 178 
     | 
    
         
            +
                    end
         
     | 
| 
      
 179 
     | 
    
         
            +
                    original_factory = broker_factory
         
     | 
| 
      
 180 
     | 
    
         
            +
                    broker_factory = proc do
         
     | 
| 
      
 181 
     | 
    
         
            +
                      broker = original_factory.call
         
     | 
| 
      
 182 
     | 
    
         
            +
                      def broker.send(name, msg)
         
     | 
| 
      
 183 
     | 
    
         
            +
                        $debug_msg_file.puts "send #{name}, #{msg.inspect}"
         
     | 
| 
      
 184 
     | 
    
         
            +
                        $debug_msg_file.flush
         
     | 
| 
      
 185 
     | 
    
         
            +
                        super
         
     | 
| 
      
 186 
     | 
    
         
            +
                      end
         
     | 
| 
      
 187 
     | 
    
         
            +
                      broker
         
     | 
| 
      
 188 
     | 
    
         
            +
                    end
         
     | 
| 
      
 189 
     | 
    
         
            +
                  end
         
     | 
| 
      
 190 
     | 
    
         
            +
                  if never_fork?
         
     | 
| 
      
 191 
     | 
    
         
            +
                    startup_non_console_processes(&broker_factory)
         
     | 
| 
      
 192 
     | 
    
         
            +
                    run_shell(broker_factory.call)
         
     | 
| 
      
 193 
     | 
    
         
            +
                    stop_threads
         
     | 
| 
      
 194 
     | 
    
         
            +
                    join_threads
         
     | 
| 
      
 195 
     | 
    
         
            +
                  else
         
     | 
| 
      
 196 
     | 
    
         
            +
                    if OPTIONS[:console]
         
     | 
| 
      
 197 
     | 
    
         
            +
                      if OPTIONS[:proxy] || OPTIONS[:server] || OPTIONS[:url_forwarder]
         
     | 
| 
      
 198 
     | 
    
         
            +
                        if windows?
         
     | 
| 
      
 199 
     | 
    
         
            +
                          require "win32/process"
         
     | 
| 
      
 200 
     | 
    
         
            +
                          options = encode_options.delete_if{|o|o=="--console"}.map{|o|%("#{o}")}.join(" ")
         
     | 
| 
      
 201 
     | 
    
         
            +
                          $stderr.puts "Lauching another process with options: #{options}"
         
     | 
| 
      
 202 
     | 
    
         
            +
                          @win32_process = Process.create(:app_name => "ruby \"#{$0}\" #{options}")
         
     | 
| 
      
 203 
     | 
    
         
            +
                        else
         
     | 
| 
      
 204 
     | 
    
         
            +
                          @child_pid = fork do
         
     | 
| 
      
 205 
     | 
    
         
            +
                            trap("TERM"){stop_threads}
         
     | 
| 
      
 206 
     | 
    
         
            +
                            trap("INT"){}
         
     | 
| 
      
 207 
     | 
    
         
            +
                            startup_non_console_processes(&broker_factory)
         
     | 
| 
      
 208 
     | 
    
         
            +
                            join_threads
         
     | 
| 
      
 209 
     | 
    
         
            +
                          end
         
     | 
| 
      
 210 
     | 
    
         
            +
                        end
         
     | 
| 
      
 211 
     | 
    
         
            +
                      end
         
     | 
| 
      
 212 
     | 
    
         
            +
                      wait_for_port(OPTIONS[:port]) if OPTIONS[:proxy]
         
     | 
| 
      
 213 
     | 
    
         
            +
                      wait_for_port(OPTIONS[:sport]) if OPTIONS[:server]
         
     | 
| 
      
 214 
     | 
    
         
            +
                      run_shell(broker_factory.call)
         
     | 
| 
      
 215 
     | 
    
         
            +
                    else
         
     | 
| 
      
 216 
     | 
    
         
            +
                      trap("TERM"){stop_threads}
         
     | 
| 
      
 217 
     | 
    
         
            +
                      trap("INT"){stop_threads}
         
     | 
| 
      
 218 
     | 
    
         
            +
                      startup_non_console_processes(&broker_factory)
         
     | 
| 
      
 219 
     | 
    
         
            +
                      join_threads
         
     | 
| 
      
 220 
     | 
    
         
            +
                    end
         
     | 
| 
      
 221 
     | 
    
         
            +
                  end
         
     | 
| 
      
 222 
     | 
    
         
            +
                end
         
     | 
| 
      
 223 
     | 
    
         
            +
             
     | 
| 
      
 224 
     | 
    
         
            +
                def wait_for_port(port)
         
     | 
| 
      
 225 
     | 
    
         
            +
                  30.times do
         
     | 
| 
      
 226 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 227 
     | 
    
         
            +
                      s = TCPSocket.open("localhost", port)
         
     | 
| 
      
 228 
     | 
    
         
            +
                      s.close
         
     | 
| 
      
 229 
     | 
    
         
            +
                      break
         
     | 
| 
      
 230 
     | 
    
         
            +
                    rescue
         
     | 
| 
      
 231 
     | 
    
         
            +
                    end
         
     | 
| 
      
 232 
     | 
    
         
            +
                    sleep 0.3
         
     | 
| 
      
 233 
     | 
    
         
            +
                  end
         
     | 
| 
      
 234 
     | 
    
         
            +
                end
         
     | 
| 
      
 235 
     | 
    
         
            +
                
         
     | 
| 
      
 236 
     | 
    
         
            +
                def windows?
         
     | 
| 
      
 237 
     | 
    
         
            +
                  RUBY_PLATFORM =~ /-mswin32$/
         
     | 
| 
      
 238 
     | 
    
         
            +
                end
         
     | 
| 
      
 239 
     | 
    
         
            +
                
         
     | 
| 
      
 240 
     | 
    
         
            +
                def never_fork?
         
     | 
| 
      
 241 
     | 
    
         
            +
                  "java" == RUBY_PLATFORM || OPTIONS[:never_fork]
         
     | 
| 
      
 242 
     | 
    
         
            +
                end
         
     | 
| 
      
 243 
     | 
    
         
            +
             
     | 
| 
      
 244 
     | 
    
         
            +
                def run_shell(broker)
         
     | 
| 
      
 245 
     | 
    
         
            +
                  shell = Shell.new(broker)
         
     | 
| 
      
 246 
     | 
    
         
            +
                  shell.run
         
     | 
| 
      
 247 
     | 
    
         
            +
                  if @child_pid
         
     | 
| 
      
 248 
     | 
    
         
            +
                    Process.kill "TERM", @child_pid
         
     | 
| 
      
 249 
     | 
    
         
            +
                    Process.waitall
         
     | 
| 
      
 250 
     | 
    
         
            +
                  elsif @win32_process
         
     | 
| 
      
 251 
     | 
    
         
            +
                    Process.kill 4, @win32_process.process_id
         
     | 
| 
      
 252 
     | 
    
         
            +
                    Process.waitpid(@win32_process.process_id)
         
     | 
| 
      
 253 
     | 
    
         
            +
                  end
         
     | 
| 
      
 254 
     | 
    
         
            +
                end
         
     | 
| 
      
 255 
     | 
    
         
            +
             
     | 
| 
      
 256 
     | 
    
         
            +
                class ThreadLauncher
         
     | 
| 
      
 257 
     | 
    
         
            +
                  attr_reader :thread
         
     | 
| 
      
 258 
     | 
    
         
            +
                  
         
     | 
| 
      
 259 
     | 
    
         
            +
                  def initialize(broker = nil)
         
     | 
| 
      
 260 
     | 
    
         
            +
                    @broker = broker
         
     | 
| 
      
 261 
     | 
    
         
            +
                  end
         
     | 
| 
      
 262 
     | 
    
         
            +
                  
         
     | 
| 
      
 263 
     | 
    
         
            +
                  def start
         
     | 
| 
      
 264 
     | 
    
         
            +
                    @thread = Thread.start do
         
     | 
| 
      
 265 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 266 
     | 
    
         
            +
                        run
         
     | 
| 
      
 267 
     | 
    
         
            +
                      rescue Exception
         
     | 
| 
      
 268 
     | 
    
         
            +
                        $stderr.puts $!
         
     | 
| 
      
 269 
     | 
    
         
            +
                        $stderr.puts $!.backtrace
         
     | 
| 
      
 270 
     | 
    
         
            +
                      end
         
     | 
| 
      
 271 
     | 
    
         
            +
                    end
         
     | 
| 
      
 272 
     | 
    
         
            +
                    wait if respond_to?(:wait)
         
     | 
| 
      
 273 
     | 
    
         
            +
                    @thread
         
     | 
| 
      
 274 
     | 
    
         
            +
                  end
         
     | 
| 
      
 275 
     | 
    
         
            +
             
     | 
| 
      
 276 
     | 
    
         
            +
                  def wait_for_port(port)
         
     | 
| 
      
 277 
     | 
    
         
            +
                    30.times do
         
     | 
| 
      
 278 
     | 
    
         
            +
                      break unless @thread.alive?
         
     | 
| 
      
 279 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 280 
     | 
    
         
            +
                        s = TCPSocket.open("localhost", port)
         
     | 
| 
      
 281 
     | 
    
         
            +
                        s.close
         
     | 
| 
      
 282 
     | 
    
         
            +
                        break
         
     | 
| 
      
 283 
     | 
    
         
            +
                      rescue
         
     | 
| 
      
 284 
     | 
    
         
            +
                      end
         
     | 
| 
      
 285 
     | 
    
         
            +
                      sleep 0.3
         
     | 
| 
      
 286 
     | 
    
         
            +
                    end
         
     | 
| 
      
 287 
     | 
    
         
            +
                  end
         
     | 
| 
      
 288 
     | 
    
         
            +
                end
         
     | 
| 
      
 289 
     | 
    
         
            +
             
     | 
| 
      
 290 
     | 
    
         
            +
                class ProxyLauncher < ThreadLauncher
         
     | 
| 
      
 291 
     | 
    
         
            +
                  def run
         
     | 
| 
      
 292 
     | 
    
         
            +
                    proxy_options = {:Port => OPTIONS[:port], :BindAddress => OPTIONS[:bind], :AccessLog => [], :ProxyVia => nil}
         
     | 
| 
      
 293 
     | 
    
         
            +
                    if OPTIONS[:debug_proxy]
         
     | 
| 
      
 294 
     | 
    
         
            +
                      proxy_options[:Logger] = WEBrick::Log.new(nil, WEBrick::BasicLog::DEBUG)
         
     | 
| 
      
 295 
     | 
    
         
            +
                    end
         
     | 
| 
      
 296 
     | 
    
         
            +
                    proxy = ProxyServer.new(@broker, proxy_options)
         
     | 
| 
      
 297 
     | 
    
         
            +
                    @proxy = proxy
         
     | 
| 
      
 298 
     | 
    
         
            +
                    proxy.start
         
     | 
| 
      
 299 
     | 
    
         
            +
                  end
         
     | 
| 
      
 300 
     | 
    
         
            +
             
     | 
| 
      
 301 
     | 
    
         
            +
                  def wait
         
     | 
| 
      
 302 
     | 
    
         
            +
                    wait_for_port(OPTIONS[:port])
         
     | 
| 
      
 303 
     | 
    
         
            +
                  end
         
     | 
| 
      
 304 
     | 
    
         
            +
             
     | 
| 
      
 305 
     | 
    
         
            +
                  def shutdown
         
     | 
| 
      
 306 
     | 
    
         
            +
                    @proxy.shutdown
         
     | 
| 
      
 307 
     | 
    
         
            +
                  end
         
     | 
| 
      
 308 
     | 
    
         
            +
                end
         
     | 
| 
      
 309 
     | 
    
         
            +
             
     | 
| 
      
 310 
     | 
    
         
            +
                class StompServerLauncher < ThreadLauncher
         
     | 
| 
      
 311 
     | 
    
         
            +
                  def start
         
     | 
| 
      
 312 
     | 
    
         
            +
                    require "stomp_server"
         
     | 
| 
      
 313 
     | 
    
         
            +
                    require "frame_journal"
         
     | 
| 
      
 314 
     | 
    
         
            +
                    super
         
     | 
| 
      
 315 
     | 
    
         
            +
                  end
         
     | 
| 
      
 316 
     | 
    
         
            +
             
     | 
| 
      
 317 
     | 
    
         
            +
                  def run
         
     | 
| 
      
 318 
     | 
    
         
            +
                    StompServer.setup(FrameJournal.new(OPTIONS[:sjournal]))
         
     | 
| 
      
 319 
     | 
    
         
            +
                    EventMachine.run do
         
     | 
| 
      
 320 
     | 
    
         
            +
                      puts "Stomp Server starting on port #{OPTIONS[:sport]}"
         
     | 
| 
      
 321 
     | 
    
         
            +
                      EventMachine.start_server OPTIONS[:sbind], OPTIONS[:sport], StompServer
         
     | 
| 
      
 322 
     | 
    
         
            +
                    end
         
     | 
| 
      
 323 
     | 
    
         
            +
                  end
         
     | 
| 
      
 324 
     | 
    
         
            +
             
     | 
| 
      
 325 
     | 
    
         
            +
                  def wait
         
     | 
| 
      
 326 
     | 
    
         
            +
                    wait_for_port(OPTIONS[:sport])
         
     | 
| 
      
 327 
     | 
    
         
            +
                  end
         
     | 
| 
      
 328 
     | 
    
         
            +
             
     | 
| 
      
 329 
     | 
    
         
            +
                  def shutdown
         
     | 
| 
      
 330 
     | 
    
         
            +
                    EventMachine.stop
         
     | 
| 
      
 331 
     | 
    
         
            +
                  end
         
     | 
| 
      
 332 
     | 
    
         
            +
                end
         
     | 
| 
      
 333 
     | 
    
         
            +
             
     | 
| 
      
 334 
     | 
    
         
            +
                class URLForwarderLauncher < ThreadLauncher
         
     | 
| 
      
 335 
     | 
    
         
            +
                  def run
         
     | 
| 
      
 336 
     | 
    
         
            +
                    @server = URLForwarder.new(@broker,
         
     | 
| 
      
 337 
     | 
    
         
            +
                                               :Port => OPTIONS[:uport], 
         
     | 
| 
      
 338 
     | 
    
         
            +
                                               :BindAddress => OPTIONS[:ubind])
         
     | 
| 
      
 339 
     | 
    
         
            +
                    @server.start
         
     | 
| 
      
 340 
     | 
    
         
            +
                  end
         
     | 
| 
      
 341 
     | 
    
         
            +
             
     | 
| 
      
 342 
     | 
    
         
            +
                  def shutdown
         
     | 
| 
      
 343 
     | 
    
         
            +
                    @server.shutdown
         
     | 
| 
      
 344 
     | 
    
         
            +
                  end
         
     | 
| 
      
 345 
     | 
    
         
            +
                end
         
     | 
| 
       39 
346 
     | 
    
         
             
              end
         
     | 
| 
       40 
347 
     | 
    
         
             
            end
         
     | 
| 
       41 
348 
     | 
    
         | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
            server = JSCommander::Broker.new(:Port => OPTIONS[:port], :AccessLog => [], :ProxyVia => nil)
         
     | 
| 
       44 
     | 
    
         
            -
            server.start
         
     | 
| 
      
 349 
     | 
    
         
            +
            JSCommander::CommandLine.new
         
     | 
| 
         @@ -0,0 +1,22 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env perl
         
     | 
| 
      
 2 
     | 
    
         
            +
            # An example script that prints title of the current page
         
     | 
| 
      
 3 
     | 
    
         
            +
            use strict;
         
     | 
| 
      
 4 
     | 
    
         
            +
            use warnings;
         
     | 
| 
      
 5 
     | 
    
         
            +
            use Net::Stomp;
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            my $stomp = Net::Stomp->new({hostname => 'localhost', port => '61613'});
         
     | 
| 
      
 8 
     | 
    
         
            +
            $stomp->connect({login => '', passcode => ''});
         
     | 
| 
      
 9 
     | 
    
         
            +
            $stomp->subscribe({destination => "/topic/events"});
         
     | 
| 
      
 10 
     | 
    
         
            +
            my $id = rand();
         
     | 
| 
      
 11 
     | 
    
         
            +
            $stomp->send({destination => "/topic/commands", 
         
     | 
| 
      
 12 
     | 
    
         
            +
            	      "jscmd.type" => "eval", 
         
     | 
| 
      
 13 
     | 
    
         
            +
            	      "jscmd.id" => $id, 
         
     | 
| 
      
 14 
     | 
    
         
            +
            	      body => "document.title"});
         
     | 
| 
      
 15 
     | 
    
         
            +
            for (;;) {
         
     | 
| 
      
 16 
     | 
    
         
            +
                my $frame = $stomp->receive_frame;
         
     | 
| 
      
 17 
     | 
    
         
            +
                if ($id eq $frame->headers->{"jscmd.in-reply-to"}) {
         
     | 
| 
      
 18 
     | 
    
         
            +
            	print $frame->body . "\n";
         
     | 
| 
      
 19 
     | 
    
         
            +
            	last;
         
     | 
| 
      
 20 
     | 
    
         
            +
                }
         
     | 
| 
      
 21 
     | 
    
         
            +
            } 
         
     | 
| 
      
 22 
     | 
    
         
            +
            $stomp->disconnect;
         
     | 
    
        data/lib/jscmd/agent.js
    CHANGED
    
    | 
         @@ -54,36 +54,45 @@ 
     | 
|
| 
       54 
54 
     | 
    
         
             
                },
         
     | 
| 
       55 
55 
     | 
    
         | 
| 
       56 
56 
     | 
    
         
             
                poll: function() {
         
     | 
| 
       57 
     | 
    
         
            -
                    var content = this.queue.length > 0 ? this.queue.shift() : "";
         
     | 
| 
      
 57 
     | 
    
         
            +
                    var content = this.queue.length > 0 ? this.queue.shift() : {type: "connect", body: ""};
         
     | 
| 
       58 
58 
     | 
    
         
             
                    var xhr = this.createXHR();
         
     | 
| 
       59 
59 
     | 
    
         
             
                    xhr.open("POST", "/_remote_js_proxy/poll", true);
         
     | 
| 
       60 
60 
     | 
    
         
             
                    xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
         
     | 
| 
      
 61 
     | 
    
         
            +
                    xhr.setRequestHeader("X-JSCmd-Agent-Id", this.agentId);
         
     | 
| 
      
 62 
     | 
    
         
            +
                    if (content.inReplyTo) {
         
     | 
| 
      
 63 
     | 
    
         
            +
                        xhr.setRequestHeader("X-JSCmd-In-Reply-To", content.inReplyTo);
         
     | 
| 
      
 64 
     | 
    
         
            +
                    }
         
     | 
| 
       61 
65 
     | 
    
         
             
                    var self = this;
         
     | 
| 
       62 
66 
     | 
    
         
             
                    xhr.onreadystatechange = function() {
         
     | 
| 
       63 
67 
     | 
    
         
             
                        if (xhr.readyState == 4) {
         
     | 
| 
       64 
68 
     | 
    
         
             
                            delete self.currentXHR;
         
     | 
| 
       65 
69 
     | 
    
         
             
                            try {
         
     | 
| 
       66 
70 
     | 
    
         
             
                                if (xhr.status == 200) {
         
     | 
| 
       67 
     | 
    
         
            -
                                    var  
     | 
| 
       68 
     | 
    
         
            -
                                     
     | 
| 
      
 71 
     | 
    
         
            +
                                    var commandId = xhr.getResponseHeader("X-JSCmd-Command-Id");
         
     | 
| 
      
 72 
     | 
    
         
            +
                                    var requestType = xhr.getResponseHeader("X-JSCmd-Type");
         
     | 
| 
      
 73 
     | 
    
         
            +
                                    var script = xhr.responseText;
         
     | 
| 
      
 74 
     | 
    
         
            +
                                    if (requestType) {
         
     | 
| 
       69 
75 
     | 
    
         
             
                                        var value = null;
         
     | 
| 
      
 76 
     | 
    
         
            +
                                        var type = null;
         
     | 
| 
       70 
77 
     | 
    
         
             
                                        try {
         
     | 
| 
       71 
     | 
    
         
            -
                                             
     | 
| 
       72 
     | 
    
         
            -
                                            var script = text.substring(1, text.length);
         
     | 
| 
       73 
     | 
    
         
            -
                                            if (option == 'P') {
         
     | 
| 
      
 78 
     | 
    
         
            +
                                            if (requestType == 'properties') {
         
     | 
| 
       74 
79 
     | 
    
         
             
                                                // get properties for code completion
         
     | 
| 
       75 
80 
     | 
    
         
             
                                                var obj = self.evaluate.apply(window, [script, false]);
         
     | 
| 
       76 
     | 
    
         
            -
                                                value =  
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
      
 81 
     | 
    
         
            +
                                                value = self.getAllProperties(obj).join(",");
         
     | 
| 
      
 82 
     | 
    
         
            +
                                                type = "value";
         
     | 
| 
      
 83 
     | 
    
         
            +
                                            } else if (requestType == 'eval') {
         
     | 
| 
       78 
84 
     | 
    
         
             
                                                // just evaluate
         
     | 
| 
       79 
     | 
    
         
            -
                                                value =  
     | 
| 
      
 85 
     | 
    
         
            +
                                                value = self.evaluate.apply(window, [script, true]);
         
     | 
| 
      
 86 
     | 
    
         
            +
                                                type = "value";
         
     | 
| 
       80 
87 
     | 
    
         
             
                                            } else {
         
     | 
| 
       81 
     | 
    
         
            -
                                                value = " 
     | 
| 
      
 88 
     | 
    
         
            +
                                                value = "bad request: " + script;
         
     | 
| 
      
 89 
     | 
    
         
            +
                                                type = "error";
         
     | 
| 
       82 
90 
     | 
    
         
             
                                            }
         
     | 
| 
       83 
91 
     | 
    
         
             
                                        } catch (e) {
         
     | 
| 
       84 
     | 
    
         
            -
                                            value =  
     | 
| 
      
 92 
     | 
    
         
            +
                                            value = e.toString();
         
     | 
| 
      
 93 
     | 
    
         
            +
                                            type = "error";
         
     | 
| 
       85 
94 
     | 
    
         
             
                                        }
         
     | 
| 
       86 
     | 
    
         
            -
                                        self.queue.push(value);
         
     | 
| 
      
 95 
     | 
    
         
            +
                                        self.queue.push({inReplyTo: commandId, type: type, body: value});
         
     | 
| 
       87 
96 
     | 
    
         
             
                                    }
         
     | 
| 
       88 
97 
     | 
    
         
             
                                }
         
     | 
| 
       89 
98 
     | 
    
         
             
                            } catch (e) {
         
     | 
| 
         @@ -102,14 +111,25 @@ 
     | 
|
| 
       102 
111 
     | 
    
         
             
                    this.currentXHR = xhr;
         
     | 
| 
       103 
112 
     | 
    
         
             
                    if (this.queue.length > 0) {
         
     | 
| 
       104 
113 
     | 
    
         
             
                        // mark that there are more messages pending
         
     | 
| 
       105 
     | 
    
         
            -
                         
     | 
| 
      
 114 
     | 
    
         
            +
                        xhr.setRequestHeader("X-JSCmd-More", "true");
         
     | 
| 
      
 115 
     | 
    
         
            +
                    }
         
     | 
| 
      
 116 
     | 
    
         
            +
                    xhr.setRequestHeader("X-JSCmd-Type", content.type);
         
     | 
| 
      
 117 
     | 
    
         
            +
                    xhr.send(encodeURI(content.body));
         
     | 
| 
      
 118 
     | 
    
         
            +
                },
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
                generateAgentId: function() {
         
     | 
| 
      
 121 
     | 
    
         
            +
                    var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
         
     | 
| 
      
 122 
     | 
    
         
            +
                    var str = "";
         
     | 
| 
      
 123 
     | 
    
         
            +
                    for (var i = 0; i < 16; i++) {
         
     | 
| 
      
 124 
     | 
    
         
            +
                        str += chars.charAt(Math.floor(Math.random() * chars.length));
         
     | 
| 
       106 
125 
     | 
    
         
             
                    }
         
     | 
| 
       107 
     | 
    
         
            -
                     
     | 
| 
      
 126 
     | 
    
         
            +
                    this.agentId = str;
         
     | 
| 
       108 
127 
     | 
    
         
             
                },
         
     | 
| 
       109 
128 
     | 
    
         | 
| 
       110 
129 
     | 
    
         
             
                startPoll: function() {
         
     | 
| 
       111 
130 
     | 
    
         
             
                    this.startPoll = function() {}
         
     | 
| 
       112 
131 
     | 
    
         
             
                    if (window.top.parent != window) return;
         
     | 
| 
      
 132 
     | 
    
         
            +
                    this.generateAgentId();
         
     | 
| 
       113 
133 
     | 
    
         
             
                    this.poll();
         
     | 
| 
       114 
134 
     | 
    
         
             
                },
         
     | 
| 
       115 
135 
     | 
    
         | 
| 
         @@ -225,10 +245,11 @@ 
     | 
|
| 
       225 
245 
     | 
    
         
             
                    this.attachEvent("pageshow", function() { self.startPoll() });
         
     | 
| 
       226 
246 
     | 
    
         | 
| 
       227 
247 
     | 
    
         
             
                    window.onerror = function(message, file, line) {
         
     | 
| 
       228 
     | 
    
         
            -
                        self.pushValue(" 
     | 
| 
       229 
     | 
    
         
            -
             
     | 
| 
       230 
     | 
    
         
            -
             
     | 
| 
       231 
     | 
    
         
            -
             
     | 
| 
      
 248 
     | 
    
         
            +
                        self.pushValue({type: "error",
         
     | 
| 
      
 249 
     | 
    
         
            +
                                        body:
         
     | 
| 
      
 250 
     | 
    
         
            +
                                        "Message: " + message + "\n" +
         
     | 
| 
      
 251 
     | 
    
         
            +
                                        "File: " + file + "\n" +
         
     | 
| 
      
 252 
     | 
    
         
            +
                                        "Line: " + line + "\n"});
         
     | 
| 
       232 
253 
     | 
    
         
             
                    }
         
     | 
| 
       233 
254 
     | 
    
         
             
                    setTimeout(function() { self.startPoll() }, 3000);
         
     | 
| 
       234 
255 
     | 
    
         | 
| 
         @@ -243,7 +264,8 @@ 
     | 
|
| 
       243 
264 
     | 
    
         
             
                                    for (var i = 0; i < arguments.length; i++) {
         
     | 
| 
       244 
265 
     | 
    
         
             
                                        message.push(arguments[i]);
         
     | 
| 
       245 
266 
     | 
    
         
             
                                    }
         
     | 
| 
       246 
     | 
    
         
            -
                                    self.pushValue( 
     | 
| 
      
 267 
     | 
    
         
            +
                                    self.pushValue({type: "value",
         
     | 
| 
      
 268 
     | 
    
         
            +
                                                    body:"[" + level + "] " + message.join(", ")});
         
     | 
| 
       247 
269 
     | 
    
         
             
                                }
         
     | 
| 
       248 
270 
     | 
    
         
             
                            })();
         
     | 
| 
       249 
271 
     | 
    
         
             
                        }
         
     | 
    
        data/lib/jscmd/asynchttpproxy.rb
    CHANGED
    
    | 
         @@ -51,7 +51,8 @@ module WEBrick 
     | 
|
| 
       51 
51 
     | 
    
         | 
| 
       52 
52 
     | 
    
         
             
                  response = nil
         
     | 
| 
       53 
53 
     | 
    
         
             
                  q = Queue.new
         
     | 
| 
       54 
     | 
    
         
            -
                   
     | 
| 
      
 54 
     | 
    
         
            +
                  data_queue = Queue.new
         
     | 
| 
      
 55 
     | 
    
         
            +
                  # p_reader, p_writer = IO.pipe
         
     | 
| 
       55 
56 
     | 
    
         
             
                  thread = Thread.start do
         
     | 
| 
       56 
57 
     | 
    
         
             
                    begin
         
     | 
| 
       57 
58 
     | 
    
         
             
                      @logger.debug "downloading #{uri}"
         
     | 
| 
         @@ -87,10 +88,12 @@ module WEBrick 
     | 
|
| 
       87 
88 
     | 
    
         
             
                            if last_size / 500000 != size / 500000
         
     | 
| 
       88 
89 
     | 
    
         
             
                              @logger.debug "downloading #{uri}: size=#{size}"
         
     | 
| 
       89 
90 
     | 
    
         
             
                            end
         
     | 
| 
       90 
     | 
    
         
            -
                            p_writer.write str
         
     | 
| 
      
 91 
     | 
    
         
            +
                            # p_writer.write str
         
     | 
| 
      
 92 
     | 
    
         
            +
                            data_queue.push str
         
     | 
| 
       91 
93 
     | 
    
         
             
                          end
         
     | 
| 
       92 
94 
     | 
    
         
             
                          @logger.debug "finished downloading #{uri}: size=#{size}"
         
     | 
| 
       93 
     | 
    
         
            -
                          p_writer.close
         
     | 
| 
      
 95 
     | 
    
         
            +
                          # p_writer.close
         
     | 
| 
      
 96 
     | 
    
         
            +
                          data_queue.push nil
         
     | 
| 
       94 
97 
     | 
    
         
             
                        end
         
     | 
| 
       95 
98 
     | 
    
         
             
                      }
         
     | 
| 
       96 
99 
     | 
    
         
             
                    rescue Exception => err
         
     | 
| 
         @@ -115,7 +118,7 @@ module WEBrick 
     | 
|
| 
       115 
118 
     | 
    
         
             
                  choose_header(response, res)
         
     | 
| 
       116 
119 
     | 
    
         
             
                  set_cookie(response, res)
         
     | 
| 
       117 
120 
     | 
    
         
             
                  set_via(res)
         
     | 
| 
       118 
     | 
    
         
            -
                  res.body = p_reader
         
     | 
| 
      
 121 
     | 
    
         
            +
                  res.body = QueueInput.new(data_queue) # p_reader
         
     | 
| 
       119 
122 
     | 
    
         
             
                  def res.flush_body
         
     | 
| 
       120 
123 
     | 
    
         
             
                    if @body.is_a?(IO)
         
     | 
| 
       121 
124 
     | 
    
         
             
                      begin
         
     | 
| 
         @@ -135,6 +138,39 @@ module WEBrick 
     | 
|
| 
       135 
138 
     | 
    
         
             
                    handler.call(req, res)
         
     | 
| 
       136 
139 
     | 
    
         
             
                  end
         
     | 
| 
       137 
140 
     | 
    
         
             
                end
         
     | 
| 
      
 141 
     | 
    
         
            +
                
         
     | 
| 
      
 142 
     | 
    
         
            +
                class QueueInput < IO
         
     | 
| 
      
 143 
     | 
    
         
            +
                  def initialize(queue)
         
     | 
| 
      
 144 
     | 
    
         
            +
                    @queue = queue
         
     | 
| 
      
 145 
     | 
    
         
            +
                    @eof = false
         
     | 
| 
      
 146 
     | 
    
         
            +
                  end
         
     | 
| 
      
 147 
     | 
    
         
            +
                  
         
     | 
| 
      
 148 
     | 
    
         
            +
                  def close; end
         
     | 
| 
      
 149 
     | 
    
         
            +
                  
         
     | 
| 
      
 150 
     | 
    
         
            +
                  def eof?
         
     | 
| 
      
 151 
     | 
    
         
            +
                    @eof
         
     | 
| 
      
 152 
     | 
    
         
            +
                  end
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
                  def pop
         
     | 
| 
      
 155 
     | 
    
         
            +
                    buf = @queue.pop
         
     | 
| 
      
 156 
     | 
    
         
            +
                    @eof = true if buf.nil?
         
     | 
| 
      
 157 
     | 
    
         
            +
                    buf
         
     | 
| 
      
 158 
     | 
    
         
            +
                  end
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
      
 160 
     | 
    
         
            +
                  def read(len = nil)
         
     | 
| 
      
 161 
     | 
    
         
            +
                    return nil if eof?
         
     | 
| 
      
 162 
     | 
    
         
            +
                    if len
         
     | 
| 
      
 163 
     | 
    
         
            +
                      pop
         
     | 
| 
      
 164 
     | 
    
         
            +
                    else
         
     | 
| 
      
 165 
     | 
    
         
            +
                      data = ""
         
     | 
| 
      
 166 
     | 
    
         
            +
                      while buf = pop
         
     | 
| 
      
 167 
     | 
    
         
            +
                        data << buf
         
     | 
| 
      
 168 
     | 
    
         
            +
                      end
         
     | 
| 
      
 169 
     | 
    
         
            +
                      data
         
     | 
| 
      
 170 
     | 
    
         
            +
                    end
         
     | 
| 
      
 171 
     | 
    
         
            +
                  end
         
     | 
| 
      
 172 
     | 
    
         
            +
                end
         
     | 
| 
       138 
173 
     | 
    
         
             
              end
         
     | 
| 
      
 174 
     | 
    
         
            +
             
     | 
| 
       139 
175 
     | 
    
         
             
            end
         
     | 
| 
       140 
176 
     | 
    
         | 
| 
         @@ -0,0 +1,31 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module JSCommander
         
     | 
| 
      
 2 
     | 
    
         
            +
              class InProcessBroker
         
     | 
| 
      
 3 
     | 
    
         
            +
                def initialize
         
     | 
| 
      
 4 
     | 
    
         
            +
                  @subscribers = {}
         
     | 
| 
      
 5 
     | 
    
         
            +
                end
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                def subscribe(name, &block)
         
     | 
| 
      
 8 
     | 
    
         
            +
                  @subscribers[name] ||= []
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @subscribers[name] << block
         
     | 
| 
      
 10 
     | 
    
         
            +
                  block
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                def unsubscribe(name, subscriber)
         
     | 
| 
      
 14 
     | 
    
         
            +
                  @subscribers[name].delete(subscriber)
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                def send(name, msg)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  if @subscribers[name]
         
     | 
| 
      
 19 
     | 
    
         
            +
                    @subscribers[name].each do |sub|
         
     | 
| 
      
 20 
     | 
    
         
            +
                      Thread.start do
         
     | 
| 
      
 21 
     | 
    
         
            +
                        begin
         
     | 
| 
      
 22 
     | 
    
         
            +
                          sub.call(msg)
         
     | 
| 
      
 23 
     | 
    
         
            +
                        rescue Exception
         
     | 
| 
      
 24 
     | 
    
         
            +
                          $stderr.puts $!
         
     | 
| 
      
 25 
     | 
    
         
            +
                        end
         
     | 
| 
      
 26 
     | 
    
         
            +
                      end
         
     | 
| 
      
 27 
     | 
    
         
            +
                    end
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,42 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            =begin
         
     | 
| 
      
 2 
     | 
    
         
            +
            Messages sent between clients and broker
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            * Topic "events": proxy -> broker -> shell
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            Common attributes:
         
     | 
| 
      
 7 
     | 
    
         
            +
            type - Type of the message. (e.g. "connect")
         
     | 
| 
      
 8 
     | 
    
         
            +
            clients - List of clients that are connected. (e.g. "[www.google.com],[www.yahoo.com]")
         
     | 
| 
      
 9 
     | 
    
         
            +
            in-reply-to - id of the command that caused this message (optional; only used with "value", "error" and "pong" types)
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            Types:
         
     | 
| 
      
 12 
     | 
    
         
            +
            connect - Notify that the new client has connected. The body must be empty.
         
     | 
| 
      
 13 
     | 
    
         
            +
            abort - Notify that the client aborted. The body must be empty.
         
     | 
| 
      
 14 
     | 
    
         
            +
            pong - Reply to "ping" command. body must be empty.
         
     | 
| 
      
 15 
     | 
    
         
            +
            value - Send value with body.
         
     | 
| 
      
 16 
     | 
    
         
            +
            error - Send error message with body.
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            * Topic "commands": shell -> broker -> proxy
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            Common attributes:
         
     | 
| 
      
 21 
     | 
    
         
            +
            type - Type of the message. (e.g. "eval")
         
     | 
| 
      
 22 
     | 
    
         
            +
            id - unique value that identifies this command. (optional; only used with "eval" and "properties" types)
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            Types:
         
     | 
| 
      
 25 
     | 
    
         
            +
            ping - Request "update_clients". The body must be empty.
         
     | 
| 
      
 26 
     | 
    
         
            +
            eval - Evaluate body.
         
     | 
| 
      
 27 
     | 
    
         
            +
            properties - Evaluate body and get list of properties.
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            =end
         
     | 
| 
      
 30 
     | 
    
         
            +
            module JSCommander
         
     | 
| 
      
 31 
     | 
    
         
            +
              class Message
         
     | 
| 
      
 32 
     | 
    
         
            +
                attr_accessor :body, :attributes
         
     | 
| 
      
 33 
     | 
    
         
            +
                
         
     | 
| 
      
 34 
     | 
    
         
            +
                def initialize(body = nil, attributes = {})
         
     | 
| 
      
 35 
     | 
    
         
            +
                  @body = body
         
     | 
| 
      
 36 
     | 
    
         
            +
                  @attributes = {}
         
     | 
| 
      
 37 
     | 
    
         
            +
                  attributes.each do |key, value|
         
     | 
| 
      
 38 
     | 
    
         
            +
                    @attributes[key.to_s] = value
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
                end
         
     | 
| 
      
 41 
     | 
    
         
            +
              end
         
     | 
| 
      
 42 
     | 
    
         
            +
            end
         
     |