HTTP Proxy en Python

Temas sobre programación ( php, c, sql, html, perl, python, ruby, java, bash, etc ) y recursos ( herramientas, frameworks, hosting, cms, etc )

Moderadores: maiku, akodo

Responder
Avatar de Usuario
gonzalo340
Forista Nuevo
Forista Nuevo
Mensajes: 19
Registrado: Mar May 12, 2009 7:00 am

HTTP Proxy en Python

Mensaje por gonzalo340 »

Hola gente.

Estoy intentando hacer un proxy en python para navegar usando la configuracion de proxy de un navegador.
Para esto, uso las funciones de sockets de python. El script funciona y responde bien a las solicitudes que realiza el navegador, pero la carga de la pagina demora mucho, me gustaria que alguien que sepa me dijera como poder arreglar esto.

Aca les paso el script, son 2 archivos:

Archivo 1: ServerConnect.py

Código: Seleccionar todo

import socket
import re

def openPage(headers):
   regexp = re.search("Host:(.*)", headers)

   respuesta= ''
   
   if regexp:
      host = regexp.group(1).strip()
      vHost= host.split(":")
      port = 80
      if len(vHost) == 2:
	 port = int(vHost[1])
	 host = vHost[0]
	 
      SO_cliente = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

      SO_cliente.connect((host, port)) 	# Me conecto al servidor
      
      arrayHeaders= headers.split("\n")
      for h in arrayHeaders:
	 SO_cliente.send(h+"\n")
	 
      bufsize = 1024				# Size maximo que voy a recivir
      dataRec = ''
      
      while True:
	 data = SO_cliente.recv(bufsize)	# Datos que recivo del servidor
	 if not data: break
	 dataRec += data
	 
      SO_cliente.close()
      respuesta= dataRec
      
   return respuesta
Este archivo tiene la funcion para retornar el contenido de una pagina.

Archivo 2: Servidor.py

Código: Seleccionar todo

import socket
import threading
import ServerConnect


class ProxyServer ( threading.Thread ):
   def __init__(self):
      threading.Thread.__init__ ( self )
      puerto = 8000;
      self.soc = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
      self.soc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
      self.soc.bind( (socket.gethostname(), puerto ) )
      self.soc.listen(100)
      
   def run ( self ):
      while True:
	 channel, details = self.soc.accept()
	 recibido = channel.recv(2048)
	 print recibido
	 respondo = ServerConnect.openPage(recibido)
	 channel.send(respondo)
	 channel.close()
	 print respondo
   
ProxyServer().start()
Este otro es el que hay que ejecutar en la terminal.

Para correr el script solo hay que poner en la terminal: python Servidor.py

Editado -- Dom Abr 29, 2012 3:02 pm --

Los scripts que le comente se los pueden descargar de aqui:
https://sites.google.com/site/gonzalofp340/

Avatar de Usuario
mcun
Administrador
Administrador
Mensajes: 3888
Registrado: Lun Abr 19, 2010 12:30 am
Ubicación: En una de las nalgas del culo del mundo (según la Bersuit Vergarabat)
Contactar:

Re: HTTP Proxy en Python

Mensaje por mcun »

pues la verdad que no entiendo como funciona ?
Los programadores de verdad no documentan. La documentación es para los idiotas que no pueden leer un volcado de memoria.

Trusted Network and Developer | Lee el Reglamento !! |WIKI-EL | Twitter @mr_mcun
Debian + TTY | ArchLinux + awesome | openSUSE + Gnome-Shell | Linux User #508809

Avatar de Usuario
gonzalo340
Forista Nuevo
Forista Nuevo
Mensajes: 19
Registrado: Mar May 12, 2009 7:00 am

Re: HTTP Proxy en Python

Mensaje por gonzalo340 »

mcun te explico como hacerlo funcionar.

