Beispiel #1
0
def bind(address, sock_type):
    family, addr = addrinfo(address)
    if isinstance(addr, int):
        _sock = _socket.fromfd(addr, family, sock_type)
        _sock.setblocking(0)
        activated = 1
    else:
        _sock = _socket.socket(family, sock_type)
        _sock.setblocking(0)
        activated = 0
        if _socket.AF_INET6 == family and '::' == addr[0]:
            _sock.setsockopt(_socket.IPPROTO_IPV6, _socket.IPV6_V6ONLY, 0)
        _sock.setsockopt(_socket.SOL_SOCKET, _socket.SO_REUSEADDR, 1)
        _sock.bind(addr)
    server_address = _sock.getsockname()
    if isinstance(server_address, tuple):
        host, server_port = server_address
        server_name = getfqdn(host)
    else:
        server_port = server_name = None
    return {'server_address': server_address,
            'server_name'   : server_name,
            'server_port'   : server_port,
            'sock_family'   : family,
            'sock_type'     : sock_type,
            'activated'     : activated,
            '_sock'         : _sock}
Beispiel #2
0
 def setup(self, addr, bind_and_activate=True):
     addr, family = addrinfo(addr)
     if isinstance(addr, int):
         self.socket = fromfd(addr, family, SOCK_STREAM)
         self.require_bind_and_activate = False
         self.family = family
         try:
             self.server_address = self.socket.getsockname()
             host, self.server_port = self.server_address
             self.server_name = getfqdn(host)
         except:
             pass
     elif 2 == len(addr):
         self.socket = realsocket(family, SOCK_STREAM)
         if AF_INET6 == family and addr[0] == '::':
             if hasattr(_socket, 'IPV6_V6ONLY'):
                 self.socket.setsockopt \
                     (IPPROTO_IPV6, _socket.IPV6_V6ONLY, 0)
         self.require_bind_and_activate = True
         self.server_address = addr
         self.server_name = getfqdn(addr[0])
         self.server_port = addr[1]
         self.family = family
         self.server_bind()
         self.server_activate()
     else:
         self.socket = realsocket(family, SOCK_STREAM)
         self.require_bind_and_activate = True
         self.server_address = addr
         self.family = family
         self.server_bind()
         self.server_activate()
     self.r_event = Io(self.socket.fileno(), EV_READ, loop,
                       self._handle_request, self)
Beispiel #3
0
 def from_file_descriptor(cls,
                          fd,
                          socket_family=_socket.AF_UNIX,
                          socket_type=_socket.SOCK_STREAM,
                          socket_state=STATE_INIT):
     return cls(_socket.fromfd(fd, socket_family, socket_type),
                socket_state)
Beispiel #4
0
 def setup(self, addr, bind_and_activate=True):
     addr, family = addrinfo(addr)
     if isinstance(addr, int):
         self.socket = fromfd(addr, family, SOCK_STREAM)
         self.require_bind_and_activate = False
         self.family = family
         try:
             self.server_address = self.socket.getsockname()
             host, self.server_port = self.server_address
             self.server_name = getfqdn(host)
         except:
             pass
     elif 2 == len(addr):
         self.socket = realsocket(family, SOCK_STREAM)
         if AF_INET6 == family and addr[0] == '::':
             if hasattr(_socket, 'IPV6_V6ONLY'):
                 self.socket.setsockopt \
                     (IPPROTO_IPV6, _socket.IPV6_V6ONLY, 0)
         self.require_bind_and_activate = True
         self.server_address = addr
         self.server_name = getfqdn(addr[0])
         self.server_port = addr[1]
         self.family = family
         self.server_bind()
         self.server_activate()
     else:
         self.socket = realsocket(family, SOCK_STREAM)
         self.require_bind_and_activate = True
         self.server_address = addr
         self.family = family
         self.server_bind()
         self.server_activate()
     self.r_event = Io(self.socket.fileno() , EV_READ , loop,
         self._handle_request, self)
Beispiel #5
0
def fromfd(*args):
    return socket(_sock=_socket.fromfd(*args))
Beispiel #6
0
 def fromfd(*args):
     return socket(_sock=_socket.fromfd(*args))
