diff --git a/eventlet/httpd.py b/eventlet/httpd.py index 59e698f..8e4e258 100644 --- a/eventlet/httpd.py +++ b/eventlet/httpd.py @@ -394,7 +394,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" @@ -418,6 +418,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 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 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 +