def parsed_headers(self): if self.DEBUG: Log.pdebug("Headers.parsed_headers") if not self.headers_have_been_parsed: self.__parse() return self.__headers
def do_TRACE(self): self.content = '' self.BASIC(what='TRACE') Log.pdebug('%s:%s, ' % (self.client_address[0], self.client_address[1]) + 'Allow: %s, ' % self.Allowed + 'prxUSR: %10s, ' % self.proxy_user[0:9] + 'Cod: %3d, Size: %8d, ' % (self.code, self.content_lenght) + 'PRX TRC '+ self.path) return
def do_OTHER(self): self.content = '' self.send_response(405) self.send_header('Allow',self.__verbs_supported) self.end_headers Log.pdebug('%s:%s, ' % (self.client_address[0], self.client_address[1]) + 'Allow: %s, ' % self.Allowed + 'prxUSR: %10s, ' % self.proxy_user[0:9] + 'Cod: %3d, Size: %8d,' % (self.code, self.content_lenght) + 'PRX OTH '+ self.path) return
def svc_hndl_NOOP(self,parms,query, Verb=''): Log.pdebug("svc_hndl_NOOP called with parms: >%s, %s<" % (Verb, parms)) if Verb=='HEAD': mensaje='' else: mensaje=self.int_get_html_message('NOOP hndl') self.int_send_HEADERS(200,mensaje) if Verb!='HEAD': self.int_send_BODY(mensaje) return
def svc_hndl_POST(self,parms,query, Verb=''): Log.pdebug("svc_hndl_POST called with parms: >%s, %s<" % (Verb, parms)) if Verb=='HEAD': mensaje='' else: mensaje='<html><head><title>My Page</title></head><body><form name="myform" action="http://localhost/dump.php" method="POST"><div align="center"><br><br><input type="text" size="25" value="Enter your name here!"><br><input type="submit" value="Send me your name!"><br></div></form></body></html>' self.int_send_HEADERS(200,mensaje) if Verb!='HEAD': self.int_send_BODY(mensaje) return
def __init__(self, headers, debug=False, ip="", port=""): self.__orig_headers = {} self.__headers = {} self.__cookies = {} self.DEBUG = debug self.ip = ip self.port = port if self.DEBUG: Log.pdebug("ClientHeaders.__init__") if headers != []: self.__orig_headers = headers
def int_send_BODY(self, message=''): try: if python_OldVersion: self.wfile.write(message) else: self.wfile.write(bytes(message, 'UTF-8')) except: Log.pdebug('excepcion en send_body :%s, %s' % (self.what, self.path)) pass return
def put(self, path, content, headers, debug=False, ip='', port=''): succeded = False if not self.is_initialized: self.setup(path=path) #self.setup(path) #self.cache_filename_base = Config.cache_Path + '/' + self.md5hash #self.cache_filename_meta = self.cache_filename_base + '.meta' #self.cache_filename_cache = self.cache_filename_base + '.cache' try: with open(self.cache_filename_meta, 'wb') as meta_file: meta_file.write(bytes(path,encoding='utf_8')) with open(self.cache_filename_cache, 'wb') as cache_file: cache_file.write(content) with open(self.cache_filename_header, 'wb') as header_file: for k,v in headers: header_file.write(bytes(k+': '+str(v)+'\n','UTF-8')) succeded = True if debug == True: Log.pdebug('%s:%s, ::: CCH filename: %s' % (ip, port, self.cache_filename_base)) Log.pdebug('%s:%s, ::: CCH path: %s' % (ip, port, path)) Log.pdebug('%s:%s, ::: CCH size %s' % (ip, port, len(content))) except Exception as e: Log.pdebug('!!! exception %s:%s %s, ::: Control Cache put %s' % (ip, port, str(e), self.cache_filename_base)) return succeded
def svc_hndl_STOP(self,parms,query, Verb=''): Log.pdebug("svc_hndl_STOP called with parms: >%s, %s<" % (Verb, parms)) if Verb=='HEAD': mensaje='' else: mensaje=self.int_get_html_message('STOP hndl') self.int_send_HEADERS(200,mensaje) if Verb!='HEAD': self.int_send_BODY(mensaje) Proxy.threadServer.force_shutdown() #self.send_html_message("FORCED SHUTDOWN") return
def __init__(self, response, debug=False, ip="", port="", server_version="HTTP_Proxy/0.1"): self.__headers = [] self.__headers.clear() self.ip = "" self.port = "" self.DEBUG = debug self.ip = ip self.port = port self.server_version = server_version self.headers_have_been_parsed = False if self.DEBUG: Log.pdebug("ServerHeaders.__init__") if response != []: self.__response = response
def setup(self, path, debug=False, ip='', port=''): self.path=path md5hash = hashlib.md5() md5hash.update(bytes(self.path,encoding='utf_8')) self.md5hash = md5hash.hexdigest() self.cache_filename_base = Config.cache_Path + '/' + self.md5hash.upper() self.cache_filename_meta = self.cache_filename_base + '.url' self.cache_filename_cache = self.cache_filename_base + '.cache' self.cache_filename_header = self.cache_filename_base + '.head' self.is_initialized = True if debug == True or self.DEBUG == True: Log.pdebug('Filecache.setup dump:') Log.pdebug(vars(self)) return
def handle_HTTP_AUTH(self): # Tenemos una cabecera con autenticacion Proxy? ## Python 3 => removed self.headers.>has_key<('Authorization'): ## cambiado por 'in' if 'Authorization' in self.headers: authorization = self.headers.get('Authorization') if DEBUG: Log.pdebug ('HTTP auth string [Authorization]: %s ' % authorization) authorization = authorization.split() # Han usado una autenticación básica? if authorization[0].lower() == "basic": try: # Sí, intentamos obtener el usuario y passwd #authorization = base64.decodestring(authorization[1]) if python_OldVersion: authorization = base64.decodestring(authorization[1]) else: authorization = base64.decodestring(bytes(authorization[1],'UTF-8')).decode() # bytes(content, 'UTF-8') except binascii.Error: # Error, entonces KO return 0 else: # Tenemos usuario & paswd y lo hemos podido decodificar authorization = authorization.split(':') self.http_user=authorization[0] self.http_password=authorization[1] if self.http_user == 'User' and self.http_password == 'Pass': #Autenticacion = OK return 1 else: #Autenticacion = KO return 0 # No está autenticado else: return 0
def is_cached(self, path, debug=False, ip='', port=''): returncode = False meta_file_path = '' if not self.is_initialized: self.setup(path=path) if os.path.exists(self.cache_filename_cache): try: with open(self.cache_filename_meta, 'r') as meta_file: meta_file_path = meta_file.read() except Exception as e: Log.pdebug('!!! exception %s:%s %s, ::: Control Cache is_cached' % (ip, port, self.cache_filename_base,e)) pass if (meta_file_path == path): returncode = True return returncode
def get(self, path, debug=False, ip='', port=''): succeded = False content= bytes('','UTF-8') headers= [] if not self.is_initialized: self.setup(path=path) try: with open(self.cache_filename_cache, 'rb') as cache_file: content=cache_file.read() # El fichero de cabeceras debe leerse en modo Ascii en windows, si no, retorna un '\n' adicional al final de la cadena with open(self.cache_filename_header, 'r') as headers_file: headers=headers_file.readlines() succeded = True except Exception as e: Log.pdebug('!!! exception %s:%s %s, ::: Control Cache get %s' % (ip, port, str(e), self.cache_filename_base)) return content, headers
def do_OPTIONS(self): self.content = '' Log.pdebug('%s:%s, ' % (self.client_address[0], self.client_address[1]) + 'Allow: %s, ' % self.Allowed + 'prxUSR: %10s, ' % self.proxy_user[0:9] + 'Cod: %3d, Size: %8d, ' % (self.code, self.content_lenght) + '??? OPT '+ self.path) if (self.path == '*'): self.send_response(200) self.send_header('Allow',self.__verbs_supported) self.send_header('Content-Length', '0') self.end_headers else: self.BASIC(what='OPTIONS') # TODO:: OPTIONS de url requiere auth... gesionado en BASIC Log.pdebug('%s:%s, ' % (self.client_address[0], self.client_address[1]) + 'Allow: %s, ' % self.Allowed + 'prxUSR: %10s, ' % self.proxy_user[0:9] + 'Cod: %3d, Size: %8d, ' % (self.code, self.content_lenght) + 'PRX OPT '+ self.path) return
def do_POST(self): Log.pdebug('%s:%s, ' % (self.client_address[0], self.client_address[1]) + 'Allow: %s, ' % self.Allowed + 'prxUSR: %10s, ' % self.proxy_user[0:9] + 'Cod: %3d, Size: %8d, ' % (self.code, self.content_lenght) + '??? PST %s' % (self.path) ) if 'Content-Length' in self.headers: self.content = self.rfile.read(int(self.headers['Content-Length'])) else: self.content = '' if DEBUG: sys.stderr.write('calling BASIC\n') self.BASIC(what='POST') Log.pdebug('%s:%s, ' % (self.client_address[0], self.client_address[1]) + 'Allow: %s, ' % self.Allowed + 'prxUSR: %10s, ' % self.proxy_user[0:9] + 'Cod: %3d, Size: %8d, ' % (self.code, self.content_lenght) + 'PRX PST '+ self.path) return
def dump(self): if self.DEBUG: Log.pdebug("Headers.dump") for i in self.__response.headers: Log.pdebug(" > %s %s: %s" % (self.port, i, self.__response.headers[i])) if self.headers_have_been_parsed: for i in self.__headers: Log.pdebug(" < %s %s:" % (self.port, i))
def svc_hndl_FILE(self,parms,query, Verb=''): Log.pdebug("svc_hndl_FILE called with parms: >%s, %s<" % (Verb, parms)) if Verb=='HEAD': mensaje='' else: if DEBUG: Log.pdebug("url parms = %s, %s" % (parms,query)) filename=re.sub(r'[^a-zA-Z0-9]', "", parms).lower() if os.path.exists('./static/'+filename+'.static'): source = open('./static/'+filename+'.static', 'r') mensaje = source.read() self.int_send_HEADERS(200,mensaje) else: mensaje=self.int_get_html_message('File "<font color="red">'+filename+'</font>" not found') self.int_send_HEADERS(404,mensaje) #self.int_send_BODY(mensaje) if Verb!='HEAD': self.int_send_BODY(mensaje) return
def do_GET(self): ''' parsed_headers = Headers(headers=self.headers.items(), debug=True, ip=self.client_address[0], port = self.client_address[1]) returned_headers = parsed_headers.input_parsed_headers() ''' Log.pdebug('%s:%s, ' % (self.client_address[0], self.client_address[1]) + 'Allow: %s, ' % self.Allowed + 'prxUSR: %10s, ' % self.proxy_user[0:9] + 'Cod: %3d, Size: %8d, ' % (self.code, self.content_lenght) + '??? GET %s' % (self.path) ) if 'Content-Length' in self.headers: self.content = self.rfile.read(int(self.headers['Content-Length'])) else: self.content = '' self.BASIC(what='GET') ''' msg = "%s:%s: " % (self.client_address[0], self.client_address[1])+ 'Allow: %s, ' % self.Allowed + 'prxUSR: %10s, ' % self.proxy_user[0:9] + 'Cod: %3d, Size: %8d,' % (self.code, self.content_lenght) + 'PRX GET ' + self.path ''' if self.content_cached: Log.pdebug('%s:%s, ' % (self.client_address[0], self.client_address[1]) + 'Allow: %s, ' % self.Allowed + 'prxUSR: %10s, ' % self.proxy_user[0:9] + 'Cod: %3d, Size: %8d, ' % (self.code, self.content_lenght) + 'CAC GET %s' % (self.path) ) else: Log.pdebug('%s:%s, ' % (self.client_address[0], self.client_address[1]) + 'Allow: %s, ' % self.Allowed + 'prxUSR: %10s, ' % self.proxy_user[0:9] + 'Cod: %3d, Size: %8d, ' % (self.code, self.content_lenght) + 'PRX GET %s' % (self.path) ) return
def parse(self): lines = self.__orig_headers.splitlines()[:-1] for line in lines: header_key, header_value = line.split(": ", 1) # Solo partimos una vez header_key = header_key.capitalize() if self.DEBUG: Log.pdebug("%s:%s: * IH %s -> %s" % (self.ip, self.port, header_key, header_value)) # Evitamos copiar la autorizacion del proxy y el host if header_key not in ["Proxy-authorization", "Host", "Accept-encoding"]: # Eliminamos la cabecera de autenticacion proxy, # Eliminamos la traza del Host y # Eliminamos las cabeceras que no sean texto plano p.ej: "Accept-encoding -> gzip, deflate" # Si tenemos la cabecera if (header_key == "Content-length") and self.DEBUG: Log.pdebug("::: HDR - %s:%s Content-length => hdr %s\n" % (self.ip, self.port, header_value)) if self.DEBUG: Log.pdebug("%s:%s: . FH %s -> %s" % (self.ip, self.port, header_key, header_value)) if header_key in self.__headers: # Copiamos el antiguo valor y hacemos un append oldvalue = self.__headers[header_key] self.__headers[header_key] = oldvalue + " " + header_value if self.DEBUG: Log.pdebug( "%s:%s: *********** Append header %s -> %s" % (self.ip, self.port, header_key, self.__headers[header_key]) ) else: self.__headers[header_key] = header_value if self.DEBUG: Log.pdebug( "%s:%s: + OH %s -> %s" % (self.ip, self.port, header_key, self.__headers[header_key]) ) else: if self.DEBUG: Log.pdebug("%s:%s: - OH %s -> %s" % (self.ip, self.port, header_key, header_value)) return self.__headers, {}
def __parse(self): if self.DEBUG: Log.pdebug("Headers.parse") for header_name, header_value in self.__response.headers.items(): if ( header_name in ["content-length", "transfer-encoding", "te", "content-encoding", "content-md5"] and self.DEBUG ): Log.pdebug("::: HDR - %s:%s header %s-> value %s\n" % (self.ip, self.port, header_name, header_value)) if self.DEBUG: Log.pdebug("IN header: %s - %s: %s" % (self.port, header_name.capitalize(), header_value)) if header_name == "date": pass elif header_name == "content-length": # Debido a que la librería request hace descompresion automatica, no nos podemos # fiar del header 'content-length' en caso de codificacion deflate/gzip, asi que # reescribimos la cabecera incondicionalmente if self.DEBUG: sys.stderr.write( ":::: Content-length => hdr %s vs cont %s\n" % (header_value, len(self.__response.content)) ) self.__headers.append([header_name.capitalize(), len(self.__response.content)]) if self.DEBUG: Log.pdebug("OU header CL: %s - %s: %s" % (self.port, header_name.capitalize(), header_value)) Log.pdebug("OU header SZ: %s - : %s" % (self.port, len(self.__response.content))) pass elif header_name == "transfer-encoding": # Eliminamos transfer-encoding por la misma razon anterior if self.DEBUG: Log.pdebug("SU header: %s - %s: %s" % (self.port, header_name.capitalize(), header_value)) elif header_name == "content-encoding": # Eliminamos transfer-encoding por la misma razon anterior if self.DEBUG: Log.pdebug("SU header: %s - %s: %s" % (self.port, header_name.capitalize(), header_value)) elif header_name == "via": self.via_header_seen = True # Agnadimos la cabecera via header_value += ", http/1.0 " + self.server_version self.__headers.append([header_name.capitalize(), header_value]) if self.DEBUG: Log.pdebug("OU header: %s - %s: %s" % (self.port, header_name.capitalize(), header_value)) elif header_name == "server": # la escribe directamente el servidor BaseHTTPServer if self.DEBUG: Log.pdebug("SU header: %s - %s: %s" % (self.port, header_name.capitalize(), header_value)) elif header_name == "set-cookie": from requests.cookies import get_cookie_header # Este bloque gestiona las cookies; Requests devuelve todas las cookies en un array 'set-cookie', pero indistinguible si hay varias. # para obtener todos los parámetros y reenviarlos, parseamos la cadena. def allindices(string, sub, listindex=[], offset=0): i = string.find(sub, offset) while i >= 0: listindex.append(i) i = string.find(sub, i + 1) return listindex # inicializamos el vector POS con valor 0 y longitud de la cadena POS = [0, len(header_value)] # Para cada una de las cookies encontradas en los headers... # Caso excepcional cuando la cookie está en la primera posición de la cadena: no la buscamos porque hemos añadido la posición 0, # así que buscaremos la cadena ' ,<COOKIE>=' y ' <COOKIE>=' for cookie in self.__response.cookies.keys(): # buscamos la cookie en formato ", cookie=" y agnadimos todas las posiciones al vector POS for i in allindices(header_value, ", " + cookie + "="): POS.append(i) # buscamos la cookie en formato " cookie=" y agnadimos todas las posiciones al vector POS for i in allindices(header_value, " " + cookie + "="): POS.append(i) # for header_nameey in resp.cooheader_nameies.header_nameeys(): # for i in allindices(header_value, ', '+header_nameey+'='): POS.append(i) # for i in allindices(header_value, header_nameey+'='): POS.append(i) # Eliminamos los valores duplicados en el array POS POS = list(set(POS)) # y lo ordenamos POS.sort() # ahora tenemos un array con las posiciones de las cookies a cortar while POS != []: parsed_cookie = header_value[POS[0] : POS[1]] # self.send_header('Set-Cookie',parsed_cookie) self.__headers.append(["Set-Cookie", parsed_cookie]) if self.DEBUG: Log.pdebug("\t... cookie: Set-cookie=%s" % (header_value[POS[0] : POS[1]])) # eliminamos las posiciones 0 y 1; como eliminamos primero el valor [0], el valor [1] # se convierte en la segunda llamada en [0] POS.remove(POS[0]) POS.remove(POS[0]) pass else: if self.DEBUG: Log.pdebug("OU header: %s - %s: %s" % (self.port, header_name.capitalize(), header_value)) self.__headers.append([header_name.capitalize(), header_value]) if not self.via_header_seen: # Agnadimos a cabecera via header_name = "Via" header_value = "http/1.0 " + self.server_version self.__headers.append([header_name.capitalize(), header_value]) if self.DEBUG: Log.pdebug("OU header: %s - %s: %s" % (self.port, header_name, header_value)) self.headers_have_been_parsed = True return
def force_shutdown(self): self.KEEP_RUNNING=False Log.pdebug("%s ServerHTTP Forced Shutdown...", time.asctime()) os._exit(0)
def BASIC(self,what): self.content = b'' self.content_lenght = 0 self.code = 0 self.processed_headers = [] self.processed_headers.clear() self.content_cached=False self.Allowed = 0 if (what==None): self.what='GET' else: self.what=what self.parse_query() # Comprobamos si nos están pidiendo nuestra URL # Por defecto no nos piden a nosotros selfquery = False ## TODO: aqui hay que cambiar que empiece por la cadena en vez de que sea la cadena ## TODO: cuando atacamos localhost:PUERTO (modo proxy), devuelve OK, pero cuando se ataca el servicio ## TODO: sin puerto, se devuelve como contenido las cabeceras if self.parsed_path.netloc in [ '127.0.0.1' , 'localhost', '' ]: # or '' ] selfquery = True; # TODO:: DESCOMENTAR ## La siguiente linea fuerza el uso de modo proxy ## selfquery = False # TODO:: DESCOMENTAR # Si es una dirección local, atendemos la petición HTTP ####################################################### if selfquery: if DEBUG: Log.pdebug(self.parsed_path) Log.pdebug("Local, %s %s" % (selfquery, self.what)) self.Allowed = self.handle_HTTP_AUTH() if DEBUG: Log.pdebug("autorizado by HTTP_AUTH: %s " % self.Allowed) if self.Allowed==1: # handler por defecto... service_handle_value="NOOP" service_handle_parms="" Log.pdebug("self.what: %s " % self.what) if self.what in ['GET', 'POST', 'HEAD']: # Para cada uno de los servicios que atenderemos... (LocalServices es una lista de servicios vs handlers) for URL in self.LocalServices: if DEBUG: Log.pdebug ("\tm%s" % URL.pattern) if URL.match(self.parsed_path.path): # Sustituimos el patron entre "/" y hacemos strip de los caracteres adicionales service_handle_value=re.sub(r"/[.]*$","",re.sub(r"^/+", "", URL.pattern.upper())) service_handle_parms=re.sub(r'(?i)'+URL.pattern, "", self.parsed_path.path) # Llamamos a la funcion que se llame svc_hndl_$(PATRON) # Por defecto, se llama a la funcion NOOP self.ServiceHandle[service_handle_value](self,service_handle_parms,self.parsed_path.query,Verb=self.what) service_handle_value = 'NOOP' else: self.do_OTHER() else: self.int_HEAD_HTTP_AUTH() # Tratamos la peticion como PROXY # ###################################################### else: if DEBUG: Log.pdebug(self.parsed_path) # Está autenticado? # Habilitamos la autenticacion o forzamos autenticado.. # TODO:: DESCOMENTAR self.Allowed = self.handle_PROXY_AUTH() if DEBUG: Log.pdebug("autorizado by PROXY_AUTH: %s " % self.Allowed) #self.Allowed = 1 # TODO:: DESCOMENTAR if self.Allowed == 1: self.client_headers = {} self.client_headers.clear() client_headers = Headers.ClientHeaders(self.headers.__str__(),debug=False, ip=self.client_address[0], port = self.client_address[1]) new_client_headers,client_cookies = client_headers.parse() if DEBUG: Log.pdebug('URL: %s: %s' % (self.client_address[1],self.path)) if DEBUG: Log.pdebug ('try request') fc = Cache.FileCache() # Filtramos el tipo de servicio y llamamos a un bloque o a otro... if ( self.what == 'GET' ): cache_content = b'' cache_headers = [] cache_headers.clear() self.content_cached = fc.is_cached(path=self.path, debug=False, ip=self.client_address[0], port=self.client_address[1]) if self.content_cached: cache_content, cache_headers = fc.get(path=self.path, debug=True, ip=self.client_address[0], port=self.client_address[1]) cache_lenght = len(cache_content) cache_code = 200 else: resp = requests.get(self.path, headers=new_client_headers, stream=True, allow_redirects=True) #fc.put(path=self.path, content=resp.content, headers=resp.headers, debug=True, ip=self.client_address[0], port=self.client_address[1]) elif ( self.what == 'POST' ): resp = requests.post(self.path, headers=new_client_headers, data=self.content, stream=True, allow_redirects=True) elif ( self.what == 'HEAD' ): resp = requests.head(self.path, stream=True, allow_redirects=True) if self.content_cached: self.content = bytes(cache_content) self.content_lenght = cache_lenght self.code = cache_code else: self.content = resp.content self.content_lenght = len(resp.content) self.code = resp.status_code if (self.code == requests.codes.ok): # enviamos el codigo self.send_response(self.code) self.processed_headers = [] self.processed_headers.clear() parsed_headers = [] could_cache=True if not self.content_cached: # Procesamos las cabeceras para reescribirlas '''if 'pragma' in resp.headers and resp.headers['pragma'] == 'no-cache': #print('Cache header: pragma ->%s' % resp.headers['pragma']) could_cache=False elif 'expires' in resp.headers and resp.headers['expires'] == '-1': #print('Cache header: expires ->%s' % resp.headers['expires']) could_cache=False #elif 'cache-control' in resp.headers: #print('\tCache header: cache-control ->%s' % resp.headers['cache-control']) #could_cache=False ''' parsed_headers = Headers.ServerHeaders(response=resp, debug=False, ip=self.client_address[0], port = self.client_address[1]) self.processed_headers = parsed_headers.parsed_headers() if could_cache: fc.put(path=self.path, content=resp.content, headers=self.processed_headers, debug=False, ip=self.client_address[0], port=self.client_address[1]) else: for header in cache_headers: header_key,header_value = str(header).split(': ',1) self.processed_headers.append([header_key,header_value]) # Enviamos todas las cabeceras reescritas for header_key,header_value in self.processed_headers: self.send_header(header_key, str(header_value).rstrip('\n')) # Fin de cabeceras self.end_headers() if self.what != 'HEAD' and self.code==200: self.wfile.write(self.content) else: self.int_HEAD_PROXY_AUTH() if DEBUG: Log.pdebug ("end") return
def do_CONNECT(self): o_port_default = None o_port = 80 self.parse_query() if DEBUG: Log.pdebug (self.parsed_path) Log.pdebug('%s:%s, ' % (self.client_address[0], self.client_address[1]) + 'Allow: %s, ' % self.Allowed + 'prxUSR: %10s, ' % self.proxy_user[0:9] + 'Cod: %3d, Size: %8d, ' % (self.code, self.content_lenght) + '??? CNT '+ self.path) # Tenemos schema? => eso nos fija el puerto por defecto en caso de no # venir definido en la cadena CONNECT... if self.parsed_path.scheme != '': o_port_default = socket.getservbyname(self.parsed_path.scheme) destination = self.parsed_path.netloc if (self.parsed_path.netloc!='') else self.parsed_path.path try: o_dest,o_port = destination.split(':', 1) except: o_dest = destination if (o_port_default!=None): o_port=o_port_default try: if DEBUG: Log.pdebug ('Outbound conection to %s:%s' % (o_dest, o_port)) self.server_socket = socket.create_connection((o_dest, o_port),timeout=3) except (socket.error, socket.herror, socket.gaierror) as e: if DEBUG: Log.pdebug ("Error %s" % e) self.send_response(404,'CONNECT error ['+str(e)+'] to '+o_dest+':'+str(o_port)) self.end_headers() except socket.timeout as e: if DEBUG: Log.pdebug ("Error %s" % e) self.send_response(504,'CONNECT Timeout ['+str(e)+'] to '+o_dest+':'+str(o_port)) #self.send_header('Content-Length', '0') self.end_headers() else: self.send_response(200,'CONNECT OK -> '+o_dest+':'+str(o_port)) self.send_header('Content-Length', '0') self.end_headers() self.server_wfile = self.server_socket.makefile('wb', self.wbufsize) #Log.pdebug('_Csrc: '+self.client_address[0] +',\tPermit: '+str(self.Allowed)+',\tprxUSR: '******',\tPRX: '+self.path) Log.pdebug('%s:%s, ' % (self.client_address[0], self.client_address[1]) + 'Allow: %s, ' % self.Allowed + 'prxUSR: %10s, ' % self.proxy_user[0:9] + 'Cod: %3d, Size: %8d, ' % (self.code, self.content_lenght) + 'PRX CNT '+ self.path) salir_bucle = False inputs = [self.connection, self.server_socket] while (inputs and not salir_bucle): # Wait for at least one of the sockets to be ready for processing if DEBUG: sys.stderr.write("waiting for the next event") #readable, writable, exceptional = select.select(inputs, [], inputs) r, w, e = select.select(inputs, [], inputs) if DEBUG: sys.stderr.write("select (i:%s, o:%s, e:%s'%(len(r),len(w),len(e))") if e != [] and not salir_bucle: # cualquiera que sea el error en los sockets de cliente o servidor, tenemos que salir.. if self.connection in e: if DEBUG: Log.pdebug("error socket cliente: cerrandolo") if server_socket in e: if DEBUG: Log.pdebug("error socket servidor: cerrandolo") if DEBUG: Log.pdebug(e) salir_bucle=True if r != [] and not salir_bucle: if DEBUG: Log.pdebug(r) if (self.connection in r) and not salir_bucle: if DEBUG: Log.pdebug('cliente tiene datos: leyendo cliente') try: sockdata = self.connection.recv(4096) if (sockdata): self.server_wfile.write(sockdata) else: if DEBUG: Log.pdebug("Cierre de socket cliente ordenado") salir_bucle=True except (socket.timeout, socket.error) as e: if DEBUG: Log.pdebug("error socket: %s" % (e)) salir_bucle=True if (self.server_socket in r) and not salir_bucle: if DEBUG: Log.pdebug('servidor tiene datos: leyendo servidor') try: sockdata = self.server_socket.recv(4096) if (sockdata): self.wfile.write(sockdata) else: if DEBUG: Log.pdebug("Cierre de socket servidor ordenado") salir_bucle=True except (socket.timeout, socket.error) as e: if DEBUG: Log.pdebug("error socket: %s" % (e)) salir_bucle=True if w != [] and not salir_bucle: if DEBUG: Log.pdebug(w) if DEBUG: Log.pdebug ("saliendo del bucle del socket...") self.server_wfile.close() self.server_socket.close() return