Beispiel #7
0
 def from_file_descriptor(cls, fd, socket_family = _socket.AF_UNIX, socket_type = _socket.SOCK_STREAM, socket_state = STATE_INIT):
     return cls(_socket.fromfd(fd, socket_family, socket_type), socket_state)
Beispiel #8
0
def worker_main():
    global PREFIX
    PREFIX = '[W%05d] ' % os.getpid()
    import optparse
    parser = optparse.OptionParser()
    parser.add_option('--fileno', type=int)
    parser.add_option('--pipe', type=int)
    parser.add_option('-u', '--user')
    parser.add_option('-s', '--server-class', default='wsgi')
    parser.add_option('--preexec')
    parser.add_option('--pythonpath',
                      help='Colon-separated entries to prepend to sys.path')
    parser.add_option('--setuid', type=int)
    parser.add_option('--setgid', type=int)
    parser.add_option('--maxaccept', type=int)
    parser.add_option('--notify-period', type=float)
    options, args = parser.parse_args()
    if args:
        if len(args) > 1:
            sys.exit('Too many arguments. Expected at most one: application')
        application_name = args[0]
    else:
        application_name = None
    server_class = server_classes.get(options.server_class,
                                      options.server_class)
    if server_class in server_classes.values():
        if application_name is None:
            sys.exit('Expected argument: application or handler')

    if options.pipe:
        fcntl.fcntl(options.pipe, fcntl.F_SETFL, os.O_NONBLOCK)

    if options.pythonpath:
        sys.path = options.pythonpath.split(':') + sys.path

    import _socket
    socket = _socket.fromfd(options.fileno, _socket.AF_INET,
                            _socket.SOCK_STREAM)
    # _socket.fromfd dups the file descriptor; it does not seem possible to avoid it
    # therefore close the old filenot that we no longer need
    os.close(options.fileno)
    del options.fileno

    import geventserver
    geventserver.socket = socket

    from gevent.hub import _import

    if options.preexec:
        preexec = _import(options.preexec)
        preexec()

    socket_txt = ':'.join(str(x) for x in socket.getsockname())
    setproctitle('geventserver worker', options.server_class, socket_txt,
                 application_name)

    drop_privileges(options.setuid, options.setgid)

    # master must always outlive its workers; if the master died, something
    # awful happened and SIGKILL for worker is warranted
    # Note, that die_if_parent_dies must be called after dropping privileges,
    # otherwise it does not work
    die_if_parent_dies(signal.SIGKILL)
    ppid = os.getppid()
    if ppid == 1:
        sys.exit(PREFIX + 'ppid cannot be 1')

    _reseed_random()

    from gevent import monkey
    monkey.patch_all()

    geventserver.quit_handler = gevent.signal(signal.SIGQUIT,
                                              worker_handle_quit, None)

    signal.signal(signal.SIGTERM, worker_handle_term)
    signal.signal(signal.SIGINT, worker_handle_int)
    # signal handlers are installed before importing user code so that imported modules could override signals

    geventserver.looptimer = LoopTimer()

    server_class = _import(options.server_class)
    if application_name:
        application = _import(application_name)
        args = (socket, application)
    else:
        application = None
        args = (socket, )

    server = server_class(*args)
    if options.maxaccept:
        # XXX unused currently?
        server.max_accept = options.max_accept

    geventserver.server = server

    server.start()
    geventserver.quit_handler.args = (server, )

    log('Serving %s', application_name or options.server_class)

    if callable(getattr(application, 'on_start', None)):
        application.on_start()

    if options.pipe is not None:
        gevent.get_hub().loop.timer(0, options.notify_period,
                                    ref=False).start(write_pipe, options.pipe)

    try:
        gevent.wait()
    except Interrupt:
        sys.exit(102)  # 100 + SIGINT
    else:
        log('Exiting cleanly.')
