From dd4c75060486d90c047ee4b3b5139f33d19fdfae Mon Sep 17 00:00:00 2001 From: donovan Date: Tue, 1 Apr 2008 14:42:21 -0700 Subject: [PATCH 1/3] Fix Request.request_protocol; it was looking for is_secure in a place the refactoring had made go away --- eventlet/httpd.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/eventlet/httpd.py b/eventlet/httpd.py index 91bf43c..154a94b 100644 --- a/eventlet/httpd.py +++ b/eventlet/httpd.py @@ -389,7 +389,7 @@ class Request(object): return self.protocol.request_version def request_protocol(self): - if self.protocol.socket.is_secure: + if self.protocol.is_secure: return "https" return "http" @@ -413,6 +413,7 @@ class Timeout(RuntimeError): class HttpProtocol(BaseHTTPServer.BaseHTTPRequestHandler): def __init__(self, request, client_address, server): self.rfile = self.wfile = request.makefile() + self.is_secure = request.is_secure request.close() # close this now so that when rfile and wfile are closed, the socket gets closed self.client_address = client_address self.server = server From 0f07b622450d140817d7f308381b81e21da681ef Mon Sep 17 00:00:00 2001 From: donovan Date: Tue, 1 Apr 2008 14:44:04 -0700 Subject: [PATCH 2/3] eventlet.support.pycurls module, experimental module which uses libcurl instead of python's httplib to perform http requests. Hopefully this can eventually be shimmed in as an optional faster implementation of the httpc module. --- eventlet/support/pycurls.py | 103 ++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 eventlet/support/pycurls.py diff --git a/eventlet/support/pycurls.py b/eventlet/support/pycurls.py new file mode 100644 index 0000000..716bc1b --- /dev/null +++ b/eventlet/support/pycurls.py @@ -0,0 +1,103 @@ +"""http client that uses pycurl +""" + +from eventlet import api + +import pycurl + + +CURL_POLL_NONE = 0 +CURL_POLL_IN = 1 +CURL_POLL_OUT = 2 +CURL_POLL_INOUT = 3 +CURL_POLL_REMOVE = 4 + + + +SUSPENDED_COROS = {} +LAST_SOCKET = None +LAST_SOCKET_DONE = False + + +def hub_callback(fileno): + print "HUB_CALLBACK", fileno + SUSPENDED_COROS[fileno].switch() + + +def socket_callback(action, socket, user_data, socket_data): + global LAST_SOCKET + global LAST_SOCKET_DONE + LAST_SOCKET = socket + LAST_SOCKET_DONE = False + print "SOCKET_CALLBACK", action, socket, user_data, socket_data + hub = api.get_hub() + if action == CURL_POLL_NONE: + # nothing to do + return + elif action == CURL_POLL_IN: + print "POLLIN" + hub.add_descriptor(socket, read=hub_callback) + elif action == CURL_POLL_OUT: + print "POLLOUT" + hub.add_descriptor(socket, write=hub_callback) + elif action == CURL_POLL_INOUT: + print "POLLINOUT" + hub.add_descriptor(socket, read=hub_callback, write=hub_callback) + elif action == CURL_POLL_REMOVE: + print "POLLREMOVE" + hub.remove_descriptor(socket) + LAST_SOCKET_DONE = True + + +THE_MULTI = pycurl.CurlMulti() +THE_MULTI.setopt(pycurl.M_SOCKETFUNCTION, socket_callback) + + +def read(*data): + print "READ", data + + +def write(*data): + print "WRITE", data + + +def runloop_observer(*_): + result, numhandles = THE_MULTI.socket_all() + print "PERFORM RESULT", result + while result == pycurl.E_CALL_MULTI_PERFORM: + result, numhandles = THE_MULTI.socket_all() + print "PERFORM RESULT2", result + + +def get(url): + hub = api.get_hub() + c = pycurl.Curl() + c.setopt(pycurl.URL, url) + #c.setopt(pycurl.M_SOCKETFUNCTION, socket_callback) + c.setopt(pycurl.WRITEFUNCTION, write) + c.setopt(pycurl.READFUNCTION, read) + c.setopt(pycurl.NOSIGNAL, 1) + THE_MULTI.add_handle(c) + hub.add_observer(runloop_observer, 'before_waiting') + while True: + print "TOP" + result, numhandles = THE_MULTI.socket_all() + print "PERFORM RESULT", result + while result == pycurl.E_CALL_MULTI_PERFORM: + result, numhandles = THE_MULTI.socket_all() + print "PERFORM RESULT2", result + + if LAST_SOCKET_DONE: + break + + SUSPENDED_COROS[LAST_SOCKET] = api.getcurrent() + print "SUSPENDED", SUSPENDED_COROS + api.get_hub().switch() + print "BOTTOM" + + if not SUSPENDED_COROS: + hub.remove_observer(runloop_observer) + + +#from eventlet.support import pycurls +#reload(pycurls); from eventlet.support import pycurls; pycurls.get('http://localhost/') \ No newline at end of file From bb6171295b232b6ffaf55a03b281b6518297e578 Mon Sep 17 00:00:00 2001 From: donovan Date: Fri, 18 Apr 2008 10:17:56 -0700 Subject: [PATCH 3/3] Catch epipe --- eventlet/wsgi.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/eventlet/wsgi.py b/eventlet/wsgi.py index 2fa765a..4b5d349 100644 --- a/eventlet/wsgi.py +++ b/eventlet/wsgi.py @@ -23,6 +23,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ +import errno import sys import time import urllib @@ -204,16 +205,21 @@ class Server(BaseHTTPServer.HTTPServer): self.log.write(message + '\n') -def server(socket, site, log=None, environ=None): - serv = Server(socket, socket.getsockname(), site, log, environ=None) +def server(sock, site, log=None, environ=None): + serv = Server(sock, sock.getsockname(), site, log, environ=None) try: - print "wsgi starting up on", socket.getsockname() + print "wsgi starting up on", sock.getsockname() while True: try: - api.spawn(serv.process_request, socket.accept()) + api.spawn(serv.process_request, sock.accept()) except KeyboardInterrupt: - api.get_hub().remove_descriptor(socket.fileno()) + api.get_hub().remove_descriptor(sock.fileno()) print "wsgi exiting" break finally: - socket.close() + try: + sock.close() + except socket.error, e: + if e[0] != errno.EPIPE: + raise +