コード例 #1
0
ファイル: ssl.py プロジェクト: inercia/evy
 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
コード例 #2
0
ファイル: os.py プロジェクト: inercia/evy
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
コード例 #3
0
ファイル: os.py プロジェクト: PlumpMath/evy
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
コード例 #4
0
ファイル: os.py プロジェクト: inercia/evy
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
コード例 #5
0
ファイル: os.py プロジェクト: PlumpMath/evy
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
コード例 #6
0
ファイル: test_green_socket.py プロジェクト: inercia/evy
 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
コード例 #7
0
 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)
コード例 #8
0
 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
コード例 #9
0
ファイル: ssl.py プロジェクト: inercia/evy
 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:
コード例 #10
0
ファイル: test_green_socket.py プロジェクト: inercia/evy
 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
コード例 #11
0
 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
コード例 #12
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
コード例 #13
0
ファイル: ssl.py プロジェクト: inercia/evy
 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
コード例 #14
0
ファイル: SSL.py プロジェクト: PlumpMath/evy
 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 ''
コード例 #15
0
ファイル: utils.py プロジェクト: inercia/evy
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
コード例 #16
0
ファイル: SSL.py プロジェクト: inercia/evy
 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 ''
コード例 #17
0
ファイル: utils.py プロジェクト: PlumpMath/evy
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
コード例 #18
0
ファイル: ssl.py プロジェクト: inercia/evy
 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
コード例 #19
0
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
コード例 #20
0
ファイル: ssl.py プロジェクト: inercia/evy
 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'))
コード例 #21
0
ファイル: backdoor.py プロジェクト: PlumpMath/evy
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()
コード例 #22
0
ファイル: sockets.py プロジェクト: inercia/evy
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
コード例 #23
0
ファイル: backdoor.py プロジェクト: inercia/evy
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()
コード例 #24
0
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
コード例 #25
0
ファイル: wsgi.py プロジェクト: inercia/evy
    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 = ''
コード例 #26
0
    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 = ''
コード例 #27
0
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
コード例 #28
0
        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()
コード例 #29
0
ファイル: websocket.py プロジェクト: inercia/evy
    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
コード例 #30
0
ファイル: sockets.py プロジェクト: inercia/evy
            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)
コード例 #31
0
ファイル: wsgi.py プロジェクト: inercia/evy
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
コード例 #32
0
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
コード例 #33
0
                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):
コード例 #34
0
ファイル: wsgi.py プロジェクト: inercia/evy
        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()
コード例 #35
0
        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)



コード例 #36
0
ファイル: ssl.py プロジェクト: inercia/evy
                    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."""