Beispiel #9
0
def Sockets(addresses, **args):
	ssl_private_key = args.get('ssl_private_key', args.get('key_file' ))
	ssl_certificate = args.get('ssl_certificate', args.get('cert_file'))

	ssl = ssl_certificate and ssl_private_key
	if ssl:
		if not SSL:
			raise ImportError('you must install pyOpenSSL to use https')

		ctx = SSLContext(SSLv23_METHOD)
		ctx.use_privatekey_file(ssl_private_key)
		ctx.use_certificate_file(ssl_certificate)

		cert = load_certificate(FILETYPE_PEM, open(ssl_certificate, 'rb').read())
		base_environ = dict(HTTPS='on', SSL_SERVER_M_SERIAL  = cert.get_serial_number(),
		                                SSL_SERVER_M_VERSION = cert.get_version())

		for prefix, dn in [("I", cert.get_issuer()), ("S", cert.get_subject())]:
			dnstr = str(dn)[18:-2]
			wsgikey = 'SSL_SERVER_%s_DN' %prefix
			base_environ[wsgikey] = dnstr
			while dnstr:
				pos = dnstr.rfind('=')
				dnstr, value = dnstr[:pos], dnstr[pos + 1:]
				pos = dnstr.rfind('/')
				dnstr, key = dnstr[:pos], dnstr[pos + 1:]
				if key and value:
					wsgikey = 'SSL_SERVER_%s_DN_%s' % (prefix, key)
					base_environ[wsgikey] = value

		socket_func = lambda family, socktype: \
			SSL(SSLConnection(ctx, Socket(family, socktype)))
		fromfd_func = lambda fileno, family, socktype: \
			SSL(SSLConnection(ctx, fromfd(fileno, family, socktype)))
	else:
		fromfd_func, socket_func, base_environ = fromfd, Socket, {}

	if isinstance(addresses, basestring):
		addresses, addrs = [], [i for i in str(addresses).split(',') if i.strip()]
		for addr in addrs:
			is_ipv6 = R_IPV6(addr)
			if is_ipv6:
				addresses.append((AF_INET6, is_ipv6.groups()))
				continue

			seq = [i.strip() for i in addr.split(':')]
			if len(seq) == 2:
				if seq[0].lower() in ('fromfd', 'fileno'):
					addresses.append((AF_INET, int(seq[1])))
					continue

				addresses.append((AF_INET, seq))
				continue

			if len(seq) == 3 and seq[0].lower() in ('fromfd', 'fileno'):
				family = seq[1].lower()
				if   family in ('inet', 'af_inet', 'ipv4'):
					addresses.append((AF_INET, int(seq[2])))
					continue

				elif family in ('inet6', 'af_inet6', 'ipv6', '6'):
					addresses.append((AF_INET, int(seq[2])))
					continue

				elif family in ('unix', 'af_unix', 's', 'socket',
				           'unix_socket', 'unixsocket', 'unixsock'):

					addresses.append((_socket.AF_UNIX, int(seq[2])))
					continue

			addresses.append((_socket.AF_UNIX, addr.strip()))
	else:
		addresses, addrs = [], addresses
		for addr in addrs:
			if isinstance(addr, (int, long)):
				addresses.append((AF_INET, addr))
				continue

			if isinstance(addr, (list, tuple)) and len(addr) == 2:
				if isinstance(addr[0], (int, long)):
					address.append(addr)
					continue

				if isinstance(addr[0], basestring):
					addresses.append((AF_INET6, addr) if ':' in addr[0] \
					            else (AF_INET , addr))
					continue

			if isinstance(addr, basestring):
				addresses.append((_socket.AF_UNIX, addr))
				continue

			raise ValueError('bad address %r' %addr)

	sockets = []
	for family, addr in addresses:
		if isinstance(addr, (int, long)):
			sock = fromfd_func(addr, family, SOCK_STREAM)
			sock.setblocking(0)

			environ = dict(SERVER_NAME='fileno:%d' %addr, SERVER_PORT='')
			environ.update(base_environ)

			sockets.append((sock, environ))
			continue

		if family == AF_UNIX:
			sock = socket_func(_socket.AF_UNIX, SOCK_STREAM)
			sock.setblocking(0)
			try:
				sock.bind(addr)

			except SocketError, address_already_in_use:
				if address_already_in_use.args[0] != 98:
					raise

				ping = socket_func(_socket.AF_UNIX, SOCK_STREAM)
				try:
					ping.connect(addr)
				except SocketError, e:
					if e.args[0] == 111:
						os.unlink(addr)
						sock.bind(addr)
				else:
					ping.close()
					raise address_already_in_use

			sock.listen(4194304)

			environ = dict(SERVER_NAME='s:%s' %addr, SERVER_PORT='')
			environ.update(base_environ)

			sockets.append((sock, environ))
			continue
