25
25
self.cmdQ.put({"input":None})
29
# Some of our 5 seconds may have elapsed, but never mind.
28
# Some of our 5 seconds may have elapsed, but
33
33
class PythonRunner(Thread):
34
34
def __init__(self, cmdQ, lineQ):
37
self.out = cStringIO.StringIO()
38
37
Thread.__init__(self)
40
def execCmd(self, cmd):
42
sys.stdin = StdinFromWeb(self.cmdQ, self.lineQ)
46
res = eval(cmd, self.globs, self.locls)
48
self.cmdQ.put({"okay":(self.out.getvalue(),res)})
50
self.out = cStringIO.StringIO()
51
except Exception, exc:
53
self.cmdQ.put({"exc":(self.out.getvalue(),str(exc))})
55
self.out = cStringIO.StringIO()
59
41
compiler = codeop.CommandCompiler()
64
if self.curr_cmd == '':
65
self.curr_cmd = ln['chat']
45
if self.curr_cmd == '':
48
self.curr_cmd = self.curr_cmd + '\n' + l
50
cmd = compiler(self.curr_cmd)
52
# The command was incomplete,
53
# so send back a None, so the
54
# client can print a '...'
55
self.cmdQ.put({"more":None})
67
self.curr_cmd = self.curr_cmd + '\n' + ln['chat']
69
cmd = compiler(self.curr_cmd)
71
# The command was incomplete,
72
# so send back a None, so the
73
# client can print a '...'
74
self.cmdQ.put({"more":None})
77
except Exception, exc:
79
self.cmdQ.put({"exc":(self.out.getvalue(),str(exc))})
81
self.out = cStringIO.StringIO()
83
# throw away a partial command.
85
cmd = compile(ln['block'], "<web session>", 'exec');
87
except Exception, exc:
89
self.cmdQ.put({"exc":(self.out.getvalue(),str(exc))})
91
self.out = cStringIO.StringIO()
57
# The command was complete,
59
sys.stdin = StdinFromWeb(self.cmdQ, self.lineQ)
60
out = cStringIO.StringIO()
64
res = eval(cmd, globs, locls)
66
self.cmdQ.put({"okay":(out.getvalue(),res)})
68
except Exception, exc:
70
self.cmdQ.put({"exc":str(exc)})
93
73
def init_state(self):
100
if os.fork(): # launch child and...
101
os._exit(0) # kill off parent
103
if os.fork(): # launch child and...
104
os._exit(0) # kill off parent again.
81
'/index.html', 'index',
82
'/(.*\.js)', 'jscript',
83
'/(.*\.css)', 'style',
107
86
# The global 'magic' is the secret that the client and server share
108
87
# which is used to create and md5 digest to authenticate requests.
109
88
# It is assigned a real value at startup.
96
digest = md5.new('hello' + magic).digest().encode('hex')
97
if inp.digest != digest:
98
web.ctx.status = '401 Unauthorized'
101
# Okay, so the authentication succeeded,
102
# so all we need to do is send back the static
103
# HTML for the console app.
104
web.output(file("index.html", "r").read())
108
web.output(file(name, "r").read())
112
web.output(file(name, "r").read())
120
digest = md5.new(inp.text + magic).digest().encode('hex')
121
if inp.digest != digest:
122
web.output("401 Unauthorized")
123
web.ctx.status = '401 Unauthorized'
126
# Okay, so the authentication succeeded,
127
# so now we have the trivial matter of actually
128
# executing the python....
131
sys.__stderr__.write(cjson.encode(r) + "\n")
132
web.output(cjson.encode(r))
112
134
cmdQ = Queue.Queue()
113
135
lineQ = Queue.Queue()
114
136
interpThread = PythonRunner(cmdQ, lineQ)
116
138
if __name__ == "__main__":
117
port = int(sys.argv[1])
118
139
magic = sys.argv[2]
120
# Attempt to open the socket.
121
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
125
# Excellent! It worked. Let's turn ourself into a daemon,
126
# then get on with the job of being a python interpreter.
129
140
interpThread.setDaemon(True)
130
141
interpThread.start()
133
(conn, addr) = s.accept()
136
buf = cStringIO.StringIO()
137
blk = conn.recv(1024)
141
blk = conn.recv(1024, socket.MSG_DONTWAIT)
143
# Exception thrown if it WOULD block (but we
144
# told it not to wait) - ie. we are done
147
msg = cjson.decode(inp)
149
# Check that the message is
150
digest = md5.new(msg['text'] + magic).digest().encode('hex')
151
if msg['digest'] != digest:
155
lineQ.put({msg['cmd']:msg['text']})
157
conn.sendall(cjson.encode(r))
142
web.run(urls, globals())