Permalink
Browse files

Additional HTTP fixes.

 * Fixed HTTP request parsing to get all data instead of only the first buffer
   worth.
 * Changed time.sleep(0) in get_data to wait_read to avoid endlessly looping.
 * Properly check for empty return value from socket.recv indicating the socket
   is closed.
  • Loading branch information...
1 parent 49acd2f commit 0540125b966f968dd56fe52b50e61353cb876805 @jterrace jterrace committed Mar 7, 2013
Showing with 24 additions and 16 deletions.
  1. +21 −14 vaurien/protocols/http.py
  2. +1 −1 vaurien/proxy.py
  3. +2 −1 vaurien/util.py
View
35 vaurien/protocols/http.py
@@ -21,22 +21,29 @@ class Http(BaseProtocol):
def _handle(self, source, dest, to_backend):
buffer_size = self.option('buffer')
- # Getting the HTTP query
- data = self._get_data(source)
- data = HOST_REPLACE.sub('\r\nHost: %s\r\n' % self.proxy.backend, data)
-
- if not data:
- self._abort_handling(to_backend, dest)
- return False
-
- # sending it to the backend
- dest.sendall(data)
-
+ # Getting the HTTP query and sending it to the backend.
+ parser = HttpParser()
+ while not parser.is_message_complete():
+ data = self._get_data(source, buffer_size)
+ if not data:
+ self._abort_handling(to_backend, dest)
+ return False
+ nparsed = parser.execute(data, len(data))
+ assert nparsed == len(data)
+ data = HOST_REPLACE.sub('\r\nHost: %s\r\n'
+ % self.proxy.backend, data)
+ dest.sendall(data)
+
+ # Getting the HTTP response and sending it back to the source.
parser = HttpParser()
while not parser.is_message_complete():
- data = self._get_data(dest, buffer_size)
- parser.execute(data, len(data))
- source.sendall(data)
+ data = self._get_data(dest, buffer_size)
+ if not data:
+ self._abort_handling(to_backend, dest)
+ return False
+ nparsed = parser.execute(data, len(data))
+ assert nparsed == len(data)
+ source.sendall(data)
keep_alive = parser.should_keep_alive()
View
2 vaurien/proxy.py
@@ -70,7 +70,7 @@ def __init__(self, proxy, backend, protocol='tcp', behaviors=None,
logger.info('* async_mode: %d' % self.async_mode)
def _create_connection(self):
- conn = create_connection(self.dest)
+ conn = create_connection(self.dest, timeout=self.timeout)
if self.async_mode:
conn.setblocking(0)
return conn
View
3 vaurien/util.py
@@ -5,6 +5,7 @@
from gevent.socket import gethostbyname
from gevent.socket import error
+from gevent.socket import wait_read
from gevent import sleep
@@ -189,7 +190,7 @@ def get_data(sock, buffer=1024):
except error, e:
if e.args[0] not in (EWOULDBLOCK, EAGAIN):
raise
- sleep(0)
+ wait_read(sock.fileno(), timeout=sock.gettimeout())
def extract_settings(args, prefix, name):

0 comments on commit 0540125

Please sign in to comment.