[Zope-CVS] CVS: Packages/tcpwatch - tcpwatch:1.12
Shane Hathaway
shane@cvs.zope.org
Mon, 25 Feb 2002 14:46:56 -0500
Update of /cvs-repository/Packages/tcpwatch
In directory cvs.zope.org:/tmp/cvs-serv6953
Modified Files:
tcpwatch
Log Message:
Added comments and made sure:
- Server connections get closed when the client connection is closed.
- Client connections get closed when servers don't finish the response.
=== Packages/tcpwatch/tcpwatch 1.11 => 1.12 ===
class ForwardingEndpoint (asyncore.dispatcher):
+ """A socket wrapper that accepts and generates stream messages.
+ """
_dests = ()
def __init__(self, conn=None):
@@ -161,7 +163,10 @@
class EndpointObserver:
- """Sends endpoint events to a ConnectionObserver.
+ """Sends stream events to a ConnectionObserver.
+
+ Streams don't distinguish sources, while ConnectionObservers do.
+ This adapter adds source information to stream events.
"""
def __init__(self, obs, from_client):
@@ -183,7 +188,6 @@
class ForwardedConnectionInfo:
-
transaction = 1
def __init__(self, connection_number, client_addr, server_addr=None):
@@ -966,6 +970,8 @@
if parser.completed:
self.finished = 1
self.flush()
+ # Note that any extra data returned from the server is
+ # ignored. Should it be? :-(
return
if not data:
break
@@ -977,7 +983,8 @@
self.flush()
def flush(self):
- """Flushes buffers and, if done, allows the next response to take over.
+ """Flushes buffers and, if the response has been sent, allows
+ the next response to take over.
"""
if self.held and self._isMyTurn():
data = ''.join(self.held)
@@ -990,15 +997,29 @@
if order:
order[0].flush() # kick!
- def close(self):
+ def handle_close(self):
"""The HTTP server closed the connection.
"""
- ForwardingEndpoint.close(self)
+ ForwardingEndpoint.handle_close(self)
if not self.finished:
- # TODO: cancel the proxy connection.
- pass
- self.finished = 1
+ # Cancel the proxy connection, even if there are responses
+ # pending, since the HTTP spec provides no way to recover
+ # from an unfinished response.
+ self.proxy_conn.close()
+
+ def close(self):
+ """Close the connection to the server.
+
+ If there is unsent response data, an error is generated.
+ """
self.flush()
+ if not self.finished:
+ t = IOError
+ v = 'Closed without finishing response to client'
+ for d in self._dests:
+ if hasattr(d, 'error'):
+ d.error(t, v)
+ ForwardingEndpoint.close(self)
@@ -1106,13 +1127,22 @@
ptos.connect((host, port))
def close(self):
+ """Closes the connection to the client.
+
+ If there are open connections to proxy servers, the server
+ connections are also closed.
+ """
ForwardingEndpoint.close(self)
- # TODO: Close the open connections to HTTP servers.
+ for ptos in self._response_order:
+ ptos.close()
+ del self._response_order[:]
class HTTPProxyService (asyncore.dispatcher):
"""A minimal HTTP proxy server"""
+ connection_class = HTTPProxyToClientConnection
+
_counter = 0
def __init__(self, listen_host, listen_port, observer_factory=None):
@@ -1131,7 +1161,7 @@
conn.setblocking(0)
counter = self._counter + 1
self._counter = counter
- HTTPProxyToClientConnection(conn, self._obs_factory, counter, addr)
+ self.connection_class(conn, self._obs_factory, counter, addr)
def handle_error(self):
# Don't stop the server.