html - rails - ruby http request
Ayuda con Proxy HTTP Intercepting en Ruby? (3)
Tengo el comienzo de un Proxy de Interceptación de HTTP escrito en Ruby:
require ''socket'' # Get sockets from stdlib
server = TCPServer.open(8080) # Socket to listen on port 8080
loop { # Servers run forever
Thread.start(server.accept) do |client|
puts "** Got connection!"
@output = ""
@host = ""
@port = 80
while line = client.gets
line.chomp!
if (line =~ /^(GET|CONNECT) .*(/.com|/.net):(.*) (HTTP//1.1|HTTP//1.0)$/)
@port = $3
elsif (line =~ /^Host: (.*)$/ && @host == "")
@host = $1
end
print line + "/n"
@output += line + "/n"
# This *may* cause problems with not getting full requests,
# but without this, the loop never returns.
break if line == ""
end
if (@host != "")
puts "** Got host! (#{@host}:#{@port})"
out = TCPSocket.open(@host, @port)
puts "** Got destination!"
out.print(@output)
while line = out.gets
line.chomp!
if (line =~ /^<proxyinfo>.*<//proxyinfo>$/)
# Logic is done here.
end
print line + "/n"
client.print(line + "/n")
end
out.close
end
client.close
end
}
Este simple proxy que hice analiza el destino de la solicitud HTTP, luego lee la respuesta HTTP y realiza la lógica basada en etiquetas HTML especiales. El proxy funciona en su mayor parte, pero parece tener problemas para tratar con datos binarios y conexiones HTTPS.
¿Cómo puedo solucionar estos problemas?
WEBrick bloquea la E / S ... Esto significa que no puede transmitir la respuesta. Por ejemplo, si vas a una página de youtube para ver un video, la transmisión no se reenviará a tu navegador hasta que el proxy haya descargado todo el video. Si desea que el video se reproduzca en su navegador durante la descarga, debe buscar una solución de E / S no bloqueante como EventMachine. Para HTTPS, la solución es un poco complicada ya que debes desarrollar un hombre en el proxy intermedio.
Esta era una vieja pregunta, pero a los fines de completarla, va otra respuesta.
Implementé un proxy de interceptación HTTP / HTTPS en Ruby, el proyecto está alojado en github .
El caso de HTTP es obvio, la interceptación de HTTPS se lleva a cabo a través de un servidor HTTPS que actúa como un proxy inverso (y maneja el protocolo de enlace TLS). Es decir
Client(e.g. Browser) <--> Proxy1 <--> HTTPS Reverse Proxy <--> Target Server
Como mencionó Valko, cuando un cliente se conecta a un servidor HTTPS a través de un proxy, verá una secuencia de bytes cifrados (dado que SSL proporciona cifrado de extremo a extremo). Pero no todo está encriptado, el proxy necesita saber a quién debe reenviarse la secuencia de bytes, por lo que el cliente emite un CONNECT host:port
solicitud de CONNECT host:port
(siendo el cuerpo de la solicitud la secuencia SSL).
El truco aquí es que el primer proxy reenviará esta solicitud al HTTPS Reverse Proxy
lugar del servidor de destino real. Este proxy inverso manejará la negociación de SSL con el cliente, tendrá acceso a las solicitudes descifradas y enviará copias (versiones opcionalmente alteradas) de estas solicitudes al servidor de destino real actuando como un cliente normal. Recibirá las respuestas del servidor de destino, (opcionalmente) alterará las respuestas y las enviará al cliente.
En primer lugar, probablemente sería mejor construir sobre una implementación de proxy de Ruby HTTP existente. Uno de ellos ya está disponible en la biblioteca estándar de Ruby, a saber, WEBrick :: HTTPProxyServer . Vea, por ejemplo, esta pregunta relacionada para una implementación basada en esa misma clase: Webrick proxy transparente .
Con respecto al proxying HTTPS, no puede hacer mucho más que simplemente pasar los bytes sin formato. Como HTTPS está protegido criptográficamente, no puede inspeccionar los contenidos en el nivel de protocolo HTTP. Es solo una corriente opaca de bytes.