Lo primero que tienes que hacer es descargarte los 2 scripts ( entra a esta pagina https://sites.google.com/site/gonzalofp340/).

Luego tienes que ir a la configuracion de proxy de tu navegador.
Si usas firefox tienes que ir a: Editar -> Preferencias, ir a la pestaña "Avanzadas"
Luego hay otra pestaña que dice "Red" y en donde dice "Configurar como firefox se conectara a internet" le das al boton Configurar.

Ahi tienes que marcar Configuracion manual del proxy y en las cajas que se activa colocas: Proxy HTTP: localhost, Puerto: 8000 (Este es el puerto que esta seteado en el script Servidor.py)

y luego pones donde dice "Usar el mismo proxy para todos los protocolos", das aceptar y listo.

Con estos pasos ya tienes configurado el navegador para que se conecte a trabes del proxy en el puerto 8000.
Ahora, para que el proxy quede escuchando en el puerto 8000, tienes que abrir un terminal y poner este comando para ejecutar el script: python Servidor.py.
Cuando coloques una url en el navegador, vas a ver en la consola las peticiones que el navegador esta enviando, y luego la respuesta que el servidor le devuelve al navegador.

Saludos.
Cualquier otra consulta a las ordenes, espero que puedas ayudarme para que el proxy responda mas rapido.

Avatar de Usuario
hipersayan_x
Forista Legendario
Forista Legendario
Mensajes: 1905
Registrado: Vie Abr 27, 2007 7:00 am
Contactar:

Re: HTTP Proxy en Python

Mensaje por hipersayan_x »

En ServerConnect.py linea 21

Código: Seleccionar todo

arrayHeaders= headers.split("\n")

for h in arrayHeaders:
    SO_cliente.send(h+"\n")
No tiene ningún sentido que partas la cabecera linea por linea y después la vuelvas a enviar linea por linea, enviala directamente.

Código: Seleccionar todo

SO_cliente.send(headers)
Desarrollo en Qt: Qt Developer Network
Mis proyectos: github | SourceForge.net

Avatar de Usuario
gonzalo340
Forista Nuevo
Forista Nuevo
Mensajes: 19
Registrado: Mar May 12, 2009 7:00 am

Re: HTTP Proxy en Python

Mensaje por gonzalo340 »

Hola hipersayan_x, gracias por responder.

Hise lo que me dijistes, pero el proxy sigue respondiendo lento.
¿Vos lo probastes para ver si te responde lento tambien?
¿Alguna otra idea para solucionarlo?

Avatar de Usuario
mcun
Administrador
Administrador
Mensajes: 3888
Registrado: Lun Abr 19, 2010 12:30 am
Ubicación: En una de las nalgas del culo del mundo (según la Bersuit Vergarabat)
Contactar:

Re: HTTP Proxy en Python

Mensaje por mcun »

mcun te explico como hacerlo funcionar.

Lo primero que tienes que hacer es descargarte los 2 scripts.......................
Si eso fue exactamente lo que hice, creo que el problema era que tenia la nick en modo promiscuo ayer...

Como sea hoy funciono, es una forma de decir, en realidad me dio un error 302 y tu app lanzo una excepción.
el log completo --> http://pastebin.com/FG8hNas5

Código: Seleccionar todo

Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 551, in __bootstrap_inner
    self.run()
  File "Servidor.py", line 20, in run
    respondo = ServerConnect.openPage(recibido)
  File "/home/mcun/Descargas/ServerConnect.py", line 29, in openPage
    data = SO_cliente.recv(bufsize)	# Datos que recivo del servidor
error: [Errno 104] Connection reset by peer

Los programadores de verdad no documentan. La documentación es para los idiotas que no pueden leer un volcado de memoria.

Trusted Network and Developer | Lee el Reglamento !! |WIKI-EL | Twitter @mr_mcun
Debian + TTY | ArchLinux + awesome | openSUSE + Gnome-Shell | Linux User #508809

Avatar de Usuario
gonzalo340
Forista Nuevo
Forista Nuevo
Mensajes: 19
Registrado: Mar May 12, 2009 7:00 am

Re: HTTP Proxy en Python

Mensaje por gonzalo340 »

hola mcun.

No se cual es el problema exactamente con lo que te paso, pero trata de entrar a paginas que devuelvan un codigo "200 OK" en la cabecera, o sea que no realice ninguna redirección.

Intenta entrar a http://www.php.net por ejemplo.
Contame que resultado te da.

Saludos

Avatar de Usuario
mcun
Administrador
Administrador
Mensajes: 3888
Registrado: Lun Abr 19, 2010 12:30 am
Ubicación: En una de las nalgas del culo del mundo (según la Bersuit Vergarabat)
Contactar:

Re: HTTP Proxy en Python

Mensaje por mcun »

ahora si "funciono" pues no carga los css de la página
Imagen

no se cual es el problema pero va por le lado de que pierde la conexión... se demora mucho con el Proxy-Connection: Keep-Alive
tal vez no estés implementando bien los threand ...

te dejo un code que encontré puede serte útil para comparar...no lo probé

http://code.google.com/p/python-proxy/s ... onProxy.py
Los programadores de verdad no documentan. La documentación es para los idiotas que no pueden leer un volcado de memoria.

Trusted Network and Developer | Lee el Reglamento !! |WIKI-EL | Twitter @mr_mcun
Debian + TTY | ArchLinux + awesome | openSUSE + Gnome-Shell | Linux User #508809

Avatar de Usuario
hipersayan_x
Forista Legendario
Forista Legendario
Mensajes: 1905
Registrado: Vie Abr 27, 2007 7:00 am
Contactar:

Re: HTTP Proxy en Python

Mensaje por hipersayan_x »

Ok, probado, en ServerConnect.py

Código: Seleccionar todo

  while True:
    data = SO_cliente.recv(bufsize)   # Datos que recivo del servidor
    if not data: break
    dataRec += data
Después de recibir los datos, se queda clavado en data = SO_cliente.recv(bufsize), lo que podrías intentar sería parsear la cabecera en busca del campo Content-Length y leer solo la cantidad justa y necesaria de datos.
Desarrollo en Qt: Qt Developer Network
Mis proyectos: github | SourceForge.net

Avatar de Usuario
gonzalo340
Forista Nuevo
Forista Nuevo
Mensajes: 19
Registrado: Mar May 12, 2009 7:00 am

Re: HTTP Proxy en Python

Mensaje por gonzalo340 »

Gracias a mcun y hipersayan_x por responder.

Voy a vichar el codigo del proxy ese para compararlo con el mio.

Muchas gracias.

Avatar de Usuario
mcun
Administrador
Administrador
Mensajes: 3888
Registrado: Lun Abr 19, 2010 12:30 am
Ubicación: En una de las nalgas del culo del mundo (según la Bersuit Vergarabat)
Contactar:

Re: HTTP Proxy en Python

Mensaje por mcun »

revisando el código, no entiendo por que defines en Servidor.py --> recibido = channel.recv(2048) , 2048 byts ,
Los programadores de verdad no documentan. La documentación es para los idiotas que no pueden leer un volcado de memoria.

Trusted Network and Developer | Lee el Reglamento !! |WIKI-EL | Twitter @mr_mcun
Debian + TTY | ArchLinux + awesome | openSUSE + Gnome-Shell | Linux User #508809

Avatar de Usuario
hipersayan_x
Forista Legendario
Forista Legendario
Mensajes: 1905
Registrado: Vie Abr 27, 2007 7:00 am
Contactar:

Re: HTTP Proxy en Python

Mensaje por hipersayan_x »

mcun escribió:revisando el código, no entiendo por que defines en Servidor.py --> recibido = channel.recv(2048) , 2048 byts ,
Es por el mismo protocolo TCP, como vos no sabes cuantos datos vas a recibir, definís un tamaño máximo de datos que pensás que vas a recibir, el tamaño que le des no tiene mucha importancia, por lo general se usan bufferes de 1024 bytes pero también son validos bufferes de otros tamaños, mayores o menores. El problema viene cuando vos intentas pedir nuevos datos y el servidor (o el cliente según sea el caso) ya cortó la comunicación con vos, entonces el programa queda clavado en recv() esperando nuevos datos que nunca van a llegar.
Desarrollo en Qt: Qt Developer Network
Mis proyectos: github | SourceForge.net

Avatar de Usuario
mcun
Administrador
Administrador
Mensajes: 3888
Registrado: Lun Abr 19, 2010 12:30 am
Ubicación: En una de las nalgas del culo del mundo (según la Bersuit Vergarabat)
Contactar:

Re: HTTP Proxy en Python

Mensaje por mcun »

yo tenia entendido que era el limite por parte de paquete, no el tamaño total del paquete que se espera,junto con ello leí por allí que fragmentar los datos en paquetes altos provocan comportamientos indeseables..lastima no encuentre el link XD
Los programadores de verdad no documentan. La documentación es para los idiotas que no pueden leer un volcado de memoria.

Trusted Network and Developer | Lee el Reglamento !! |WIKI-EL | Twitter @mr_mcun
Debian + TTY | ArchLinux + awesome | openSUSE + Gnome-Shell | Linux User #508809

Responder
  • Temas similares
    Respuestas
    Vistas
    Último mensaje