Beispiel #10
0
def worker_main():
    global PREFIX
    PREFIX = "[W%05d] " % os.getpid()
    import optparse

    parser = optparse.OptionParser()
    parser.add_option("--fileno", type=int)
    parser.add_option("--pipe", type=int)
    parser.add_option("-u", "--user")
    parser.add_option("-s", "--server-class", default="wsgi")
    parser.add_option("--preexec")
    parser.add_option("--pythonpath", help="Colon-separated entries to prepend to sys.path")
    parser.add_option("--setuid", type=int)
    parser.add_option("--setgid", type=int)
    parser.add_option("--maxaccept", type=int)
    parser.add_option("--notify-period", type=float)
    options, args = parser.parse_args()
    if args:
        if len(args) > 1:
            sys.exit("Too many arguments. Expected at most one: application")
        application_name = args[0]
    else:
        application_name = None
    server_class = server_classes.get(options.server_class, options.server_class)
    if server_class in server_classes.values():
        if application_name is None:
            sys.exit("Expected argument: application or handler")

    if options.pipe:
        fcntl.fcntl(options.pipe, fcntl.F_SETFL, os.O_NONBLOCK)

    if options.pythonpath:
        sys.path = options.pythonpath.split(":") + sys.path

    import _socket

    socket = _socket.fromfd(options.fileno, _socket.AF_INET, _socket.SOCK_STREAM)
    # _socket.fromfd dups the file descriptor; it does not seem possible to avoid it
    # therefore close the old filenot that we no longer need
    os.close(options.fileno)
    del options.fileno

    import geventserver

    geventserver.socket = socket

    from gevent.hub import _import

    if options.preexec:
        preexec = _import(options.preexec)
        preexec()

    socket_txt = ":".join(str(x) for x in socket.getsockname())
    setproctitle("geventserver worker", options.server_class, socket_txt, application_name)

    drop_privileges(options.setuid, options.setgid)

    # master must always outlive its workers; if the master died, something
    # awful happened and SIGKILL for worker is warranted
    # Note, that die_if_parent_dies must be called after dropping privileges,
    # otherwise it does not work
    die_if_parent_dies(signal.SIGKILL)
    ppid = os.getppid()
    if ppid == 1:
        sys.exit(PREFIX + "ppid cannot be 1")

    _reseed_random()

    from gevent import monkey

    monkey.patch_all()

    geventserver.quit_handler = gevent.signal(signal.SIGQUIT, worker_handle_quit, None)

    signal.signal(signal.SIGTERM, worker_handle_term)
    signal.signal(signal.SIGINT, worker_handle_int)
    # signal handlers are installed before importing user code so that imported modules could override signals

    geventserver.looptimer = LoopTimer()

    server_class = _import(options.server_class)
    if application_name:
        application = _import(application_name)
        args = (socket, application)
    else:
        application = None
        args = (socket,)

    server = server_class(*args)
    if options.maxaccept:
        # XXX unused currently?
        server.max_accept = options.max_accept

    geventserver.server = server

    server.start()
    geventserver.quit_handler.args = (server,)

    log("Serving %s", application_name or options.server_class)

    if callable(getattr(application, "on_start", None)):
        application.on_start()

    if options.pipe is not None:
        gevent.get_hub().loop.timer(0, options.notify_period, ref=False).start(write_pipe, options.pipe)

    try:
        gevent.wait()
    except Interrupt:
        sys.exit(102)  # 100 + SIGINT
    else:
        log("Exiting cleanly.")
