def sendall (self, data, flags = 0): # *NOTE: gross, copied code from ssl.py becase it's not factored well enough to be used as-is if self._sslobj: if flags != 0: raise ValueError( "non-zero flags not allowed in calls to sendall() on %s" % self.__class__) amount = len(data) count = 0 while (count < amount): v = self.send(data[count:]) count += v return amount else: while True: try: return socket.sendall(self, buflen, flags) except orig_socket.error, e: if self.act_non_blocking: raise if get_errno(e) == errno.EWOULDBLOCK: trampoline(self, write = True, timeout = self.gettimeout(), timeout_exc = timeout_exc('timed out')) if get_errno(e) in SOCKET_CLOSED: return '' raise
def read (fd, n): """ read(fd, buffersize) -> string Read a file descriptor.""" while True: try: return __original_read__(fd, n) except (OSError, IOError), e: if get_errno(e) != errno.EAGAIN: raise except socket.error, e: if get_errno(e) == errno.EPIPE: return '' raise
def write(fd, st): """ write(fd, string) -> byteswritten Write a string to a file descriptor. """ while True: try: return __original_write__(fd, st) except (OSError, IOError), e: if get_errno(e) != errno.EAGAIN: raise except socket.error, e: if get_errno(e) != errno.EPIPE: raise
def write (fd, st): """ write(fd, string) -> byteswritten Write a string to a file descriptor. """ while True: try: return __original_write__(fd, st) except (OSError, IOError), e: if get_errno(e) != errno.EAGAIN: raise except socket.error, e: if get_errno(e) != errno.EPIPE: raise
def read(fd, n): """ read(fd, buffersize) -> string Read a file descriptor.""" while True: try: return __original_read__(fd, n) except (OSError, IOError), e: if get_errno(e) != errno.EAGAIN: raise except socket.error, e: if get_errno(e) == errno.EPIPE: return '' raise
def spam_to_me (address): sock = convenience.connect(address) while True: try: sock.sendall('hello world') except socket.error, e: if get_errno(e) == errno.EPIPE: return raise
def recv (self, buflen): while True: try: data = _os_orig.read(self._fileno, buflen) return data except OSError, e: if get_errno(e) != errno.EAGAIN: raise IOError(*e.args) wait_read(self)
def spam_to_me(address): sock = convenience.connect(address) while True: try: sock.sendall('hello world') except socket.error, e: if get_errno(e) == errno.EPIPE: return raise
def _socket_connect (self, addr): real_connect = socket.connect if self.act_non_blocking: return real_connect(self, addr) else: # *NOTE: gross, copied code from greenio because it's not factored # well enough to reuse if self.gettimeout() is None: while True: try: return real_connect(self, addr) except orig_socket.error, exc: if get_errno(exc) in CONNECT_ERR: trampoline(self, write = True) elif get_errno(exc) in CONNECT_SUCCESS: return else: raise else:
def reader (): try: while True: data = client.recv(1024) self.assert_(data) except socket.error, e: # we get an EBADF because client is closed in the same process # (but a different greenthread) if get_errno(e) != errno.EBADF: raise
def sendall (self, data): len_data = len(data) os_write = _os_orig.write fileno = self._fileno try: total_sent = os_write(fileno, data) except OSError, e: if get_errno(e) != errno.EAGAIN: raise IOError(*e.args) total_sent = 0
def reader(): try: while True: data = client.recv(1024) self.assert_(data) except socket.error, e: # we get an EBADF because client is closed in the same process # (but a different greenthread) if get_errno(e) != errno.EBADF: raise
def _call_trampolining (self, func, *a, **kw): if self.act_non_blocking: return func(*a, **kw) else: while True: try: return func(*a, **kw) except __ssl.SSLError, exc: if get_errno(exc) == __ssl.SSL_ERROR_WANT_READ: trampoline(self, read = True, timeout = self.gettimeout(), timeout_exc = timeout_exc('timed out')) elif get_errno(exc) == __ssl.SSL_ERROR_WANT_WRITE: trampoline(self, write = True, timeout = self.gettimeout(), timeout_exc = timeout_exc('timed out')) else: raise
def read(self, size): """Works like a blocking call to SSL_read(), whose behavior is described here: http://www.openssl.org/docs/ssl/SSL_read.html""" if self.act_non_blocking: return self.fd.read(size) while True: try: return self.fd.read(size) except WantReadError: trampoline(self.fd.fileno(), read=True, timeout=self.gettimeout(), timeout_exc=socket.timeout) except WantWriteError: trampoline(self.fd.fileno(), write=True, timeout=self.gettimeout(), timeout_exc=socket.timeout) except SysCallError, e: if get_errno(e) == -1 or get_errno(e) > 0: return ''
def socket_accept (descriptor): """ Attempts to accept() on the descriptor, returns a client,address tuple if it succeeds; returns None if it needs to trampoline, and raises any exceptions. """ try: return descriptor.accept() except socket.error, e: if get_errno(e) == errno.EWOULDBLOCK: return None raise
def read (self, size): """Works like a blocking call to SSL_read(), whose behavior is described here: http://www.openssl.org/docs/ssl/SSL_read.html""" if self.act_non_blocking: return self.fd.read(size) while True: try: return self.fd.read(size) except WantReadError: trampoline(self.fd.fileno(), read = True, timeout = self.gettimeout(), timeout_exc = socket.timeout) except WantWriteError: trampoline(self.fd.fileno(), write = True, timeout = self.gettimeout(), timeout_exc = socket.timeout) except SysCallError, e: if get_errno(e) == -1 or get_errno(e) > 0: return ''
def socket_accept(descriptor): """ Attempts to accept() on the descriptor, returns a client,address tuple if it succeeds; returns None if it needs to trampoline, and raises any exceptions. """ try: return descriptor.accept() except socket.error, e: if get_errno(e) == errno.EWOULDBLOCK: return None raise
def recv (self, buflen = 1024, flags = 0): # *NOTE: gross, copied code from ssl.py becase it's not factored well enough to be used as-is if self._sslobj: if flags != 0: raise ValueError( "non-zero flags not allowed in calls to recv() on %s" % self.__class__) read = self.read(buflen) return read else: while True: try: return socket.recv(self, buflen, flags) except orig_socket.error, e: if self.act_non_blocking: raise if get_errno(e) == errno.EWOULDBLOCK: trampoline(self, read = True, timeout = self.gettimeout(), timeout_exc = timeout_exc('timed out')) if get_errno(e) in SOCKET_CLOSED: return '' raise
class TestGreenSocketErrors(LimitedTestCase): TEST_TIMEOUT = 2 def assertWriteToClosedFileRaises(self, fd): if sys.version_info[0] < 3: # 2.x socket._fileobjects are odd: writes don't check # whether the socket is closed or not, and you get an # AttributeError during flush if it is closed fd.write('a') self.assertRaises(Exception, fd.flush) else: # 3.x poll write to closed file-like pbject raises ValueError self.assertRaises(ValueError, fd.write, 'a') def test_socket_error(self): # Testing socket module exceptions def raise_error(*args, **kwargs): raise socket.error def raise_herror(*args, **kwargs): raise socket.herror def raise_gaierror(*args, **kwargs): raise socket.gaierror self.assertRaises(socket.error, raise_error, "Error raising socket exception.") self.assertRaises(socket.error, raise_herror, "Error raising socket exception.") self.assertRaises(socket.error, raise_gaierror, "Error raising socket exception.") def test_connect_timeout(self): gs = sockets.GreenSocket(socket.AF_INET, socket.SOCK_STREAM) gs.settimeout(0.5) try: gs.connect(('192.0.2.2', 80)) except socket.timeout, e: self.assert_(hasattr(e, 'args')) self.assertEqual(e.args[0], 'timed out') except socket.error, e: # unreachable is also a valid outcome if not get_errno(e) in (errno.EHOSTUNREACH, errno.ENETUNREACH): raise
def accept (self): """ Accepts a new connection from a remote client, and returns a tuple containing that new connection wrapped with a server-side SSL channel, and the address of the remote client. """ # RDW grr duplication of code from greenio if self.act_non_blocking: newsock, addr = socket.accept(self) else: while True: try: newsock, addr = socket.accept(self) set_nonblocking(newsock) break except orig_socket.error, e: if get_errno(e) != errno.EWOULDBLOCK: raise trampoline(self, read = True, timeout = self.gettimeout(), timeout_exc = timeout_exc('timed out'))
def backdoor_server(sock, locals=None): """ Blocking function that runs a backdoor server on the socket *sock*, accepting connections and running backdoor consoles for each client that connects. The *locals* argument is a dictionary that will be included in the locals() of the interpreters. It can be convenient to stick important application variables in here. """ print "backdoor server listening on %s:%s" % sock.getsockname() try: try: while True: socketpair = sock.accept() backdoor(socketpair, locals) except socket.error, e: # Broken pipe means it was shutdown if get_errno(e) != errno.EPIPE: raise finally: sock.close()
def shutdown_safe (sock): """ Shuts down the socket. This is a convenience method for code that wants to gracefully handle regular sockets, SSL.Connection sockets from PyOpenSSL and ssl.SSLSocket objects from Python 2.6 interchangeably. Both types of ssl socket require a shutdown() before close, but they have different arity on their shutdown method. Regular sockets don't need a shutdown before close, but it doesn't hurt. """ try: try: # socket, ssl.SSLSocket return sock.shutdown(socket.SHUT_RDWR) except TypeError: # SSL.Connection return sock.shutdown() except socket.error, e: # we don't care if the socket is already closed; # this will often be the case in an http server context if get_errno(e) != errno.ENOTCONN: raise
def backdoor_server (sock, locals = None): """ Blocking function that runs a backdoor server on the socket *sock*, accepting connections and running backdoor consoles for each client that connects. The *locals* argument is a dictionary that will be included in the locals() of the interpreters. It can be convenient to stick important application variables in here. """ print "backdoor server listening on %s:%s" % sock.getsockname() try: try: while True: socketpair = sock.accept() backdoor(socketpair, locals) except socket.error, e: # Broken pipe means it was shutdown if get_errno(e) != errno.EPIPE: raise finally: sock.close()
def shutdown_safe(sock): """ Shuts down the socket. This is a convenience method for code that wants to gracefully handle regular sockets, SSL.Connection sockets from PyOpenSSL and ssl.SSLSocket objects from Python 2.6 interchangeably. Both types of ssl socket require a shutdown() before close, but they have different arity on their shutdown method. Regular sockets don't need a shutdown before close, but it doesn't hurt. """ try: try: # socket, ssl.SSLSocket return sock.shutdown(socket.SHUT_RDWR) except TypeError: # SSL.Connection return sock.shutdown() except socket.error, e: # we don't care if the socket is already closed; # this will often be the case in an http server context if get_errno(e) != errno.ENOTCONN: raise
def handle_one_request (self): if self.server.max_http_version: self.protocol_version = self.server.max_http_version if self.rfile.closed: self.close_connection = 1 return try: self.raw_requestline = self.rfile.readline(self.server.url_length_limit) if len(self.raw_requestline) == self.server.url_length_limit: self.wfile.write( "HTTP/1.0 414 Request URI Too Long\r\n" "Connection: close\r\nContent-length: 0\r\n\r\n") self.close_connection = 1 return except sockets.SSL.ZeroReturnError: self.raw_requestline = '' except socket.error, e: if get_errno(e) not in BAD_SOCK: raise self.raw_requestline = ''
def handle_one_request(self): if self.server.max_http_version: self.protocol_version = self.server.max_http_version if self.rfile.closed: self.close_connection = 1 return try: self.raw_requestline = self.rfile.readline( self.server.url_length_limit) if len(self.raw_requestline) == self.server.url_length_limit: self.wfile.write( "HTTP/1.0 414 Request URI Too Long\r\n" "Connection: close\r\nContent-length: 0\r\n\r\n") self.close_connection = 1 return except sockets.SSL.ZeroReturnError: self.raw_requestline = '' except socket.error, e: if get_errno(e) not in BAD_SOCK: raise self.raw_requestline = ''
class HttpProtocol(BaseHTTPServer.BaseHTTPRequestHandler): protocol_version = 'HTTP/1.1' minimum_chunk_size = MINIMUM_CHUNK_SIZE def setup(self): # overriding SocketServer.setup to correctly handle SSL.Connection objects conn = self.connection = self.request try: self.rfile = conn.makefile('rb', self.rbufsize) self.wfile = conn.makefile('wb', self.wbufsize) except (AttributeError, NotImplementedError): if hasattr(conn, 'send') and hasattr(conn, 'recv'): # it's an SSL.Connection self.rfile = socket._fileobject(conn, "rb", self.rbufsize) self.wfile = socket._fileobject(conn, "wb", self.wbufsize) else: # it's a SSLObject, or a martian raise NotImplementedError("wsgi.py doesn't support sockets "\ "of type %s" % type(conn)) def handle_one_request(self): if self.server.max_http_version: self.protocol_version = self.server.max_http_version if self.rfile.closed: self.close_connection = 1 return try: self.raw_requestline = self.rfile.readline( self.server.url_length_limit) if len(self.raw_requestline) == self.server.url_length_limit: self.wfile.write( "HTTP/1.0 414 Request URI Too Long\r\n" "Connection: close\r\nContent-length: 0\r\n\r\n") self.close_connection = 1 return except sockets.SSL.ZeroReturnError: self.raw_requestline = '' except socket.error, e: if get_errno(e) not in BAD_SOCK: raise self.raw_requestline = '' if not self.raw_requestline: self.close_connection = 1 return orig_rfile = self.rfile try: self.rfile = FileObjectForHeaders(self.rfile) if not self.parse_request(): return except HeaderLineTooLong: self.wfile.write("HTTP/1.0 400 Header Line Too Long\r\n" "Connection: close\r\nContent-length: 0\r\n\r\n") self.close_connection = 1 return except HeadersTooLarge: self.wfile.write("HTTP/1.0 400 Headers Too Large\r\n" "Connection: close\r\nContent-length: 0\r\n\r\n") self.close_connection = 1 return finally: self.rfile = orig_rfile content_length = self.headers.getheader('content-length') if content_length: try: int(content_length) except ValueError: self.wfile.write( "HTTP/1.0 400 Bad Request\r\n" "Connection: close\r\nContent-length: 0\r\n\r\n") self.close_connection = 1 return self.environ = self.get_environ() self.application = self.server.app try: self.server.outstanding_requests += 1 try: self.handle_one_response() except socket.error, e: # Broken pipe, connection reset by peer if get_errno(e) not in BROKEN_SOCK: raise finally: self.server.outstanding_requests -= 1
serv.log.write("(%s) wsgi starting up on %s://%s%s/\n" % (os.getpid(), scheme, host, port)) while True: try: client_socket = sock.accept() try: pool.spawn_n(serv.process_request, client_socket) except AttributeError: warnings.warn("wsgi's pool should be an instance of "\ "evy.greenpool.GreenPool, is %s. Please convert your"\ " call site to use GreenPool instead" % type(pool), DeprecationWarning, stacklevel = 2) pool.execute_async(serv.process_request, client_socket) except ACCEPT_EXCEPTIONS, e: if get_errno(e) not in ACCEPT_ERRNO: raise except (KeyboardInterrupt, SystemExit): serv.log.write("wsgi exiting\n") break finally: try: # NOTE: It's not clear whether we want this to leave the # socket open or close it. Use cases like Spawning want # the underlying fd to remain open, but if we're going # that far we might as well not bother closing sock at # all. sock.close() except socket.error, e: if get_errno(e) not in BROKEN_SOCK: traceback.print_exc()
def __call__ (self, environ, start_response): if not (environ.get('HTTP_CONNECTION') == 'Upgrade' and environ.get('HTTP_UPGRADE') == 'WebSocket'): # need to check a few more things here for true compliance start_response('400 Bad Request', [('Connection', 'close')]) return [] # See if they sent the new-format headers if 'HTTP_SEC_WEBSOCKET_KEY1' in environ: self.protocol_version = 76 if 'HTTP_SEC_WEBSOCKET_KEY2' not in environ: # That's bad. start_response('400 Bad Request', [('Connection', 'close')]) return [] else: self.protocol_version = 75 # Get the underlying socket and wrap a WebSocket class around it sock = environ['evy.input'].get_socket() ws = WebSocket(sock, environ, self.protocol_version) # If it's new-version, we need to work out our challenge response if self.protocol_version == 76: key1 = self._extract_number(environ['HTTP_SEC_WEBSOCKET_KEY1']) key2 = self._extract_number(environ['HTTP_SEC_WEBSOCKET_KEY2']) # There's no content-length header in the request, but it has 8 # bytes of data. environ['wsgi.input'].content_length = 8 key3 = environ['wsgi.input'].read(8) key = struct.pack(">II", key1, key2) + key3 response = md5(key).digest() # Start building the response scheme = 'ws' if environ.get('wsgi.url_scheme') == 'https': scheme = 'wss' location = '%s://%s%s%s' % ( scheme, environ.get('HTTP_HOST'), environ.get('SCRIPT_NAME'), environ.get('PATH_INFO') ) qs = environ.get('QUERY_STRING') if qs is not None: location += '?' + qs if self.protocol_version == 75: handshake_reply = ("HTTP/1.1 101 Web Socket Protocol Handshake\r\n" "Upgrade: WebSocket\r\n" "Connection: Upgrade\r\n" "WebSocket-Origin: %s\r\n" "WebSocket-Location: %s\r\n\r\n" % ( environ.get('HTTP_ORIGIN'), location)) elif self.protocol_version == 76: handshake_reply = ("HTTP/1.1 101 WebSocket Protocol Handshake\r\n" "Upgrade: WebSocket\r\n" "Connection: Upgrade\r\n" "Sec-WebSocket-Origin: %s\r\n" "Sec-WebSocket-Protocol: %s\r\n" "Sec-WebSocket-Location: %s\r\n" "\r\n%s" % ( environ.get('HTTP_ORIGIN'), environ.get('HTTP_SEC_WEBSOCKET_PROTOCOL', 'default'), location, response)) else: #pragma NO COVER raise ValueError("Unknown WebSocket protocol version.") sock.sendall(handshake_reply) try: self.handler(ws) except socket.error, e: if get_errno(e) not in ACCEPTABLE_CLIENT_ERRORS: raise
except (socket.timeout, Timeout): return errno.ETIME except pyuv.error.TCPError, e: raise socket.error(*last_socket_error(e.args[0], msg = 'connect error')) except Exception, e: code = e.args[0] return code else: fd = self.uv_fd if self.gettimeout() is None: while not socket_connect(fd, address): try: trampoline(fd, write = True) socket_checkerr(fd) except socket.error, ex: return get_errno(ex) else: end = time.time() + self.gettimeout() while True: try: if socket_connect(fd, address): return 0 if time.time() >= end: raise socket.timeout(errno.EAGAIN) wait_write(fd, end - time.time(), socket.timeout(errno.EAGAIN)) socket_checkerr(fd) except socket.error, ex: return get_errno(ex) def ioctl (self, *args): self.uv_fd.ioctl(*args)
def server (sock, site, log = None, environ = None, max_size = None, max_http_version = DEFAULT_MAX_HTTP_VERSION, protocol = HttpProtocol, server_event = None, minimum_chunk_size = None, log_x_forwarded_for = True, custom_pool = None, keepalive = True, log_output = True, log_format = DEFAULT_LOG_FORMAT, url_length_limit = MAX_REQUEST_LINE, debug = True): """ Start up a wsgi server handling requests from the supplied server socket. This function loops forever. The *sock* object will be closed after server exits, but the underlying file descriptor will remain open, so if you have a dup() of *sock*, it will remain usable. :param sock: Server socket, must be already bound to a port and listening. :param site: WSGI application function. :param log: File-like object that logs should be written to. If not specified, sys.stderr is used. :param environ: Additional parameters that go into the environ dictionary of every request. :param max_size: Maximum number of client connections opened at any time by this server. :param max_http_version: Set to "HTTP/1.0" to make the server pretend it only supports HTTP 1.0. This can help with applications or clients that don't behave properly using HTTP 1.1. :param protocol: Protocol class. Deprecated. :param server_event: Used to collect the Server object. Deprecated. :param minimum_chunk_size: Minimum size in bytes for http chunks. This can be used to improve performance of applications which yield many small strings, though using it technically violates the WSGI spec. :param log_x_forwarded_for: If True (the default), logs the contents of the x-forwarded-for header in addition to the actual client ip address in the 'client_ip' field of the log line. :param custom_pool: A custom GreenPool instance which is used to spawn client green threads. If this is supplied, max_size is ignored. :param keepalive: If set to False, disables keepalives on the server; all connections will be closed after serving one request. :param log_output: A Boolean indicating if the server will log data or not. :param log_format: A python format string that is used as the template to generate log lines. The following values can be formatted into it: client_ip, date_time, request_line, status_code, body_length, wall_seconds. The default is a good example of how to use it. :param url_length_limit: A maximum allowed length of the request url. If exceeded, 414 error is returned. :param debug: True if the server should send exception tracebacks to the clients on 500 errors. If False, the server will respond with empty bodies. """ serv = Server(sock, sock.getsockname(), site, log, environ = environ, max_http_version = max_http_version, protocol = protocol, minimum_chunk_size = minimum_chunk_size, log_x_forwarded_for = log_x_forwarded_for, keepalive = keepalive, log_output = log_output, log_format = log_format, url_length_limit = url_length_limit, debug = debug) if server_event is not None: server_event.send(serv) if max_size is None: max_size = DEFAULT_MAX_SIMULTANEOUS_REQUESTS if custom_pool is not None: pool = custom_pool else: pool = GreenPool(max_size) try: host, port = sock.getsockname()[:2] port = ':%s' % (port, ) if hasattr(sock, 'do_handshake'): scheme = 'https' if port == ':443': port = '' else: scheme = 'http' if port == ':80': port = '' serv.log.write("(%s) wsgi starting up on %s://%s%s/\n" % ( os.getpid(), scheme, host, port)) while True: try: client_socket = sock.accept() try: pool.spawn_n(serv.process_request, client_socket) except AttributeError: warnings.warn("wsgi's pool should be an instance of "\ "evy.greenpool.GreenPool, is %s. Please convert your"\ " call site to use GreenPool instead" % type(pool), DeprecationWarning, stacklevel = 2) pool.execute_async(serv.process_request, client_socket) except ACCEPT_EXCEPTIONS, e: if get_errno(e) not in ACCEPT_ERRNO: raise except (KeyboardInterrupt, SystemExit): serv.log.write("wsgi exiting\n") break
def server(sock, site, log=None, environ=None, max_size=None, max_http_version=DEFAULT_MAX_HTTP_VERSION, protocol=HttpProtocol, server_event=None, minimum_chunk_size=None, log_x_forwarded_for=True, custom_pool=None, keepalive=True, log_output=True, log_format=DEFAULT_LOG_FORMAT, url_length_limit=MAX_REQUEST_LINE, debug=True): """ Start up a wsgi server handling requests from the supplied server socket. This function loops forever. The *sock* object will be closed after server exits, but the underlying file descriptor will remain open, so if you have a dup() of *sock*, it will remain usable. :param sock: Server socket, must be already bound to a port and listening. :param site: WSGI application function. :param log: File-like object that logs should be written to. If not specified, sys.stderr is used. :param environ: Additional parameters that go into the environ dictionary of every request. :param max_size: Maximum number of client connections opened at any time by this server. :param max_http_version: Set to "HTTP/1.0" to make the server pretend it only supports HTTP 1.0. This can help with applications or clients that don't behave properly using HTTP 1.1. :param protocol: Protocol class. Deprecated. :param server_event: Used to collect the Server object. Deprecated. :param minimum_chunk_size: Minimum size in bytes for http chunks. This can be used to improve performance of applications which yield many small strings, though using it technically violates the WSGI spec. :param log_x_forwarded_for: If True (the default), logs the contents of the x-forwarded-for header in addition to the actual client ip address in the 'client_ip' field of the log line. :param custom_pool: A custom GreenPool instance which is used to spawn client green threads. If this is supplied, max_size is ignored. :param keepalive: If set to False, disables keepalives on the server; all connections will be closed after serving one request. :param log_output: A Boolean indicating if the server will log data or not. :param log_format: A python format string that is used as the template to generate log lines. The following values can be formatted into it: client_ip, date_time, request_line, status_code, body_length, wall_seconds. The default is a good example of how to use it. :param url_length_limit: A maximum allowed length of the request url. If exceeded, 414 error is returned. :param debug: True if the server should send exception tracebacks to the clients on 500 errors. If False, the server will respond with empty bodies. """ serv = Server(sock, sock.getsockname(), site, log, environ=environ, max_http_version=max_http_version, protocol=protocol, minimum_chunk_size=minimum_chunk_size, log_x_forwarded_for=log_x_forwarded_for, keepalive=keepalive, log_output=log_output, log_format=log_format, url_length_limit=url_length_limit, debug=debug) if server_event is not None: server_event.send(serv) if max_size is None: max_size = DEFAULT_MAX_SIMULTANEOUS_REQUESTS if custom_pool is not None: pool = custom_pool else: pool = GreenPool(max_size) try: host, port = sock.getsockname()[:2] port = ':%s' % (port, ) if hasattr(sock, 'do_handshake'): scheme = 'https' if port == ':443': port = '' else: scheme = 'http' if port == ':80': port = '' serv.log.write("(%s) wsgi starting up on %s://%s%s/\n" % (os.getpid(), scheme, host, port)) while True: try: client_socket = sock.accept() try: pool.spawn_n(serv.process_request, client_socket) except AttributeError: warnings.warn("wsgi's pool should be an instance of "\ "evy.greenpool.GreenPool, is %s. Please convert your"\ " call site to use GreenPool instead" % type(pool), DeprecationWarning, stacklevel = 2) pool.execute_async(serv.process_request, client_socket) except ACCEPT_EXCEPTIONS, e: if get_errno(e) not in ACCEPT_ERRNO: raise except (KeyboardInterrupt, SystemExit): serv.log.write("wsgi exiting\n") break
return errno.ETIME except pyuv.error.TCPError, e: raise socket.error( *last_socket_error(e.args[0], msg='connect error')) except Exception, e: code = e.args[0] return code else: fd = self.uv_fd if self.gettimeout() is None: while not socket_connect(fd, address): try: trampoline(fd, write=True) socket_checkerr(fd) except socket.error, ex: return get_errno(ex) else: end = time.time() + self.gettimeout() while True: try: if socket_connect(fd, address): return 0 if time.time() >= end: raise socket.timeout(errno.EAGAIN) wait_write(fd, end - time.time(), socket.timeout(errno.EAGAIN)) socket_checkerr(fd) except socket.error, ex: return get_errno(ex) def ioctl(self, *args):
serv.log.write("(%s) wsgi starting up on %s://%s%s/\n" % ( os.getpid(), scheme, host, port)) while True: try: client_socket = sock.accept() try: pool.spawn_n(serv.process_request, client_socket) except AttributeError: warnings.warn("wsgi's pool should be an instance of "\ "evy.greenpool.GreenPool, is %s. Please convert your"\ " call site to use GreenPool instead" % type(pool), DeprecationWarning, stacklevel = 2) pool.execute_async(serv.process_request, client_socket) except ACCEPT_EXCEPTIONS, e: if get_errno(e) not in ACCEPT_ERRNO: raise except (KeyboardInterrupt, SystemExit): serv.log.write("wsgi exiting\n") break finally: try: # NOTE: It's not clear whether we want this to leave the # socket open or close it. Use cases like Spawning want # the underlying fd to remain open, but if we're going # that far we might as well not bother closing sock at # all. sock.close() except socket.error, e: if get_errno(e) not in BROKEN_SOCK: traceback.print_exc()
len_data = len(data) os_write = _os_orig.write fileno = self._fileno try: total_sent = os_write(fileno, data) except OSError, e: if get_errno(e) != errno.EAGAIN: raise IOError(*e.args) total_sent = 0 while total_sent < len_data: wait_write(self) try: total_sent += os_write(fileno, data[total_sent:]) except OSError, e: if get_errno(e) != errno. EAGAIN: raise IOError(*e.args) def __del__ (self): try: _os_orig.close(self._fileno) except: # os.close may fail if __init__ didn't complete (i.e file dscriptor passed to popen was invalid pass def __repr__ (self): return "%s:%d" % (self.__class__.__name__, self._fileno)
try: return real_connect(self, addr) except orig_socket.error, exc: if get_errno(exc) in CONNECT_ERR: trampoline(self, write = True) elif get_errno(exc) in CONNECT_SUCCESS: return else: raise else: end = time.time() + self.gettimeout() while True: try: real_connect(self, addr) except orig_socket.error, exc: if get_errno(exc) in CONNECT_ERR: trampoline(self, write = True, timeout = end - time.time(), timeout_exc = timeout_exc('timed out')) elif get_errno(exc) in CONNECT_SUCCESS: return else: raise if time.time() >= end: raise timeout_exc('timed out') def connect (self, addr): """ Connects to remote ADDR, and then wraps the connection in an SSL channel."""