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}
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)
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)
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)
def fromfd(*args): return socket(_sock=_socket.fromfd(*args))
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)
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.')
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
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.")
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