~azzar1/unity/add-show-desktop-key

« back to all changes in this revision

Viewing changes to ivle/chat.py

  • Committer: Matt Giuca
  • Date: 2010-02-23 07:46:34 UTC
  • Revision ID: matt.giuca@gmail.com-20100223074634-r08p14zoy3u5atoc
browser.js: Fixed check for whether to use specialhome -- now works if the path ends in a '/'. This fixes Launchpad Bug #492510.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 
22
22
import cjson
23
23
import cStringIO
24
 
import md5
 
24
import hashlib
25
25
import sys
26
26
import os
27
27
import socket
28
28
import traceback
29
29
 
 
30
SOCKETTIMEOUT = 60
 
31
BLOCKSIZE = 1024
 
32
 
30
33
class Terminate(Exception):
31
 
    """Exception thrown when server is to be shut down. It will attempt to sned 
32
 
    the final_response to the client and then exits"""
 
34
    """Exception thrown when server is to be shut down. It will attempt to
 
35
    send the final_response to the client and then exits"""
33
36
    def __init__(self, final_response=None):
34
37
        self.final_response = final_response
35
38
 
36
39
    def __str__(self):
37
40
        return repr(self.final_response)
38
41
 
 
42
class ProtocolError(Exception):
 
43
    """Exception thrown when client violates the the chat protocol"""
 
44
    pass
39
45
 
40
46
def start_server(port, magic, daemon_mode, handler, initializer = None):
41
47
    # Attempt to open the socket.
81
87
 
82
88
    while True:
83
89
        (conn, addr) = s.accept()
 
90
        conn.settimeout(SOCKETTIMEOUT)
84
91
        try:
85
92
            # Grab the input
86
 
            buf = cStringIO.StringIO()
87
 
            blk = conn.recv(1024)
88
 
            while blk:
89
 
                buf.write(blk)
90
 
                try:
91
 
                    blk = conn.recv(1024, socket.MSG_DONTWAIT)
92
 
                except:
93
 
                    # Exception thrown if it WOULD block (but we
94
 
                    # told it not to wait) - ie. we are done
95
 
                    blk = None
96
 
            inp = buf.getvalue()
 
93
            inp = recv_netstring(conn)
97
94
            env = cjson.decode(inp)
98
 
            
 
95
 
99
96
            # Check that the message is 
100
 
            digest = md5.new(env['content'] + magic).digest().encode('hex')
 
97
            digest = hashlib.md5(env['content'] + magic).hexdigest()
101
98
            if env['digest'] != digest:
102
99
                conn.close()
103
100
                continue
106
103
 
107
104
            response = handler(content)
108
105
 
109
 
            conn.sendall(cjson.encode(response))
 
106
            send_netstring(conn, cjson.encode(response))
110
107
 
111
108
            conn.close()
112
109
 
113
110
        except Terminate, t:
114
111
            # Try and send final response and then terminate
115
112
            if t.final_response:
116
 
                conn.sendall(cjson.encode(t.final_response))
 
113
                send_netstring(conn, cjson.encode(t.final_response))
117
114
            conn.close()
118
115
            sys.exit(0)
119
116
        except Exception:
126
123
                "value": str(e_val),
127
124
                "traceback": tb_dump.getvalue()
128
125
            }
129
 
            conn.sendall(cjson.encode(json_exc))
 
126
            send_netstring(conn, cjson.encode(json_exc))
130
127
            conn.close()
131
128
 
132
129
 
133
130
def chat(host, port, msg, magic, decode = True):
134
131
    sok = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
135
132
    sok.connect((host, port))
 
133
    sok.settimeout(SOCKETTIMEOUT)
136
134
    content = cjson.encode(msg)
137
 
    digest = md5.new(content + magic).digest().encode("hex")
 
135
    digest = hashlib.md5(content + magic).hexdigest()
138
136
    env = {'digest':digest,'content':content}
139
 
    sok.send(cjson.encode(env))
140
 
 
141
 
    buf = cStringIO.StringIO()
142
 
    blk = sok.recv(1024)
143
 
    while blk:
144
 
        buf.write(blk)
145
 
        try:
146
 
            blk = sok.recv(1024, socket.MSG_DONTWAIT)
147
 
        except socket.error, e:
148
 
            if e[0] != 11:
149
 
                raise
150
 
            # Exception thrown if it WOULD block (but we
151
 
            # told it not to wait) - ie. we are done
152
 
            blk = None
153
 
    inp = buf.getvalue()
 
137
    json = cjson.encode(env)
 
138
 
 
139
    send_netstring(sok, json)
 
140
    inp = recv_netstring(sok)
 
141
 
154
142
    sok.close()
155
143
 
156
144
    if decode:
158
146
    else:
159
147
        return inp
160
148
 
 
149
 
 
150
def send_netstring(sok, data):
 
151
    netstring = "%d:%s,"%(len(data),data)
 
152
    sok.sendall(netstring)
 
153
 
 
154
 
 
155
def recv_netstring(sok):
 
156
    # Decode netstring
 
157
    size_buffer = []
 
158
    c = sok.recv(1)
 
159
    while c != ':':
 
160
        # Limit the Netstring to less than 10^10 bytes (~1GB).
 
161
        if len(size_buffer) >= 10:
 
162
            raise ProtocolError(
 
163
                    "Could not read Netstring size in first 9 bytes: '%s'"%(
 
164
                    ''.join(size_buffer)))
 
165
        size_buffer.append(c)
 
166
        c = sok.recv(1)
 
167
    try:
 
168
        # Message should be length plus ',' terminator
 
169
        recv_expected = int(''.join(size_buffer)) + 1
 
170
    except ValueError, e:
 
171
        raise ProtocolError("Could not decode Netstring size as int: '%s'"%(
 
172
                ''.join(size_buffer)))
 
173
 
 
174
    # Read data
 
175
    buf = []
 
176
    recv_data = sok.recv(min(recv_expected, BLOCKSIZE))
 
177
    recv_size = len(recv_data)
 
178
    while recv_size < recv_expected:
 
179
        buf.append(recv_data)
 
180
        recv_data = sok.recv(min(recv_expected-recv_size, 1024))
 
181
        recv_size = recv_size + len(recv_data)
 
182
    assert(recv_size == recv_expected)
 
183
 
 
184
    # Did we receive the correct amount?
 
185
    if recv_data[-1] != ',':
 
186
        raise ProtocolError("Netstring did not end with ','")
 
187
    buf.append(recv_data[:-1])
 
188
 
 
189
    return ''.join(buf)