pry-remote-em 0.4.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/README.md ADDED
@@ -0,0 +1,258 @@
1
+ # What is it?
2
+
3
+ A way to start Pry remotely in EventMachine and to connect to it. This provides access to the state of the running program from anywhere.
4
+
5
+ It's based off of [Mon-Ouie's](https://github.com/Mon-Ouie) [pry-remote](https://github.com/Mon-Ouie/pry-remote) for DRb.
6
+
7
+ # Compatibility
8
+
9
+ MRI 1.9 or any other VM with support for Fibers is required.
10
+
11
+
12
+ # Installation
13
+
14
+ ```bash
15
+ gem install pry-remote-em
16
+ ```
17
+
18
+ # Usage
19
+
20
+ ```ruby
21
+ require 'pry-remote-em/server'
22
+
23
+ class Foo
24
+ def initialize(x, y)
25
+ binding.remote_pry_em
26
+ end
27
+ end
28
+
29
+ EM.run { Foo.new 10, 20 }
30
+ ```
31
+
32
+ Running it will print out a message telling you Pry is waiting for a
33
+ program to connect itself to it:
34
+
35
+ [pry-remote-em] listening for connections on pryem://localhost:6462/
36
+
37
+ You can then connect to the pry session using ``pry-remote-em``:
38
+
39
+ $ pry-remote-em
40
+ [pry-remote-em] client connected to pryem://127.0.0.1:6462/
41
+ [pry-remote-em] remote is PryRemoteEm 0.1.0
42
+ [1] pry(#<Foo>)> stat
43
+ Method Information:
44
+ --
45
+ Name: initialize
46
+ Owner: Foo
47
+ Visibility: private
48
+ Type: Bound
49
+ Arity: 2
50
+ Method Signature: initialize(x, y)
51
+ Source Location: (irb):2
52
+
53
+ [2] pry(#<Foo>)> self
54
+ => #<Foo:0x007fe66a426fa0>
55
+
56
+ [3] pry(#<Foo>)> ls
57
+ locals: _ _dir_ _ex_ _file_ _in_ _out_ _pry_ x y
58
+ [4] pry(#<Foo>)> x
59
+ => 10
60
+
61
+ [5] pry(#<Foo>)> x = 12
62
+ => 12
63
+
64
+ [6] pry(#<Foo>)> x
65
+ => 12
66
+
67
+ [7] pry(#<Foo>)> exit
68
+ [pry-remote-em] session terminated
69
+
70
+ $ pry-remote-em
71
+ [pry-remote-em] client connected to pryem://127.0.0.1:6462/
72
+ [pry-remote-em] remote is PryRemoteEm 0.1.0
73
+ [1] pry(#<Foo>)> x
74
+ => 12
75
+
76
+ [2] pry(#<Foo>)> exit
77
+ [pry-remote-em] session terminated
78
+
79
+ # Features
80
+
81
+ ## TLS Encryption
82
+
83
+ When creating a server pass the :tls => true option to enable TLS. If
84
+ you pass a Hash, e.g. ``:tls => {:private_key_file => '/tmp/server.key'}`` it will be used to configure the internal TLS handler.
85
+ See [EventMachine::Connection#start_tls](http://eventmachine.rubyforge.org/EventMachine/Connection.html#M000296) for the available options.
86
+
87
+ To start the command line client in TLS mode pass it a pryems URL instead of a pryem URL.
88
+
89
+ ```bash
90
+ $ bin/pry-remote-em pryems:///
91
+ [pry-remote-em] client connected to pryem://127.0.0.1:6462/
92
+ [pry-remote-em] remote is PryRemoteEm 0.2.0 pryems
93
+ [pry-remote-em] negotiating TLS
94
+ [pry-remote-em] TLS connection established
95
+ [1] pry(#<Hash>)>
96
+ ```
97
+
98
+ ## User Authentication
99
+
100
+ ### Server
101
+
102
+ If the service is started with the :auth option it will require all
103
+ clients to authenticate on connect. The :auth option can be a Hash, proc
104
+ or any object that responds to #call.
105
+
106
+ #### Auth with a Hash
107
+ ```ruby
108
+ auth_hash = {'caleb' => 'crane', 'john' => 'lowski'}
109
+ obj = {:encoding => __ENCODING__, :weather => :cloudy}
110
+ EM.run{
111
+ obj.remote_pry_em('localhost', :auto, :tls => true, :auth => auth_hash)
112
+ }
113
+ ```
114
+
115
+ #### Auth with a lambda
116
+ ```ruby
117
+ require ‘net/ldap’
118
+ ldap_anon = lambda do |user, pass|
119
+ ldap = Net::LDAP.new :host => “10.0.0.1”, :port => 389, :auth => {:method => :simple, :username => user, :password => pass}
120
+ ldap.bind
121
+ end
122
+ obj = {:encoding => __ENCODING__, :weather => :cloudy}
123
+ EM.run{
124
+ obj.remote_pry_em('localhost', :auto, :tls => true, :auth => ldap_anon)
125
+ }
126
+ ```
127
+
128
+ #### Auth with an object
129
+ ```ruby
130
+ class Authenticator
131
+ def initialize(db)
132
+ @db = db
133
+ end
134
+ def call(user, pass)
135
+ @db[user] && @db[user] == pass
136
+ end
137
+ end
138
+
139
+ obj = {:encoding => __ENCODING__, :weather => :cloudy}
140
+ EM.run{
141
+ obj.remote_pry_em('localhost', :auto, :tls => true, :auth => Authenticator.new(auth_hash))
142
+ }
143
+ ```
144
+
145
+
146
+ ### Client
147
+
148
+ The included command line client ``pry-remote-em`` can take a username
149
+ and/or password as part of the url argument. If either a username or
150
+ password is not supplied, but required by the server it will prompt for
151
+ them.
152
+
153
+ ```shell
154
+ $ pry-remote-em pryems://localhost:6464/
155
+ [pry-remote-em] client connected to pryem://127.0.0.1:6464/
156
+ [pry-remote-em] remote is PryRemoteEm 0.4.0 pryems
157
+ [pry-remote-em] negotiating TLS
158
+ [pry-remote-em] TLS connection established
159
+ user: caleb
160
+ caleb's password: *****
161
+ [1] pry(#<Hash>)>
162
+ ```
163
+
164
+
165
+ ```shell
166
+ $ pry-remote-em pryems://caleb@localhost:6464
167
+ [pry-remote-em] client connected to pryem://127.0.0.1:6464/
168
+ [pry-remote-em] remote is PryRemoteEm 0.4.0 pryems
169
+ [pry-remote-em] negotiating TLS
170
+ [pry-remote-em] TLS connection established
171
+ caleb's password: *****
172
+ [1] pry(#<Hash>)> exit
173
+ ```
174
+
175
+ ```shell
176
+ $ pry-remote-em pryems://caleb:crane@localhost:6464
177
+ [pry-remote-em] client connected to pryem://127.0.0.1:6464/
178
+ [pry-remote-em] remote is PryRemoteEm 0.4.0 pryems
179
+ [pry-remote-em] negotiating TLS
180
+ [pry-remote-em] TLS connection established
181
+ [1] pry(#<Hash>)> exit
182
+ ```
183
+
184
+
185
+ ## Tab Completion
186
+
187
+ Tab completion candidates will be retrieved from the server and
188
+ presented on the client side.
189
+
190
+ ```ruby
191
+ $ bin/pry-remote-em pryems:///
192
+ [pry-remote-em] client connected to pryem://127.0.0.1:6462/
193
+ [pry-remote-em] remote is PryRemoteEm 0.2.0 pryems
194
+ [1] pry(#<Hash>)> key (^TAB ^TAB)
195
+ key key? keys
196
+ [1] pry(#<Hash>)> keys
197
+ => [:encoding]
198
+ ```
199
+
200
+ ## Paging
201
+
202
+ The standard Pry pager is supported through the included client.
203
+
204
+ ```ruby
205
+ [1] pry(#<Hash>)> ENV
206
+ => {"COMMAND_MODE"=>"unix2003",
207
+ "DISPLAY"=>"/tmp/launch-0EGhJW/org.x:0",
208
+ "EDITOR"=>"mvim -f --nomru -c \"au VimLeave * !open -a Terminal\"",
209
+ "GEM_HOME"=>"/Users/caleb/.rvm/gems/ruby-1.9.2-p290",
210
+ "GEM_PATH"=>
211
+ "/Users/caleb/.rvm/gems/ruby-1.9.2-p290:/Users/caleb/.rvm/gems/ruby-1.9.2-p290@global",
212
+ "GREP_COLOR"=>"1;32",
213
+ "GREP_OPTIONS"=>"--color=auto",
214
+ "HOME"=>"/Users/caleb",
215
+ "IRBRC"=>"/Users/caleb/.rvm/rubies/ruby-1.9.2-p290/.irbrc",
216
+ "LC_CTYPE"=>"",
217
+ "LOGNAME"=>"caleb",
218
+ "LSCOLORS"=>"Gxfxcxdxbxegedabagacad",
219
+ :
220
+ ```
221
+
222
+ # Missing Features
223
+
224
+ - AutoDiscovery/Broker [ticket](https://github.com/simulacre/pry-remote-em/issues/11)
225
+ - HTTP Transport [ticket](https://github.com/simulacre/pry-remote-em/issues/12)
226
+ - Shell Commands [ticket](https://github.com/simulacre/pry-remote-em/issues/15)
227
+ - Vi mode editing - RbReadline doesn't support vi edit mode. I'm looking into contributing it. PryRemoteEm uses rb-readline because the STLIB version doesn't play nice with Fibers.
228
+ - Ssh key based authentication
229
+
230
+
231
+ # Issues
232
+
233
+ Please post any bug reports or feature requests on [Github](https://github.com/simulacre/pry-remote-em/issues)
234
+
235
+
236
+
237
+
238
+ # Copyright
239
+
240
+ Copyright (c) 2012 Caleb Crane
241
+
242
+ Permission is hereby granted, free of charge, to any person obtaining a
243
+ copy of this software and associated documentation files (the "Software"),
244
+ to deal in the Software without restriction, including without limitation
245
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
246
+ and/or sell copies of the Software, and to permit persons to whom the
247
+ Software is furnished to do so, subject to the following conditions:
248
+
249
+ The above copyright notice and this permission notice shall be included
250
+ in all copies or substantial portions of the Software.
251
+
252
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
253
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
254
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
255
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
256
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
257
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
258
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/bin/pry-remote-em ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'uri'
4
+ require 'highline'
5
+ require 'pry-remote-em/client'
6
+
7
+ uri = ARGV[0] || "pryem://localhost:#{PryRemoteEm::DEFPORT}"
8
+ uri = URI.parse(uri)
9
+ unless %w(pryem pryems).include?(uri.scheme)
10
+ abort "only pryem URIs are currently supported\n usage: pryem(s)://127.0.0.1:#{PryRemoteEm::DEFPORT}"
11
+ end
12
+
13
+ tried = 0
14
+ auth_proc = proc do
15
+ tried += 1
16
+ user = uri.user || ($stdin.tty? ? Readline.readline("user: ") : raise("username is require for authentication"))
17
+ pass = if !uri.password.nil? && tried <= 1
18
+ uri.password
19
+ elsif $stdin.tty?
20
+ HighLine.new.ask("#{user}'s password: ") { |q| q.echo = '*'}
21
+ else
22
+ raise "password is required to authenticate"
23
+ end
24
+ [user, pass]
25
+ end
26
+
27
+ EM.run do
28
+ PryRemoteEm::Client.start(uri.host, uri.port, :auth=>auth_proc, :tls=>uri.scheme=='pryems') { |e| EM.stop }
29
+ end
@@ -0,0 +1,25 @@
1
+ begin
2
+ require 'openssl'
3
+ rescue LoadError
4
+ warn "OpenSSL support is not available"
5
+ end
6
+ require 'pry-remote-em/version'
7
+ require 'pry-remote-em/json-proto'
8
+ require 'eventmachine'
9
+ require 'socket'
10
+ require 'json'
11
+ require "fiber"
12
+
13
+ module PryRemoteEm
14
+ DEFHOST = 'localhost'
15
+ DEFPORT = 6462
16
+ NEGOTIMER = 15
17
+ end
18
+
19
+
20
+ class Object
21
+ def remote_pry_em(host = PryRemoteEm::DEFHOST, port = PryRemoteEm::DEFPORT, opts = {:tls => false})
22
+ opts = {:target => self}.merge(opts)
23
+ PryRemoteEm::Server.run(opts[:target], host, port, opts)
24
+ end
25
+ end
@@ -0,0 +1,128 @@
1
+ require 'uri'
2
+ require 'pry-remote-em'
3
+ require 'pry/helpers/base_helpers'
4
+ #require "readline" # doesn't work with Fiber.yield
5
+ # - /Users/caleb/src/pry-remote-em/lib/pry-remote-em/client.rb:45:in `yield': fiber called across stack rewinding barrier (FiberError)
6
+ require "rb-readline" # doesn't provide vi-mode support :(
7
+ # https://github.com/luislavena/rb-readline/issues/21
8
+ # https://github.com/simulacre/rb-readline/commit/0376eb4e9526b3dc1a6512716322efcef409628d
9
+
10
+ module PryRemoteEm
11
+ module Client
12
+ include EM::Deferrable
13
+ include JsonProto
14
+ include Pry::Helpers::BaseHelpers
15
+
16
+ class << self
17
+ def start(host = PryRemoteEm::DEFHOST, port = PryRemoteEM::DEFPORT, opts = {:tls => false})
18
+ EM.connect(host || PryRemoteEm::DEFHOST, port || PryRemoteEm::DEFPORT, PryRemoteEm::Client, opts) do |c|
19
+ c.callback { yield if block_given? }
20
+ c.errback do |e|
21
+ puts "[pry-remote-em] connection failed\n#{e}"
22
+ yield(e) if block_given?
23
+ end
24
+ end
25
+ end
26
+ end # class << self
27
+
28
+ def initialize(opts = {})
29
+ @opts = opts
30
+ if (a = opts[:auth])
31
+ if a.respond_to?(:call)
32
+ @auth = a
33
+ else
34
+ @auth = lambda { a }
35
+ end
36
+ end
37
+ end
38
+
39
+ def post_init
40
+ return fail("connection was not established") unless get_peername
41
+ port, ip = Socket.unpack_sockaddr_in(get_peername)
42
+ Kernel.puts "[pry-remote-em] client connected to pryem://#{ip}:#{port}/"
43
+ @nego_timer = EM::Timer.new(PryRemoteEm::NEGOTIMER) do
44
+ fail("[pry-remote-em] server didn't finish negotiation within #{PryRemoteEm::NEGOTIMER} seconds; terminating")
45
+ end
46
+ Readline.completion_proc = method(:auto_complete)
47
+ end
48
+
49
+ def auto_complete(word)
50
+ @waiting = Fiber.current
51
+ send_data({:c => word})
52
+ return Fiber.yield
53
+ end
54
+
55
+ def receive_json(j)
56
+ if j['p'] # prompt
57
+ if @negotiated && !@unbound
58
+ Fiber.new { send_data(Readline.readline(j['p'], true)) }.resume
59
+ end
60
+
61
+ elsif j['d'] # printable data
62
+ stagger_output j['d'], $stdout # Pry::Helpers::BaseHelpers
63
+
64
+ elsif j['g'] # server banner
65
+ Kernel.puts "[pry-remote-em] remote is #{j['g']}"
66
+ name, version, scheme = j['g'].split(" ", 3)
67
+ # TODO parse version and compare against a Gem style matcher
68
+ # https://github.com/simulacre/pry-remote-em/issues/21
69
+ return fail("[pry-remote-em] incompatible version #{version}") if version != PryRemoteEm::VERSION
70
+ if scheme.nil? || scheme != (reqscheme = @opts[:tls] ? 'pryems' : 'pryem')
71
+ if scheme == 'pryems' && defined?(::OpenSSL)
72
+ @opts[:tls] = true
73
+ else
74
+ return fail("[pry-remote-em] server doesn't support required scheme #{reqscheme.dump}")
75
+ end # scheme == 'pryems' && defined?(::OpenSSL)
76
+ end
77
+ @nego_timer.cancel
78
+ @negotiated = true
79
+ start_tls if @opts[:tls]
80
+
81
+ elsif j['c'] # tab completion response
82
+ @waiting, f = nil, @waiting
83
+ f.resume(j['c']) if f
84
+
85
+ elsif j.include?('a') # authentication demand
86
+ return fail j['a'] if j['a'].is_a?(String)
87
+ return authenticate if j['a'] == false
88
+ @authenticated = true if j['a'] == true
89
+
90
+ else
91
+ warn "[pry-remote-em] received unexpected data: #{j.inspect}"
92
+ end
93
+ end
94
+
95
+ def authenticate
96
+ return fail("[pry-remote-em] authentication required") unless @auth
97
+ return fail("[pry-remote-em] can't authenticate before negotiation complete") unless @negotiated
98
+ user, pass = @auth.call
99
+ return fail("[pry-remote-em] expected #{@auth} to return a user and password") unless user && pass
100
+ send_data({:a => [user, pass]})
101
+ end # authenticate
102
+
103
+ def ssl_handshake_completed
104
+ Kernel.puts "[pry-remote-em] TLS connection established"
105
+ end
106
+
107
+ def start_tls
108
+ Kernel.puts "[pry-remote-em] negotiating TLS"
109
+ super(@opts[:tls].is_a?(Hash) ? @opts[:tls] : {})
110
+ end
111
+
112
+ def unbind
113
+ @unbound = true
114
+ Kernel.puts "[pry-remote-em] session terminated"
115
+ # prior to 1.0.0.b4 error? returns true here even when it's not
116
+ return succeed if Gem.loaded_specs["eventmachine"].version < Gem::Version.new("1.0.0.beta4")
117
+ error? ? fail : succeed
118
+ end
119
+ end # module::Client
120
+ end # module::PryRemoteEm
121
+
122
+ # Pry::Helpers::BaseHelpers#stagger_output expects Pry.pager to be defined
123
+ class Pry
124
+ class << self
125
+ attr_accessor :pager unless respond_to?(:pager)
126
+ end
127
+ end
128
+ Pry.pager = true
@@ -0,0 +1,30 @@
1
+ require 'json'
2
+
3
+ module PryRemoteEm
4
+ module JsonProto
5
+ DELIM = ']]>]]><[[<[['
6
+
7
+ def receive_data(d)
8
+ return unless d && d.length > 0
9
+ @buffer ||= "" # inlieu of a post_init
10
+
11
+ if six = d.index(DELIM)
12
+ @buffer << d[0...six]
13
+ j = JSON.load(@buffer)
14
+ @buffer.clear
15
+ receive_json(j)
16
+ receive_data(d[(six + DELIM.length)..-1])
17
+ else
18
+ @buffer << d
19
+ end
20
+ end
21
+
22
+ def receive_json(j)
23
+ end
24
+
25
+ def send_data(d)
26
+ super(JSON.dump(d.is_a?(String) ? {:d => d} : d) + DELIM)
27
+ end
28
+
29
+ end # module::JsonProto
30
+ end # module::PryRemoteEm
@@ -0,0 +1,168 @@
1
+ require 'pry'
2
+ require 'pry-remote-em'
3
+
4
+ module PryRemoteEm
5
+ module Server
6
+ include JsonProto
7
+
8
+ class << self
9
+ def run(obj, host = DEFHOST, port = DEFPORT, opts = {:tls => false})
10
+ tries = :auto == port ? 100.tap{ port = DEFPORT } : 1
11
+ # TODO raise a useful exception not RuntimeError
12
+ raise "root permission required for port below 1024 (#{port})" if port < 1024 && Process.euid != 0
13
+ begin
14
+ EM.start_server(host, port, PryRemoteEm::Server, opts) do |pre|
15
+ Fiber.new {
16
+ begin
17
+ Pry.start(obj, :input => pre, :output => pre)
18
+ ensure
19
+ pre.close_connection
20
+ end
21
+ }.resume
22
+ end
23
+ rescue => e
24
+ # EM 1.0.0.beta4's message tells us the port is in use; 0.12.10 just says, 'no acceptor'
25
+ if (e.message.include?('port is in use') || e.message.include?('no acceptor')) && tries >= 1
26
+ tries -= 1
27
+ port += 1
28
+ retry
29
+ end
30
+ raise e
31
+ end
32
+ scheme = opts[:tls] ? 'pryems' : 'pryem'
33
+ Kernel.puts "[pry-remote-em] listening for connections on #{scheme}://#{host}:#{port}/"
34
+ end # run(obj, host = DEFHOST, port = DEFPORT)
35
+ end # class << self
36
+
37
+ def initialize(opts = {:tls => false})
38
+ @after_auth = []
39
+ @opts = opts
40
+ if (a = opts[:auth])
41
+ if a.respond_to?(:call)
42
+ return error("auth handler procs must take two arguments") unless a.method(:call).arity == 2
43
+ @auth = a
44
+ else
45
+ return error("auth handler objects must respond to :call, or :[]") unless a.respond_to?(:[])
46
+ @auth = lambda {|u,p| a[u] && a[u] == p }
47
+ end
48
+ @auth_tries = 5
49
+ end
50
+ end
51
+
52
+ def post_init
53
+ @lines = []
54
+ Pry.config.pager, @old_pager = false, Pry.config.pager
55
+ Pry.config.system, @old_system = PryRemoteEm::Server::System, Pry.config.system
56
+ @auth_required = @auth
57
+ port, ip = Socket.unpack_sockaddr_in(get_peername)
58
+ Kernel.puts "[pry-remote-em] received client connection from #{ip}:#{port}"
59
+ send_data({:g => "PryRemoteEm #{VERSION} #{@opts[:tls] ? 'pryems' : 'pryem'}"})
60
+ @opts[:tls] ? start_tls : (@auth_required && send_data({:a => false}))
61
+ end
62
+
63
+ def start_tls
64
+ Kernel.puts "[pry-remote-em] starting TLS (#{peer_ip}:#{peer_port})"
65
+ super(@opts[:tls].is_a?(Hash) ? @opts[:tls] : {})
66
+ end
67
+
68
+ def ssl_handshake_completed
69
+ Kernel.puts "[pry-remote-em] TLS connection established (#{peer_ip}:#{peer_port})"
70
+ send_data({:a => false}) if @auth_required
71
+ end
72
+
73
+ def peer_ip
74
+ return @peer_ip if @peer_ip
75
+ return "" if get_peername.nil?
76
+ @peer_port, @peer_ip = Socket.unpack_sockaddr_in(get_peername)
77
+ @peer_ip
78
+ end
79
+
80
+ def peer_port
81
+ return @peer_port if @peer_port
82
+ return "" if get_peername.nil?
83
+ @peer_port, @peer_ip = Socket.unpack_sockaddr_in(get_peername)
84
+ @peer_port
85
+ end
86
+
87
+ def receive_json(j)
88
+ return send_data({:a => false}) if @auth_required && !j['a']
89
+
90
+ if j['d'] # just normal data
91
+ @lines.push(*j['d'].split("\n"))
92
+ if @waiting
93
+ f, @waiting = @waiting, nil
94
+ f.resume(@lines.shift)
95
+ end
96
+ elsif j['c'] # tab completion request
97
+ send_data({:c => @compl_proc.call(j['c'])})
98
+
99
+ elsif j['a'] # authentication response
100
+ return send_data({:a => true}) if !@auth || !@auth_required
101
+ return send_data({:a => 'auth data must be a two element array'}) unless j['a'].is_a?(Array) && j['a'].length == 2
102
+ unless (@auth_required = !@auth.call(*j['a']))
103
+ authenticated!
104
+ else
105
+ if @auth_tries <= 0
106
+ msg = "max authentication attempts reached"
107
+ send_data({:a => msg})
108
+ Kernel.puts "[pry-remote-em] #{msg} (#{peer_ip}:#{peer_port})"
109
+ return close_connection_after_writing
110
+ end
111
+ @auth_tries -= 1
112
+ end
113
+ return send_data({:a => !@auth_required})
114
+
115
+ else
116
+ warn "received unexpected data: #{j.inspect}"
117
+ end # j['d']
118
+ end # receive_json(j)
119
+
120
+
121
+ def authenticated!
122
+ while (aa = @after_auth.shift)
123
+ send_data(aa)
124
+ end
125
+ end
126
+
127
+ def unbind
128
+ Pry.config.pager = @old_pager
129
+ Pry.config.system = @old_system
130
+ Kernel.puts "[pry-remote-em] remote session terminated (#{peer_ip}:#{peer_port})"
131
+ end
132
+
133
+ # Methods that make Server compatible with Pry
134
+
135
+ def readline(prompt)
136
+ @auth_required ? @after_auth.push({:p => prompt}) : send_data({:p => prompt})
137
+ return @lines.shift unless @lines.empty?
138
+ @waiting = Fiber.current
139
+ return Fiber.yield
140
+ end
141
+
142
+ def print(val)
143
+ send_data({:d => val})
144
+ end
145
+ alias :write :print
146
+
147
+ def puts(data = "")
148
+ s = data.to_s
149
+ print(s[0] == "\n" ? s : s + "\n")
150
+ end
151
+
152
+ def completion_proc=(compl)
153
+ @compl_proc = compl
154
+ end
155
+
156
+ def tty?
157
+ true # might be a very bad idea ....
158
+ end
159
+
160
+ def flush
161
+ true
162
+ end
163
+
164
+ System = proc do |output, cmd, _|
165
+ output.puts("shell commands are not yet supported")
166
+ end
167
+ end # module::Server
168
+ end # module::PryRemoteEm
@@ -0,0 +1,3 @@
1
+ module PryRemoteEm
2
+ VERSION = '0.4.0'
3
+ end
metadata ADDED
@@ -0,0 +1,97 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pry-remote-em
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Caleb Crane
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-01-28 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: eventmachine
16
+ requirement: &70305814043480 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70305814043480
25
+ - !ruby/object:Gem::Dependency
26
+ name: pry
27
+ requirement: &70305814042980 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 0.9.6
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70305814042980
36
+ - !ruby/object:Gem::Dependency
37
+ name: rb-readline
38
+ requirement: &70305814042560 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70305814042560
47
+ - !ruby/object:Gem::Dependency
48
+ name: highline
49
+ requirement: &70305814042100 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *70305814042100
58
+ description: Connect to Pry remotely using EventMachine with tab-completion, paging,
59
+ user authentication and SSL support.
60
+ email: pry-remote-em@simulacre.org
61
+ executables:
62
+ - pry-remote-em
63
+ extensions: []
64
+ extra_rdoc_files: []
65
+ files:
66
+ - lib/pry-remote-em/client.rb
67
+ - lib/pry-remote-em/json-proto.rb
68
+ - lib/pry-remote-em/server.rb
69
+ - lib/pry-remote-em/version.rb
70
+ - lib/pry-remote-em.rb
71
+ - bin/pry-remote-em
72
+ - README.md
73
+ homepage: http://github.com/simulacre/pry-remote-em
74
+ licenses: []
75
+ post_install_message:
76
+ rdoc_options: []
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ none: false
81
+ requirements:
82
+ - - ! '>='
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ! '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ requirements: []
92
+ rubyforge_project:
93
+ rubygems_version: 1.8.10
94
+ signing_key:
95
+ specification_version: 3
96
+ summary: Connect to Pry remotely using EventMachine
97
+ test_files: []