Beispiel #11
0
def Sockets(addresses, **args):
    ssl_private_key = args.get('ssl_private_key', args.get('key_file'))
    ssl_certificate = args.get('ssl_certificate', args.get('cert_file'))

    ssl = ssl_certificate and ssl_private_key
    if ssl:
        if not SSL:
            raise ImportError('you must install pyOpenSSL to use https')

        ctx = SSLContext(SSLv23_METHOD)
        ctx.use_privatekey_file(ssl_private_key)
        ctx.use_certificate_file(ssl_certificate)

        cert = load_certificate(FILETYPE_PEM,
                                open(ssl_certificate, 'rb').read())
        base_environ = dict(HTTPS='on',
                            SSL_SERVER_M_SERIAL=cert.get_serial_number(),
                            SSL_SERVER_M_VERSION=cert.get_version())

        for prefix, dn in [("I", cert.get_issuer()),
                           ("S", cert.get_subject())]:
            dnstr = str(dn)[18:-2]
            wsgikey = 'SSL_SERVER_%s_DN' % prefix
            base_environ[wsgikey] = dnstr
            while dnstr:
                pos = dnstr.rfind('=')
                dnstr, value = dnstr[:pos], dnstr[pos + 1:]
                pos = dnstr.rfind('/')
                dnstr, key = dnstr[:pos], dnstr[pos + 1:]
                if key and value:
                    wsgikey = 'SSL_SERVER_%s_DN_%s' % (prefix, key)
                    base_environ[wsgikey] = value

        socket_func = lambda family, socktype: \
         SSL(SSLConnection(ctx, Socket(family, socktype)))
        fromfd_func = lambda fileno, family, socktype: \
         SSL(SSLConnection(ctx, fromfd(fileno, family, socktype)))
    else:
        fromfd_func, socket_func, base_environ = fromfd, Socket, {}

    if isinstance(addresses, basestring):
        addresses, addrs = [], [
            i for i in str(addresses).split(',') if i.strip()
        ]
        for addr in addrs:
            is_ipv6 = R_IPV6(addr)
            if is_ipv6:
                addresses.append((AF_INET6, is_ipv6.groups()))
                continue

            seq = [i.strip() for i in addr.split(':')]
            if len(seq) == 2:
                if seq[0].lower() in ('fromfd', 'fileno'):
                    addresses.append((AF_INET, int(seq[1])))
                    continue

                addresses.append((AF_INET, seq))
                continue

            if len(seq) == 3 and seq[0].lower() in ('fromfd', 'fileno'):
                family = seq[1].lower()
                if family in ('inet', 'af_inet', 'ipv4'):
                    addresses.append((AF_INET, int(seq[2])))
                    continue

                elif family in ('inet6', 'af_inet6', 'ipv6', '6'):
                    addresses.append((AF_INET, int(seq[2])))
                    continue

                elif family in ('unix', 'af_unix', 's', 'socket',
                                'unix_socket', 'unixsocket', 'unixsock'):

                    addresses.append((_socket.AF_UNIX, int(seq[2])))
                    continue

            addresses.append((_socket.AF_UNIX, addr.strip()))
    else:
        addresses, addrs = [], addresses
        for addr in addrs:
            if isinstance(addr, (int, long)):
                addresses.append((AF_INET, addr))
                continue

            if isinstance(addr, (list, tuple)) and len(addr) == 2:
                if isinstance(addr[0], (int, long)):
                    address.append(addr)
                    continue

                if isinstance(addr[0], basestring):
                    addresses.append((AF_INET6, addr) if ':' in addr[0] \
                                else (AF_INET , addr))
                    continue

            if isinstance(addr, basestring):
                addresses.append((_socket.AF_UNIX, addr))
                continue

            raise ValueError('bad address %r' % addr)

    sockets = []
    for family, addr in addresses:
        if isinstance(addr, (int, long)):
            sock = fromfd_func(addr, family, SOCK_STREAM)
            sock.setblocking(0)

            environ = dict(SERVER_NAME='fileno:%d' % addr, SERVER_PORT='')
            environ.update(base_environ)

            sockets.append((sock, environ))
            continue

        if family == AF_UNIX:
            sock = socket_func(_socket.AF_UNIX, SOCK_STREAM)
            sock.setblocking(0)
            try:
                sock.bind(addr)

            except SocketError, address_already_in_use:
                if address_already_in_use.args[0] != 98:
                    raise

                ping = socket_func(_socket.AF_UNIX, SOCK_STREAM)
                try:
                    ping.connect(addr)
                except SocketError, e:
                    if e.args[0] == 111:
                        os.unlink(addr)
                        sock.bind(addr)
                else:
                    ping.close()
                    raise address_already_in_use

            sock.listen(4194304)

            environ = dict(SERVER_NAME='s:%s' % addr, SERVER_PORT='')
            environ.update(base_environ)

            sockets.append((sock, environ))
            continue