summaryrefslogtreecommitdiffstats
path: root/Mac/Tools/IDE/Wsocket.py
diff options
context:
space:
mode:
Diffstat (limited to 'Mac/Tools/IDE/Wsocket.py')
-rw-r--r--Mac/Tools/IDE/Wsocket.py658
1 files changed, 329 insertions, 329 deletions
diff --git a/Mac/Tools/IDE/Wsocket.py b/Mac/Tools/IDE/Wsocket.py
index 913797c..eb5936d 100644
--- a/Mac/Tools/IDE/Wsocket.py
+++ b/Mac/Tools/IDE/Wsocket.py
@@ -17,375 +17,375 @@ BUFSIZE = 512
VERBOSE = 1
class Server(asyncore.dispatcher):
-
- """Generic asynchronous server class"""
-
- def __init__(self, port, handler_class, backlog=1, host=""):
- """arguments:
- - port: the port to listen to
- - handler_class: class to handle requests
- - backlog: backlog queue size (optional) (don't fully understand, see socket docs)
- - host: host name (optional: can be empty to use default host name)
- """
- if VERBOSE:
- print "Starting", self.__class__.__name__
- self.handler_class = handler_class
- asyncore.dispatcher.__init__(self)
- self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
- self.bind((host, port))
- self.listen(backlog)
-
- def handle_accept(self):
- conn, addr = self.accept()
- if VERBOSE:
- print 'Incoming Connection from %s:%d' % addr
- self.handler_class(conn)
+
+ """Generic asynchronous server class"""
+
+ def __init__(self, port, handler_class, backlog=1, host=""):
+ """arguments:
+ - port: the port to listen to
+ - handler_class: class to handle requests
+ - backlog: backlog queue size (optional) (don't fully understand, see socket docs)
+ - host: host name (optional: can be empty to use default host name)
+ """
+ if VERBOSE:
+ print "Starting", self.__class__.__name__
+ self.handler_class = handler_class
+ asyncore.dispatcher.__init__(self)
+ self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
+ self.bind((host, port))
+ self.listen(backlog)
+
+ def handle_accept(self):
+ conn, addr = self.accept()
+ if VERBOSE:
+ print 'Incoming Connection from %s:%d' % addr
+ self.handler_class(conn)
class ProxyServer(Server):
-
- """Generic proxy server class"""
-
- def __init__(self, port, handler_class, proxyaddr=None, closepartners=0):
- """arguments:
- - port: the port to listen to
- - handler_class: proxy class to handle requests
- - proxyaddr: a tuple containing the address and
- port of a remote host to connect to (optional)
- - closepartners: boolean, specifies whether we should close
- all proxy connections or not (optional). http seems to *not*
- want this, but telnet does...
- """
- Server.__init__(self, port, handler_class, 1, "")
- self.proxyaddr = proxyaddr
- self.closepartners = closepartners
-
- def handle_accept(self):
- conn, addr = self.accept()
- if VERBOSE:
- print 'Incoming Connection from %s:%d' % addr
- self.handler_class(conn, self.proxyaddr, closepartner=self.closepartners)
+
+ """Generic proxy server class"""
+
+ def __init__(self, port, handler_class, proxyaddr=None, closepartners=0):
+ """arguments:
+ - port: the port to listen to
+ - handler_class: proxy class to handle requests
+ - proxyaddr: a tuple containing the address and
+ port of a remote host to connect to (optional)
+ - closepartners: boolean, specifies whether we should close
+ all proxy connections or not (optional). http seems to *not*
+ want this, but telnet does...
+ """
+ Server.__init__(self, port, handler_class, 1, "")
+ self.proxyaddr = proxyaddr
+ self.closepartners = closepartners
+
+ def handle_accept(self):
+ conn, addr = self.accept()
+ if VERBOSE:
+ print 'Incoming Connection from %s:%d' % addr
+ self.handler_class(conn, self.proxyaddr, closepartner=self.closepartners)
class Connection(asyncore.dispatcher):
-
- """Generic connection class"""
-
- def __init__(self, sock_or_address=None, readfunc=None, terminator=None):
- """arguments:
- - sock_or_address: either a socket, or a tuple containing the name
- and port number of a remote host
- - readfunc: callback function (optional). Will be called whenever
- there is some data available, or when an appropraite terminator
- is found.
- - terminator: string which specifies when a read is complete (optional)"""
- self._out_buffer = ""
- self._in_buffer = ""
- self.readfunc = readfunc
- self.terminator = terminator
- asyncore.dispatcher.__init__(self)
- if hasattr(sock_or_address, "fileno"):
- self.set_socket(sock_or_address)
- else:
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- sock.setblocking(0)
- self.set_socket(sock)
- if sock_or_address:
- self.connect(sock_or_address)
-
- # public methods
- def send(self, data):
- self._out_buffer = self._out_buffer + data
-
- def recv(self, bytes=-1):
- if bytes == -1:
- bytes = len(self._in_buffer)
- data = self._in_buffer[:bytes]
- self._in_buffer = self._in_buffer[bytes:]
- return data
-
- def set_terminator(self, terminator):
- self.terminator = terminator
-
- # override this if you want to control the incoming data stream
- def handle_incoming_data(self, data):
- if self.readfunc:
- if self.terminator:
- self._in_buffer = self._in_buffer + data
- pos = string.find(self._in_buffer, self.terminator)
- if pos < 0:
- return
- data = self._in_buffer[:pos]
- self._in_buffer = self._in_buffer[pos + len(self.terminator):]
- self.readfunc(data)
- else:
- self.readfunc(self._in_buffer + data)
- self._in_buffer = ""
- else:
- self._in_buffer = self._in_buffer + data
-
- # internal muck
- def handle_read(self):
- data = asyncore.dispatcher.recv(self, BUFSIZE)
- if data:
- if VERBOSE > 2:
- print "incoming -> %x %r" % (id(self), data)
- self.handle_incoming_data(data)
-
- def handle_write(self):
- if self._out_buffer:
- sent = self.socket.send(self._out_buffer[:BUFSIZE])
- if VERBOSE > 2:
- print "outgoing -> %x %r" % (id(self), self._out_buffer[:sent])
- self._out_buffer = self._out_buffer[sent:]
-
- def close(self):
- if self.readfunc and self._in_buffer:
- self.readfunc(self._in_buffer)
- self._in_buffer = ""
- #elif VERBOSE > 1 and self._in_buffer:
- # print "--- there is unread data: %r", (self._in_buffer,)
- asyncore.dispatcher.close(self)
-
- def handle_close(self):
- self.close()
-
- def handle_connect(self):
- pass
+
+ """Generic connection class"""
+
+ def __init__(self, sock_or_address=None, readfunc=None, terminator=None):
+ """arguments:
+ - sock_or_address: either a socket, or a tuple containing the name
+ and port number of a remote host
+ - readfunc: callback function (optional). Will be called whenever
+ there is some data available, or when an appropraite terminator
+ is found.
+ - terminator: string which specifies when a read is complete (optional)"""
+ self._out_buffer = ""
+ self._in_buffer = ""
+ self.readfunc = readfunc
+ self.terminator = terminator
+ asyncore.dispatcher.__init__(self)
+ if hasattr(sock_or_address, "fileno"):
+ self.set_socket(sock_or_address)
+ else:
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ sock.setblocking(0)
+ self.set_socket(sock)
+ if sock_or_address:
+ self.connect(sock_or_address)
+
+ # public methods
+ def send(self, data):
+ self._out_buffer = self._out_buffer + data
+
+ def recv(self, bytes=-1):
+ if bytes == -1:
+ bytes = len(self._in_buffer)
+ data = self._in_buffer[:bytes]
+ self._in_buffer = self._in_buffer[bytes:]
+ return data
+
+ def set_terminator(self, terminator):
+ self.terminator = terminator
+
+ # override this if you want to control the incoming data stream
+ def handle_incoming_data(self, data):
+ if self.readfunc:
+ if self.terminator:
+ self._in_buffer = self._in_buffer + data
+ pos = string.find(self._in_buffer, self.terminator)
+ if pos < 0:
+ return
+ data = self._in_buffer[:pos]
+ self._in_buffer = self._in_buffer[pos + len(self.terminator):]
+ self.readfunc(data)
+ else:
+ self.readfunc(self._in_buffer + data)
+ self._in_buffer = ""
+ else:
+ self._in_buffer = self._in_buffer + data
+
+ # internal muck
+ def handle_read(self):
+ data = asyncore.dispatcher.recv(self, BUFSIZE)
+ if data:
+ if VERBOSE > 2:
+ print "incoming -> %x %r" % (id(self), data)
+ self.handle_incoming_data(data)
+
+ def handle_write(self):
+ if self._out_buffer:
+ sent = self.socket.send(self._out_buffer[:BUFSIZE])
+ if VERBOSE > 2:
+ print "outgoing -> %x %r" % (id(self), self._out_buffer[:sent])
+ self._out_buffer = self._out_buffer[sent:]
+
+ def close(self):
+ if self.readfunc and self._in_buffer:
+ self.readfunc(self._in_buffer)
+ self._in_buffer = ""
+ #elif VERBOSE > 1 and self._in_buffer:
+ # print "--- there is unread data: %r", (self._in_buffer,)
+ asyncore.dispatcher.close(self)
+
+ def handle_close(self):
+ self.close()
+
+ def handle_connect(self):
+ pass
class ConnectionUI:
-
- """Glue to let a connection tell things to the UI in a standardized way.
-
- The protocoll defines four functions, which the connection will call:
-
- def settotal(int total): gets called when the connection knows the data size
- def setcurrent(int current): gets called when some new data has arrived
- def done(): gets called when the transaction is complete
- def error(type, value, tb): gets called wheneven an error occured
- """
-
- def __init__(self, settotal_func, setcurrent_func, done_func, error_func):
- self.settotal = settotal_func
- self.setcurrent = setcurrent_func
- self.done = done_func
- self.error = error_func
+
+ """Glue to let a connection tell things to the UI in a standardized way.
+
+ The protocoll defines four functions, which the connection will call:
+
+ def settotal(int total): gets called when the connection knows the data size
+ def setcurrent(int current): gets called when some new data has arrived
+ def done(): gets called when the transaction is complete
+ def error(type, value, tb): gets called wheneven an error occured
+ """
+
+ def __init__(self, settotal_func, setcurrent_func, done_func, error_func):
+ self.settotal = settotal_func
+ self.setcurrent = setcurrent_func
+ self.done = done_func
+ self.error = error_func
class HTTPError(socket.error): pass
class HTTPClient(Connection, httplib.HTTP):
-
- """Asynchronous HTTP connection"""
-
- def __init__(self, (host, port), datahandler, ui=None):
- Connection.__init__(self, (host, port))
- self.datahandler = datahandler
- self.ui = ui
- self.buf = ""
- self.doneheaders = 0
- self.done = 0
- self.headers = None
- self.length = None
- self.pos = 0
-
- def getreply(self):
- raise TypeError, "getreply() is not supported in async HTTP connection"
-
- def handle_incoming_data(self, data):
- assert not self.done
- if not self.doneheaders:
- self.buf = self.buf + data
- pos = string.find(self.buf, "\r\n\r\n")
- if pos >= 0:
- self.handle_reply(self.buf[:pos+4])
- length = self.headers.getheader("Content-Length")
- if length is not None:
- self.length = int(length)
- if self.ui is not None:
- self.ui.settotal(self.length)
- else:
- self.length = -1
- self.doneheaders = 1
- self.handle_data(self.buf[pos+4:])
- self.buf = ""
- else:
- self.handle_data(data)
-
- def handle_reply(self, data):
- f = cStringIO.StringIO(data)
- ver, code, msg = string.split(f.readline(), None, 2)
- code = int(code)
- msg = string.strip(msg)
- if code <> 200:
- # Hm, this is what *I* need, but probably not correct...
- raise HTTPError, (code, msg)
- self.headers = mimetools.Message(f)
-
- def handle_data(self, data):
- self.pos = self.pos + len(data)
- if self.ui is not None:
- self.ui.setcurrent(self.pos)
- self.datahandler(data)
- if self.pos >= self.length:
- self.datahandler("")
- self.done = 1
- if self.ui is not None:
- self.ui.done()
-
- def handle_error(self, type, value, tb):
- if self.ui is not None:
- self.ui.error(type, value, tb)
- else:
- Connection.handle_error(self, type, value, tb)
-
- def log(self, message):
- if VERBOSE:
- print 'LOG:', message
+
+ """Asynchronous HTTP connection"""
+
+ def __init__(self, (host, port), datahandler, ui=None):
+ Connection.__init__(self, (host, port))
+ self.datahandler = datahandler
+ self.ui = ui
+ self.buf = ""
+ self.doneheaders = 0
+ self.done = 0
+ self.headers = None
+ self.length = None
+ self.pos = 0
+
+ def getreply(self):
+ raise TypeError, "getreply() is not supported in async HTTP connection"
+
+ def handle_incoming_data(self, data):
+ assert not self.done
+ if not self.doneheaders:
+ self.buf = self.buf + data
+ pos = string.find(self.buf, "\r\n\r\n")
+ if pos >= 0:
+ self.handle_reply(self.buf[:pos+4])
+ length = self.headers.getheader("Content-Length")
+ if length is not None:
+ self.length = int(length)
+ if self.ui is not None:
+ self.ui.settotal(self.length)
+ else:
+ self.length = -1
+ self.doneheaders = 1
+ self.handle_data(self.buf[pos+4:])
+ self.buf = ""
+ else:
+ self.handle_data(data)
+
+ def handle_reply(self, data):
+ f = cStringIO.StringIO(data)
+ ver, code, msg = string.split(f.readline(), None, 2)
+ code = int(code)
+ msg = string.strip(msg)
+ if code <> 200:
+ # Hm, this is what *I* need, but probably not correct...
+ raise HTTPError, (code, msg)
+ self.headers = mimetools.Message(f)
+
+ def handle_data(self, data):
+ self.pos = self.pos + len(data)
+ if self.ui is not None:
+ self.ui.setcurrent(self.pos)
+ self.datahandler(data)
+ if self.pos >= self.length:
+ self.datahandler("")
+ self.done = 1
+ if self.ui is not None:
+ self.ui.done()
+
+ def handle_error(self, type, value, tb):
+ if self.ui is not None:
+ self.ui.error(type, value, tb)
+ else:
+ Connection.handle_error(self, type, value, tb)
+
+ def log(self, message):
+ if VERBOSE:
+ print 'LOG:', message
class PyMessage:
-
- def __init__(self):
- self._buf = ""
- self._len = None
- self._checksum = None
-
- def feed(self, data):
- self._buf = self._buf + data
- if self._len is None:
- if len(self._buf) >= 8:
- import struct
- self._len, self._checksum = struct.unpack("ll", self._buf[:8])
- self._buf = self._buf[8:]
- if self._len is not None:
- if len(self._buf) >= self._len:
- import zlib
- data = self._buf[:self._len]
- leftover = self._buf[self._len:]
- self._buf = None
- assert self._checksum == zlib.adler32(data), "corrupt data"
- self.data = data
- return 1, leftover
- else:
- return 0, None
- else:
- return 0, None
+
+ def __init__(self):
+ self._buf = ""
+ self._len = None
+ self._checksum = None
+
+ def feed(self, data):
+ self._buf = self._buf + data
+ if self._len is None:
+ if len(self._buf) >= 8:
+ import struct
+ self._len, self._checksum = struct.unpack("ll", self._buf[:8])
+ self._buf = self._buf[8:]
+ if self._len is not None:
+ if len(self._buf) >= self._len:
+ import zlib
+ data = self._buf[:self._len]
+ leftover = self._buf[self._len:]
+ self._buf = None
+ assert self._checksum == zlib.adler32(data), "corrupt data"
+ self.data = data
+ return 1, leftover
+ else:
+ return 0, None
+ else:
+ return 0, None
class PyConnection(Connection):
-
- def __init__(self, sock_or_address):
- Connection.__init__(self, sock_or_address)
- self.currentmessage = PyMessage()
-
- def handle_incoming_data(self, data):
- while data:
- done, data = self.currentmessage.feed(data)
- if done:
- import cPickle
- self.handle_object(cPickle.loads(self.currentmessage.data))
- self.currentmessage = PyMessage()
-
- def handle_object(self, object):
- print 'unhandled object:', repr(object)
-
- def send(self, object):
- import cPickle, zlib, struct
- data = cPickle.dumps(object, 1)
- length = len(data)
- checksum = zlib.adler32(data)
- data = struct.pack("ll", length, checksum) + data
- Connection.send(self, data)
+
+ def __init__(self, sock_or_address):
+ Connection.__init__(self, sock_or_address)
+ self.currentmessage = PyMessage()
+
+ def handle_incoming_data(self, data):
+ while data:
+ done, data = self.currentmessage.feed(data)
+ if done:
+ import cPickle
+ self.handle_object(cPickle.loads(self.currentmessage.data))
+ self.currentmessage = PyMessage()
+
+ def handle_object(self, object):
+ print 'unhandled object:', repr(object)
+
+ def send(self, object):
+ import cPickle, zlib, struct
+ data = cPickle.dumps(object, 1)
+ length = len(data)
+ checksum = zlib.adler32(data)
+ data = struct.pack("ll", length, checksum) + data
+ Connection.send(self, data)
class Echo(Connection):
-
- """Simple echoing connection: it sends everything back it receives."""
-
- def handle_incoming_data(self, data):
- self.send(data)
+
+ """Simple echoing connection: it sends everything back it receives."""
+
+ def handle_incoming_data(self, data):
+ self.send(data)
class Proxy(Connection):
-
- """Generic proxy connection"""
-
- def __init__(self, sock_or_address=None, proxyaddr=None, closepartner=0):
- """arguments:
- - sock_or_address is either a socket or a tuple containing the
- name and port number of a remote host
- - proxyaddr: a tuple containing a name and a port number of a
- remote host (optional).
- - closepartner: boolean, specifies whether we should close
- the proxy connection (optional)"""
-
- Connection.__init__(self, sock_or_address)
- self.other = None
- self.proxyaddr = proxyaddr
- self.closepartner = closepartner
-
- def close(self):
- if self.other:
- other = self.other
- self.other = None
- other.other = None
- if self.closepartner:
- other.close()
- Connection.close(self)
-
- def handle_incoming_data(self, data):
- if not self.other:
- # pass data for possible automatic remote host detection
- # (see HTTPProxy)
- data = self.connectproxy(data)
- self.other.send(data)
-
- def connectproxy(self, data):
- other = self.__class__(self.proxyaddr, closepartner=self.closepartner)
- self.other = other
- other.other = self
- return data
+
+ """Generic proxy connection"""
+
+ def __init__(self, sock_or_address=None, proxyaddr=None, closepartner=0):
+ """arguments:
+ - sock_or_address is either a socket or a tuple containing the
+ name and port number of a remote host
+ - proxyaddr: a tuple containing a name and a port number of a
+ remote host (optional).
+ - closepartner: boolean, specifies whether we should close
+ the proxy connection (optional)"""
+
+ Connection.__init__(self, sock_or_address)
+ self.other = None
+ self.proxyaddr = proxyaddr
+ self.closepartner = closepartner
+
+ def close(self):
+ if self.other:
+ other = self.other
+ self.other = None
+ other.other = None
+ if self.closepartner:
+ other.close()
+ Connection.close(self)
+
+ def handle_incoming_data(self, data):
+ if not self.other:
+ # pass data for possible automatic remote host detection
+ # (see HTTPProxy)
+ data = self.connectproxy(data)
+ self.other.send(data)
+
+ def connectproxy(self, data):
+ other = self.__class__(self.proxyaddr, closepartner=self.closepartner)
+ self.other = other
+ other.other = self
+ return data
class HTTPProxy(Proxy):
-
- """Simple, useless, http proxy. It figures out itself where to connect to."""
-
- def connectproxy(self, data):
- if VERBOSE:
- print "--- proxy request", repr(data)
- addr, data = de_proxify(data)
- other = Proxy(addr)
- self.other = other
- other.other = self
- return data
+
+ """Simple, useless, http proxy. It figures out itself where to connect to."""
+
+ def connectproxy(self, data):
+ if VERBOSE:
+ print "--- proxy request", repr(data)
+ addr, data = de_proxify(data)
+ other = Proxy(addr)
+ self.other = other
+ other.other = self
+ return data
# helper for HTTPProxy
def de_proxify(data):
- import re
- req_pattern = "GET http://([a-zA-Z0-9-_.]+)(:([0-9]+))?"
- m = re.match(req_pattern, data)
- host, dummy, port = m.groups()
- if not port:
- port = 80
- else:
- port = int(port)
- # change "GET http://xx.xx.xx/yy" into "GET /yy"
- data = re.sub(req_pattern, "GET ", data)
- return (host, port), data
+ import re
+ req_pattern = "GET http://([a-zA-Z0-9-_.]+)(:([0-9]+))?"
+ m = re.match(req_pattern, data)
+ host, dummy, port = m.groups()
+ if not port:
+ port = 80
+ else:
+ port = int(port)
+ # change "GET http://xx.xx.xx/yy" into "GET /yy"
+ data = re.sub(req_pattern, "GET ", data)
+ return (host, port), data
# if we're running "under W", let's register the socket poller to the event loop
try:
- import W
+ import W
except:
- pass
+ pass
else:
- W.getapplication().addidlefunc(asyncore.poll)
+ W.getapplication().addidlefunc(asyncore.poll)
## testing muck