-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.rb
153 lines (134 loc) · 3.07 KB
/
main.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
require 'rubygems'
require 'pty'
require 'eventmachine'
require 'evma_httpserver'
require 'em-pusher'
class MyHttpServer < EM::Connection
include EM::HttpServer
def post_init
super
no_environment_strings
end
def default
response = EM::DelegatedHttpResponse.new(self)
response.status = 404
response.content_type 'text/html'
response.content = 'nothing here'
response.send_response
end
def handle_get
if @http_path_info == "/index.html" or @http_path_info == "/"
p "starting shell"
$shell = PTY.spawn('/bin/csh')
$r_pty, $w_pty = $shell
response = EM::DelegatedHttpResponse.new(self)
response.status = 200
response.content_type 'text/html'
response.content = File.read('index.html')
response.send_response
else
default
end
end
def start_shell
response = EM::DelegatedHttpResponse.new(self)
response.status = 200
response.content_type 'text/html'
response.content = 'post'
response.send_response
end
def recv_command
key_code = @http_post_content.split('=').last.to_i
$w_pty.print key_code.chr
$w_pty.flush
response = EM::DelegatedHttpResponse.new(self)
response.status = 200
response.content_type 'text/html'
response.content = 'post'
response.send_response
end
def handle_post
if @http_path_info == "/start"
start_shell
else
recv_command
end
end
def process_http_request
# the http request details are available via the following instance variables:
# @http_protocol
# @http_request_method
# @http_cookie
# @http_if_none_match
# @http_content_type
# @http_path_info
# @http_request_uri
# @http_query_string
# @http_post_content
# @http_headers
if @http_request_method.downcase == "post"
handle_post
else
handle_get
end
end
end
class BufferedPusher
def initialize(size, &block)
@blk = block
@size = size
@arr = []
end
def push(obj)
p "called push"
if @arr.length > @size
p "calling block"
@blk.call(@arr)
@arr = []
end
@arr << obj
end
end
#$buffered_pusher = BufferedPusher.new(10) { |buff| }
$buffer = []
def flush_from_buffer
buff = []
while last = $buffer.shift
buff << last
end
p "flushing #{buff.inspect}"
$pusher.trigger('shell', { :code => buff.join('') }) unless buff.empty?
end
def flush_to_buffer
$reader = Thread.new {
while true
begin
next if $r_pty.nil?
c = $r_pty.getc
if c.nil? then
Thread.stop
end
$buffer.push(c.chr)
p "$buffer if #{$buffer}"
#print c.chr
rescue
Thread.stop
end
end
}
end
EM.run{
$pusher = EventMachine::Pusher.new(
:app_id => 9118,
:auth_key => 'aa94d705bd3fef88df05',
:auth_secret => '4272f175e71800bd3c90',
:channel => 'shell'
)
EventMachine::PeriodicTimer.new(0.5) do
flush_from_buffer
end
EventMachine::PeriodicTimer.new(0.5) do
flush_to_buffer
end
EM.start_server '0.0.0.0', 8080, MyHttpServer
}