[tor-commits] [flashproxy/master] Add readline abstraction.

dcf at torproject.org dcf at torproject.org
Fri Aug 31 11:39:36 UTC 2012


commit d3e4263f443da5760fe7ed533fa1dbd48e4bc54a
Author: David Fifield <david at bamsoftware.com>
Date:   Sat Jul 7 07:31:31 2012 -0700

    Add readline abstraction.
---
 facilitator |   42 +++++++++++++++++++++++++++++++++++++++---
 1 files changed, 39 insertions(+), 3 deletions(-)

diff --git a/facilitator b/facilitator
index 26c964d..16782cc 100755
--- a/facilitator
+++ b/facilitator
@@ -16,6 +16,8 @@ DEFAULT_LOG_FILENAME = "facilitator.log"
 
 # Don't indulge clients for more than this many seconds.
 CLIENT_TIMEOUT = 1.0
+# Buffer no many than this many bytes when trying to read a line.
+READLINE_MAX_LENGTH = 10240
 
 LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
 
@@ -115,6 +117,8 @@ def format_addr(addr):
 class Handler(SocketServer.StreamRequestHandler):
     def __init__(self, *args, **kwargs):
         self.deadline = time.time() + CLIENT_TIMEOUT
+        # Buffer for readline.
+        self.buffer = ""
         SocketServer.StreamRequestHandler.__init__(self, *args, **kwargs)
 
     def recv(self):
@@ -123,13 +127,45 @@ class Handler(SocketServer.StreamRequestHandler):
         return self.connection.recv(1024)
 
     def readline(self):
+        # A line already buffered?
+        i = self.buffer.find("\n")
+        if i >= 0:
+            line = self.buffer[:i+1]
+            self.buffer = self.buffer[i+1:]
+            return line
+
+        auxbuf = []
+        buflen = len(self.buffer)
         while True:
-            self.connection.settimeout(timeout)
+            data = self.recv()
+            if not data:
+                if self.buffer or auxbuf:
+                    raise socket.error("readline: stream does not end with a newline")
+                else:
+                    return ""
+            i = data.find("\n")
+            if i >= 0:
+                line = self.buffer + "".join(auxbuf) + data[:i+1]
+                self.buffer = data[i+1:]
+                return line
+            else:
+                auxbuf.append(data)
+                buflen += len(data)
+                if buflen >= READLINE_MAX_LENGTH:
+                    raise socket.error("readline: refusing to buffer %d bytes (last read was %d bytes)" % (buflen, len(data)))
 
     def handle(self):
+        num_lines = 0
         while True:
-            data = self.recv()
-            print repr(data)
+            try:
+                line = self.readline()
+                if not line:
+                    break
+                num_lines += 1
+            except socket.error, e:
+                log("socket error after reading %d lines: %s" % (num_lines, str(e)))
+                break
+            print "line", repr(line)
 
 class Server(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
     allow_reuse_address = True





More information about the tor-commits mailing list