<s> """<STR_LIT>""" <EOL> from six . moves import http_client as httplib <EOL> from six . moves . urllib import parse as urlparse <EOL> from six . moves . urllib . parse import quote <EOL> import six <EOL> from paste import httpexceptions <EOL> from paste . util . converters import aslist <EOL> filtered_headers = ( <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> ) <EOL> class Proxy ( object ) : <EOL> def __init__ ( self , address , allowed_request_methods = ( ) , <EOL> suppress_http_headers = ( ) ) : <EOL> self . address = address <EOL> self . parsed = urlparse . urlsplit ( address ) <EOL> self . scheme = self . parsed [ <NUM_LIT:0> ] . lower ( ) <EOL> self . host = self . parsed [ <NUM_LIT:1> ] <EOL> self . path = self . parsed [ <NUM_LIT:2> ] <EOL> self . allowed_request_methods = [ <EOL> x . lower ( ) for x in allowed_request_methods if x ] <EOL> self . suppress_http_headers = [ <EOL> x . lower ( ) for x in suppress_http_headers if x ] <EOL> def __call__ ( self , environ , start_response ) : <EOL> if ( self . allowed_request_methods and <EOL> environ [ '<STR_LIT>' ] . lower ( ) not in self . allowed_request_methods ) : <EOL> return httpexceptions . HTTPBadRequest ( "<STR_LIT>" ) ( environ , start_response ) <EOL> if self . scheme == '<STR_LIT:http>' : <EOL> ConnClass = httplib . HTTPConnection <EOL> elif self . scheme == '<STR_LIT>' : <EOL> ConnClass = httplib . HTTPSConnection <EOL> else : <EOL> raise ValueError ( <EOL> "<STR_LIT>" % ( self . address , self . scheme ) ) <EOL> conn = ConnClass ( self . host ) <EOL> headers = { } <EOL> for key , value in environ . items ( ) : <EOL> if key . startswith ( '<STR_LIT>' ) : <EOL> key = key [ <NUM_LIT:5> : ] . lower ( ) . replace ( '<STR_LIT:_>' , '<STR_LIT:->' ) <EOL> if key == '<STR_LIT:host>' or key in self . suppress_http_headers : <EOL> continue <EOL> headers [ key ] = value <EOL> headers [ '<STR_LIT:host>' ] = self . host <EOL> if '<STR_LIT>' in environ : <EOL> headers [ '<STR_LIT>' ] = environ [ '<STR_LIT>' ] <EOL> if environ . get ( '<STR_LIT>' ) : <EOL> headers [ '<STR_LIT>' ] = environ [ '<STR_LIT>' ] <EOL> if environ . get ( '<STR_LIT>' ) : <EOL> if environ [ '<STR_LIT>' ] == '<STR_LIT>' : <EOL> body = environ [ '<STR_LIT>' ] . read ( - <NUM_LIT:1> ) <EOL> headers [ '<STR_LIT>' ] = str ( len ( body ) ) <EOL> else : <EOL> headers [ '<STR_LIT>' ] = environ [ '<STR_LIT>' ] <EOL> length = int ( environ [ '<STR_LIT>' ] ) <EOL> body = environ [ '<STR_LIT>' ] . read ( length ) <EOL> else : <EOL> body = '<STR_LIT>' <EOL> path_info = quote ( environ [ '<STR_LIT>' ] ) <EOL> if self . path : <EOL> request_path = path_info <EOL> if request_path and request_path [ <NUM_LIT:0> ] == '<STR_LIT:/>' : <EOL> request_path = request_path [ <NUM_LIT:1> : ] <EOL> path = urlparse . urljoin ( self . path , request_path ) <EOL> else : <EOL> path = path_info <EOL> if environ . get ( '<STR_LIT>' ) : <EOL> path += '<STR_LIT:?>' + environ [ '<STR_LIT>' ] <EOL> conn . request ( environ [ '<STR_LIT>' ] , <EOL> path , <EOL> body , headers ) <EOL> res = conn . getresponse ( ) <EOL> headers_out = parse_headers ( res . msg ) <EOL> status = '<STR_LIT>' % ( res . status , res . reason ) <EOL> start_response ( status , headers_out ) <EOL> length = res . getheader ( '<STR_LIT>' ) <EOL> if length is not None : <EOL> body = res . read ( int ( length ) ) <EOL> else : <EOL> body = res . read ( ) <EOL> conn . close ( ) <EOL> return [ body ] <EOL> def make_proxy ( global_conf , address , allowed_request_methods = "<STR_LIT>" , <EOL> suppress_http_headers = "<STR_LIT>" ) : <EOL> """<STR_LIT>""" <EOL> allowed_request_methods = aslist ( allowed_request_methods ) <EOL> suppress_http_headers = aslist ( suppress_http_headers ) <EOL> return Proxy ( <EOL> address , <EOL> allowed_request_methods = allowed_request_methods , <EOL> suppress_http_headers = suppress_http_headers ) <EOL> class TransparentProxy ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , force_host = None , <EOL> force_scheme = '<STR_LIT:http>' ) : <EOL> self . force_host = force_host <EOL> self . force_scheme = force_scheme <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' % ( <EOL> self . __class__ . __name__ , <EOL> hex ( id ( self ) ) , <EOL> self . force_host , self . force_scheme ) <EOL> def __call__ ( self , environ , start_response ) : <EOL> scheme = environ [ '<STR_LIT>' ] <EOL> if self . force_host is None : <EOL> conn_scheme = scheme <EOL> else : <EOL> conn_scheme = self . force_scheme <EOL> if conn_scheme == '<STR_LIT:http>' : <EOL> ConnClass = httplib . HTTPConnection <EOL> elif conn_scheme == '<STR_LIT>' : <EOL> ConnClass = httplib . HTTPSConnection <EOL> else : <EOL> raise ValueError ( <EOL> "<STR_LIT>" % scheme ) <EOL> if '<STR_LIT>' not in environ : <EOL> raise ValueError ( <EOL> "<STR_LIT>" ) <EOL> host = environ [ '<STR_LIT>' ] <EOL> if self . force_host is None : <EOL> conn_host = host <EOL> else : <EOL> conn_host = self . force_host <EOL> conn = ConnClass ( conn_host ) <EOL> headers = { } <EOL> for key , value in environ . items ( ) : <EOL> if key . startswith ( '<STR_LIT>' ) : <EOL> key = key [ <NUM_LIT:5> : ] . lower ( ) . replace ( '<STR_LIT:_>' , '<STR_LIT:->' ) <EOL> headers [ key ] = value <EOL> headers [ '<STR_LIT:host>' ] = host <EOL> if '<STR_LIT>' in environ and '<STR_LIT>' not in environ : <EOL> headers [ '<STR_LIT>' ] = environ [ '<STR_LIT>' ] <EOL> if environ . get ( '<STR_LIT>' ) : <EOL> headers [ '<STR_LIT>' ] = environ [ '<STR_LIT>' ] <EOL> if environ . get ( '<STR_LIT>' ) : <EOL> length = int ( environ [ '<STR_LIT>' ] ) <EOL> body = environ [ '<STR_LIT>' ] . read ( length ) <EOL> if length == - <NUM_LIT:1> : <EOL> environ [ '<STR_LIT>' ] = str ( len ( body ) ) <EOL> elif '<STR_LIT>' not in environ : <EOL> body = '<STR_LIT>' <EOL> length = <NUM_LIT:0> <EOL> else : <EOL> body = '<STR_LIT>' <EOL> length = <NUM_LIT:0> <EOL> path = ( environ . get ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> + environ . get ( '<STR_LIT>' , '<STR_LIT>' ) ) <EOL> path = quote ( path ) <EOL> if '<STR_LIT>' in environ : <EOL> path += '<STR_LIT:?>' + environ [ '<STR_LIT>' ] <EOL> conn . request ( environ [ '<STR_LIT>' ] , <EOL> path , body , headers ) <EOL> res = conn . getresponse ( ) <EOL> headers_out = parse_headers ( res . msg ) <EOL> status = '<STR_LIT>' % ( res . status , res . reason ) <EOL> start_response ( status , headers_out ) <EOL> length = res . getheader ( '<STR_LIT>' ) <EOL> if length is not None : <EOL> body = res . read ( int ( length ) ) <EOL> else : <EOL> body = res . read ( ) <EOL> conn . close ( ) <EOL> return [ body ] <EOL> def parse_headers ( message ) : <EOL> """<STR_LIT>""" <EOL> headers_out = [ ] <EOL> if six . PY3 : <EOL> for header , value in message . items ( ) : <EOL> if header . lower ( ) not in filtered_headers : <EOL> headers_out . append ( ( header , value ) ) <EOL> else : <EOL> for full_header in message . headers : <EOL> if not full_header : <EOL> continue <EOL> if full_header [ <NUM_LIT:0> ] . isspace ( ) : <EOL> if not headers_out : <EOL> raise ValueError ( <EOL> "<STR_LIT>" % full_header ) <EOL> last_header , last_value = headers_out . pop ( ) <EOL> value = last_value + '<STR_LIT:U+0020>' + full_header . strip ( ) <EOL> headers_out . append ( ( last_header , value ) ) <EOL> continue <EOL> try : <EOL> header , value = full_header . split ( '<STR_LIT::>' , <NUM_LIT:1> ) <EOL> except : <EOL> raise ValueError ( "<STR_LIT>" % full_header ) <EOL> value = value . strip ( ) <EOL> if header . lower ( ) not in filtered_headers : <EOL> headers_out . append ( ( header , value ) ) <EOL> return headers_out <EOL> def make_transparent_proxy ( <EOL> global_conf , force_host = None , force_scheme = '<STR_LIT:http>' ) : <EOL> """<STR_LIT>""" <EOL> return TransparentProxy ( force_host = force_host , <EOL> force_scheme = force_scheme ) </s>
