def file_header(code, size, protocol='1.1'): date = time.strftime('%c %Z') version = load().proxy.version return '\r\n'.join([ 'HTTP/%s %s %s' % (protocol, str(code), _HTTP_NAMES.get(code, '-')), 'Date: %s' % date, 'Server: exaproxy/%s (%s)' % (str(version), str(sys.platform)), 'Content-Length: %d' % size, 'Connection: close', 'Content-Type: text/html', 'Cache-Control: no-store', 'Pragma: no-cache', '' ])
def http(code, message, protocol='1.1'): encoding = 'html' if message[:5].lower().startswith('<html') else 'plain' date = time.strftime('%c %Z') version = load().proxy.version return '\r\n'.join([ 'HTTP/%s %s %s' % (protocol, str(code), _HTTP_NAMES.get(code, '-')), 'Date: %s' % date, 'Server: exaproxy/%s (%s)' % (str(version), str(sys.platform)), 'Content-Length: %d' % len(message), 'Content-Type: text/%s' % encoding, 'Cache-Control: no-store', 'Pragma: no-cache', '', message ])
def file_header(code, size, name, protocol='1.1'): date = time.strftime('%c %Z') version = load().proxy.version return '\r\n'.join([ 'HTTP/%s %s %s' % (protocol, str(code), _HTTP_NAMES.get(code,'-')), 'Date: %s' % date, 'Server: exaproxy/%s (%s)' % (str(version), str(sys.platform)), 'Content-Length: %d' % size, 'Connection: close', 'Content-Type: text/html', 'Cache-Control: no-store', 'Pragma: no-cache', '' ])
def http (code,message, protocol='1.1'): encoding = 'html' if message[:5].lower().startswith('<html') else 'plain' date = time.strftime('%c %Z') version = load().proxy.version return '\r\n'.join([ 'HTTP/%s %s %s' % (protocol, str(code), _HTTP_NAMES.get(code,'-')), 'Date: %s' % date, 'Server: exaproxy/%s (%s)' % (str(version), str(sys.platform)), 'Content-Length: %d' % len(message), 'Content-Type: text/%s' % encoding, 'Cache-Control: no-store', 'Pragma: no-cache', '', message ])
# encoding: utf-8 """ async/__init__.py Created by David Farrar on 2012-01-31. Copyright (c) 2011-2013 Exa Networks. All rights reserved. """ import sys import select from exaproxy.util.log.logger import Logger from exaproxy.configuration import load configuration = load() log = Logger('supervisor', configuration.log.supervisor) def Poller(configuration, speed=None): reactor = configuration.reactor if reactor == 'best': if sys.platform.startswith('linux'): configuration.reactor = 'epoll' elif sys.platform.startswith('freebsd'): configuration.reactor = 'kqueue' elif sys.platform.startswith('darwin'): configuration.reactor = 'kqueue' else: log.error( 'we could not autodetect an high performance reactor for your OS'
nettools.py Created by Thomas Mangin on 2011-11-30. Copyright (c) 2011-2013 Exa Networks. All rights reserved. """ import socket import errno from exaproxy.util.log.logger import Logger from exaproxy.network.errno_list import errno_block from exaproxy.configuration import load IP_TRANSPARENT = 19 configuration = load() log = Logger('server', configuration.log.server) def isipv4(address): try: socket.inet_pton(socket.AF_INET, address) return True except socket.error: return False def isipv6(address): try: socket.inet_pton(socket.AF_INET6, address) return True except socket.error: return False
def main(): main = int(sys.version[0]) secondary = int(sys.version[2]) if main != 2 or secondary < 4: sys.exit( 'This program can not work (is not tested) with your python version (< 2.4 or >= 3.0)' ) if main == 2 and secondary == 4: version_warning() from exaproxy.configuration import ConfigurationError, load, ini, env next = '' arguments = { 'configuration': '', } for arg in sys.argv[1:]: if next: arguments[next] = arg next = '' continue if arg in ['-c', '--conf-file']: next = 'configuration' version = os.environ.get('exaproxy_release', 'unknown') defaults = { 'tcp4': { 'host': (value.unquote, string.quote, '127.0.0.1', 'the host the proxy listen on'), 'port': (value.integer, string.nop, '3128', 'the port the proxy listen on'), 'timeout': (value.integer, string.nop, '5', 'time before we abandon inactive established connections'), 'backlog': (value.integer, string.nop, '200', 'when busy how many connection should the OS queue for us'), 'listen': (value.boolean, string.lower, 'true', 'should we listen for connections over IPv4'), 'out': (value.boolean, string.lower, 'true', 'allow connections to remote web servers over IPv4'), 'bind': (value.unquote, string.quote, '0.0.0.0', 'which ipv4 to use when creating outbound connection'), }, 'tcp6': { 'host': (value.unquote, string.quote, '::1', 'the host the proxy listen on'), 'port': (value.integer, string.nop, '3128', 'the port the proxy listen on'), 'timeout': (value.integer, string.nop, '5', 'time before we abandon inactive established connections'), 'backlog': (value.integer, string.nop, '200', 'when busy how many connection should the OS queue for us'), 'listen': (value.boolean, string.lower, 'false', 'should we listen for connections over IPv6'), 'out': (value.boolean, string.lower, 'true', 'allow connections to remote web servers over IPv6'), 'bind': (value.unquote, string.quote, '::', 'which ipv6 to use when creating outbound connection'), }, 'redirector': { 'enable': (value.boolean, string.lower, 'false', 'use redirector programs to filter http request'), 'program': (value.exe, string.path, 'etc/exaproxy/redirector/url-allow', 'the program used to know where to send request'), 'minimum': (value.integer, string.nop, '5', 'minimum number of worker threads (forked program)'), 'maximum': (value.integer, string.nop, '25', 'maximum number of worker threads (forked program)'), 'protocol': (value.redirector, string.quote, 'url', 'what protocol to use (url -> squid like / icap:://<uri> -> icap like)' ) }, 'http': { 'idle-connect': (value.integer, string.nop, '300', 'time before we abandon new inactive http client connections (0: unlimited)' ), 'connections': (value.integer, string.nop, '32768', 'the maximum number of proxy connections'), 'transparent': (value.boolean, string.lower, 'false', 'do not reveal the presence of the proxy'), 'forward': (value.lowunquote, string.quote, '', 'read client address from this header (normally x-forwarded-for)' ), 'mask': (value.boolean, string.lower, 'false', 'hide client address by removing the header specified in exaproxy.http.forward' ), 'allow-connect': (value.boolean, string.lower, 'true', 'allow client to use CONNECT and https connections'), 'expect': (value.boolean, string.lower, 'false', 'block messages with EXPECT headers with a 417'), 'extensions': (value.methods, string.list, '', 'allow new HTTP method (space separated)'), 'proxied': (value.boolean, string.lower, 'false', 'request is encapsulated with haproxy proxy protocol'), 'header-size': (value.integer, string.nop, '65536', 'maximum size in bytes for HTTP headers (0 : unlimited)'), }, 'icap': { 'enable': (value.boolean, string.lower, 'true', 'enable the icap server'), 'host': (value.unquote, string.quote, '127.0.0.1', 'the address the icap server listens on'), 'ipv6': (value.unquote, string.quote, '::', 'the ipv6 address the icap server listens on'), 'port': (value.integer, string.nop, '1344', 'port the icap server listens on'), 'idle-connect': (value.integer, string.nop, '300', 'time before we abandon new inactive icap client connections (0: unlimited)' ), 'connections': (value.integer, string.nop, '32768', 'the maximum number of icap connections'), 'proxied': (value.boolean, string.lower, 'false', 'request is encapsulated with haproxy proxy protocol'), 'header-size': (value.integer, string.nop, '65536', 'maximum size in bytes for ICAP headers (0 : unlimited)'), }, 'web': { 'enable': (value.boolean, string.lower, 'true', 'enable the built-in webserver'), 'host': (value.unquote, string.quote, '127.0.0.1', 'the address the web server listens on'), 'port': (value.integer, string.nop, '8080', 'port the web server listens on'), 'html': (value.folder, string.path, 'etc/exaproxy/html', 'where internal proxy html pages are served from'), 'connections': (value.integer, string.nop, '100', 'the maximum number of web connections'), 'debug': (value.boolean, string.lower, 'false', 'allow to debug the program via the web client (do not use in production)' ), }, 'daemon': { 'identifier': (value.unquote, string.nop, 'ExaProxy', 'a name for the log (to diferenciate multiple instances more easily)' ), 'pidfile': (value.unquote, string.quote, '', 'where to save the pid if we manage it'), 'user': (value.user, string.quote, 'nobody', 'user to run as'), 'daemonize': (value.boolean, string.lower, 'false', 'should we run in the background'), 'reactor': (value.unquote, string.quote, 'best', 'event polling mechanism to use (select/epoll/kqueue/best)'), 'speed': (value.integer, string.nop, '2', 'sleep duration when waiting for connection'), 'poll-interfaces': (value.boolean, string.lower, 'true', 'periodically poll for local addresses the proxy should not connect to' ), }, 'security': { 'local': (value.services, string.services, '', 'ip:port for allowed services (*:80 or 127.0.0.1:* allowed)'), 'connect': (value.ports, string.list, '443 981 7000', 'ports allowed with CONNECT'), }, 'dns': { 'resolver': (value.resolver, string.path, '/etc/resolv.conf', 'resolver file'), 'timeout': (value.integer, string.nop, '2', 'how long to wait for DNS replies before retrying'), 'retries': (value.integer, string.nop, '10', 'how many times to retry sending requests'), 'ttl': (value.integer, string.nop, '900', 'amount of time (in seconds) we will cache dns results for'), 'fqdn': (value.boolean, string.lower, 'true', 'only resolve FQDN (hostnames must have a dot'), 'definitions': (value.folder, string.path, 'etc/exaproxy/dns/types', 'location of file defining dns query types'), }, 'log': { 'enable': (value.boolean, string.lower, 'true', 'enable traffic logging'), 'level': (value.syslog, string.syslog, 'ERROR', 'log message with at least the priority logging.<level>'), 'destination': (value.unquote, string.quote, 'stdout', 'where syslog should log'), 'signal': (value.boolean, string.lower, 'true', 'log messages from the signal subsystem'), 'configuration': (value.boolean, string.lower, 'true', 'log messages from the configuration subsystem'), 'supervisor': (value.boolean, string.lower, 'true', 'log messages from the supervisor subsystem'), 'daemon': (value.boolean, string.lower, 'true', 'log messages from the daemon subsystem'), 'server': (value.boolean, string.lower, 'true', 'log messages from the server subsystem'), 'client': (value.boolean, string.lower, 'true', 'log messages from the client subsystem'), 'manager': (value.boolean, string.lower, 'true', 'log messages from the manager subsystem'), 'worker': (value.boolean, string.lower, 'true', 'log messages from the worker subsystem'), 'download': (value.boolean, string.lower, 'true', 'log messages from the download subsystem'), 'http': (value.boolean, string.lower, 'true', 'log messages from the http subsystem'), 'header': (value.boolean, string.lower, 'true', 'log messages from the header subsystem'), 'resolver': (value.boolean, string.lower, 'true', 'log messages from the dns subsystem'), 'web': (value.boolean, string.lower, 'true', 'log messages from the web subsystem'), }, 'usage': { 'enable': (value.boolean, string.lower, 'false', 'enable traffic logging'), 'destination': (value.unquote, string.quote, 'stdout', 'where syslog should log'), }, 'profile': { 'enable': (value.boolean, string.lower, 'false', 'enable profiling'), 'destination': (value.unquote, string.quote, 'stdout', 'save profiling to file (instead of to the screen on exit)'), }, 'proxy': { 'version': (value.nop, string.nop, version, 'ExaProxy\'s version'), }, # Here for internal use 'debug': { 'memory': (value.boolean, string.lower, 'false', 'command line option --memory'), 'pdb': (value.boolean, string.lower, 'false', 'command line option --pdb'), 'log': (value.boolean, string.lower, 'false', 'command line option --debug'), }, } try: configuration = load('exaproxy', defaults, arguments['configuration']) except ConfigurationError, e: print >> sys.stderr, 'configuration issue,', str(e) sys.exit(1)
def main (): primary = int(sys.version[0]) secondary = int(sys.version[2]) if primary != 2 or secondary < 4: sys.exit('This program can not work (is not tested) with your python version (< 2.4 or >= 3.0)') if primary == 2 and secondary == 4: version_warning() from exaproxy.configuration import ConfigurationError,load,ini,env followup = '' arguments = { 'configuration' : '', } for arg in sys.argv[1:]: if followup: arguments[followup] = arg followup = '' continue if arg in ['-c','--conf-file']: followup = 'configuration' defaults = { 'tcp4' : { 'host' : (value.unquote,string.quote,'127.0.0.1', 'the host the proxy listen on'), 'port' : (value.integer,string.nop,'3128', 'the port the proxy listen on'), 'timeout' : (value.integer,string.nop,'5', 'time before we abandon inactive established connections'), 'backlog' : (value.integer,string.nop,'200', 'when busy how many connection should the OS queue for us'), 'listen' : (value.boolean,string.lower,'true', 'should we listen for connections over IPv4'), 'out' : (value.boolean,string.lower,'true', 'allow connections to remote web servers over IPv4'), 'bind' : (value.unquote,string.quote,'0.0.0.0', 'which ipv4 to use when creating outbound connection'), }, 'tcp6' : { 'host' : (value.unquote,string.quote,'::1', 'the host the proxy listen on'), 'port' : (value.integer,string.nop,'3128', 'the port the proxy listen on'), 'timeout' : (value.integer,string.nop,'5', 'time before we abandon inactive established connections'), 'backlog' : (value.integer,string.nop,'200', 'when busy how many connection should the OS queue for us'), 'listen' : (value.boolean,string.lower,'false', 'should we listen for connections over IPv6'), 'out' : (value.boolean,string.lower,'true', 'allow connections to remote web servers over IPv6'), 'bind' : (value.unquote,string.quote,'::', 'which ipv6 to use when creating outbound connection'), }, 'redirector' : { 'enable' : (value.boolean,string.lower,'false', 'use redirector programs to filter http request'), 'program' : (value.exe,string.path,'etc/exaproxy/redirector/url-allow', 'the program used to know where to send request'), 'minimum' : (value.integer,string.nop,'5', 'minimum number of worker threads (forked program)'), 'maximum' : (value.integer,string.nop,'25', 'maximum number of worker threads (forked program)'), 'protocol': (value.redirector,string.quote,'url', 'what protocol to use (url -> squid like / icap:://<uri> -> icap like)') }, 'http' : { 'idle-connect' : (value.integer,string.nop,'300', 'time before we abandon new inactive http client connections (0: unlimited)'), 'connections' : (value.integer,string.nop,'32768', 'the maximum number of proxy connections'), 'transparent' : (value.boolean,string.lower,'false', 'do not reveal the presence of the proxy'), 'forward' : (value.lowunquote,string.quote,'', 'read client address from this header (normally x-forwarded-for)'), 'mask' : (value.boolean,string.lower,'false', 'hide client address by removing the header specified in exaproxy.http.forward'), 'connect' : (value.boolean,string.lower,'true', 'allow client to use CONNECT and https connections'), 'expect' : (value.boolean,string.lower,'false', 'block messages with EXPECT headers with a 417'), 'extensions' : (value.methods,string.list,'', 'allow new HTTP method (space separated)'), 'proxied' : (value.boolean,string.lower,'false', 'request is encapsulated with haproxy proxy protocol'), 'header-size' : (value.integer,string.nop,'65536', 'maximum size in bytes for HTTP headers (0 : unlimited)'), }, 'passthrough' : { 'enable' : (value.boolean,string.lower,'false', 'enable the passthrough server'), 'host' : (value.unquote,string.quote,'127.0.0.1', 'the address the passthrough server listens on'), 'ipv6' : (value.unquote,string.quote,'::', 'the ipv6 address the passthrough server listens on'), 'port' : (value.integer,string.nop,'8000', 'port the passthrough server listens on'), 'idle-connect' : (value.integer,string.nop,'300', 'time before we abandon new inactive passthrough client connections (0: unlimited)'), 'connections' : (value.integer,string.nop,'32768', 'the maximum number of passthrough connections'), 'proxied' : (value.boolean,string.lower,'false', 'request is encapsulated with haproxy proxy protocol'), }, 'icap' : { 'enable' : (value.boolean,string.lower,'false', 'enable the icap server'), 'host' : (value.unquote,string.quote,'127.0.0.1', 'the address the icap server listens on'), 'ipv6' : (value.unquote,string.quote,'::', 'the ipv6 address the icap server listens on'), 'port' : (value.integer,string.nop,'1344', 'port the icap server listens on'), 'idle-connect' : (value.integer,string.nop,'300', 'time before we abandon new inactive icap client connections (0: unlimited)'), 'connections' : (value.integer,string.nop,'32768', 'the maximum number of icap connections'), 'proxied' : (value.boolean,string.lower,'false', 'request is encapsulated with haproxy proxy protocol'), 'header-size' : (value.integer,string.nop,'65536', 'maximum size in bytes for ICAP headers (0 : unlimited)'), }, 'tls' : { 'enable' : (value.boolean,string.lower,'false', 'enable the TLS server'), 'host' : (value.unquote,string.quote,'127.0.0.1', 'the address the TLS server listens on'), 'ipv6' : (value.unquote,string.quote,'::', 'the ipv6 address the TLS server listens on'), 'port' : (value.integer,string.nop,'443', 'port the TLS server listens on'), 'idle-connect' : (value.integer,string.nop,'300', 'time before we abandon new inactive TLS client connections (0: unlimited)'), 'connections' : (value.integer,string.nop,'32768', 'the maximum number of TLS connections'), 'proxied' : (value.boolean,string.lower,'false', 'request is encapsulated with haproxy proxy protocol'), 'header-size' : (value.integer,string.nop,'65536', 'maximum size in bytes for TLS headers (0 : unlimited)'), }, 'web' : { 'enable' : (value.boolean,string.lower,'true', 'enable the built-in webserver'), 'host' : (value.unquote,string.quote,'127.0.0.1', 'the address the web server listens on'), 'port' : (value.integer,string.nop,'8080', 'port the web server listens on'), 'html' : (value.folder,string.path,'etc/exaproxy/html', 'where internal proxy html pages are served from'), 'connections' : (value.integer,string.nop,'100', 'the maximum number of web connections'), 'debug' : (value.boolean,string.lower,'false', 'allow to debug the program via the web client (do not use in production)'), }, 'daemon' : { 'identifier' : (value.unquote,string.nop,'ExaProxy','a name for the log (to diferenciate multiple instances more easily)'), 'pidfile' : (value.unquote,string.quote,'', 'where to save the pid if we manage it'), 'user' : (value.user,string.quote,'nobody', 'user to run as'), 'daemonize' : (value.boolean,string.lower,'false', 'should we run in the background'), 'reactor' : (value.unquote,string.quote,'best', 'event polling mechanism to use (select/epoll/kqueue/best)'), 'speed' : (value.integer,string.nop,'2', 'sleep duration when waiting for connection'), 'poll-interfaces' : (value.boolean,string.lower,'true', 'periodically poll for local addresses the proxy should not connect to'), }, 'security' : { 'local' : (value.services,string.services, '', 'ip:port for allowed services (*:80 or 127.0.0.1:* allowed)'), 'connect' : (value.ports,string.list, '443 981 7000', 'ports allowed with CONNECT'), }, 'dns' : { 'resolver' : (value.resolver,string.path,'/etc/resolv.conf', 'resolver file'), 'timeout' : (value.integer,string.nop,'2', 'how long to wait for DNS replies before retrying'), 'retries' : (value.integer,string.nop,'10', 'how many times to retry sending requests'), 'ttl' : (value.integer,string.nop,'900', 'amount of time (in seconds) we will cache dns results for'), 'fqdn' : (value.boolean,string.lower,'true', 'only resolve FQDN (hostnames must have a dot'), 'definitions' : (value.folder,string.path,'etc/exaproxy/dns/types', 'location of file defining dns query types'), }, 'log' : { 'enable' : (value.boolean,string.lower,'true', 'enable traffic logging'), 'level' : (value.syslog,string.syslog,'ERROR', 'log message with at least the priority logging.<level>'), 'destination' : (value.unquote,string.quote,'stdout', 'where syslog should log'), 'signal' : (value.boolean,string.lower,'true', 'log messages from the signal subsystem'), 'configuration' : (value.boolean,string.lower,'true', 'log messages from the configuration subsystem'), 'supervisor' : (value.boolean,string.lower,'true', 'log messages from the supervisor subsystem'), 'daemon' : (value.boolean,string.lower,'true', 'log messages from the daemon subsystem'), 'server' : (value.boolean,string.lower,'true', 'log messages from the server subsystem'), 'client' : (value.boolean,string.lower,'true', 'log messages from the client subsystem'), 'manager' : (value.boolean,string.lower,'true', 'log messages from the manager subsystem'), 'worker' : (value.boolean,string.lower,'true', 'log messages from the worker subsystem'), 'download' : (value.boolean,string.lower,'true', 'log messages from the download subsystem'), 'http' : (value.boolean,string.lower,'true', 'log messages from the http subsystem'), 'header' : (value.boolean,string.lower,'true', 'log messages from the header subsystem'), 'resolver' : (value.boolean,string.lower,'true', 'log messages from the dns subsystem'), 'web' : (value.boolean,string.lower,'true', 'log messages from the web subsystem'), }, 'usage' : { 'enable' : (value.boolean,string.lower,'false', 'enable traffic logging'), 'destination' : (value.unquote,string.quote,'stdout', 'where syslog should log'), }, 'profile' : { 'enable' : (value.boolean,string.lower,'false', 'enable profiling'), 'destination' : (value.unquote,string.quote,'stdout', 'save profiling to file (instead of to the screen on exit)'), }, 'proxy' : { 'version' : (value.nop,string.nop,version, 'ExaProxy\'s version'), }, # Here for internal use 'debug' : { 'memory' : (value.boolean,string.lower,'false','command line option --memory'), 'pdb' : (value.boolean,string.lower,'false','command line option --pdb'), 'log' : (value.boolean,string.lower,'false','command line option --debug'), }, } try: configuration = load('exaproxy',defaults,arguments['configuration']) except ConfigurationError,e: print >> sys.stderr, 'configuration issue,', str(e) sys.exit(1)