Помогите с HTTP-перехватом прокси в Ruby? - PullRequest
2 голосов
/ 21 апреля 2010

У меня есть начало HTTP Intercepting Proxy, написанного на 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
}

Этот простой прокси, который я создал, анализирует назначение из HTTP-запроса, затем читает HTTP-ответ и выполняет логику на основе специальных HTML-тегов. Прокси-сервер работает по большей части, но, похоже, возникают проблемы с двоичными данными и HTTPS-соединениями.

Как я могу исправить эти проблемы?

Ответы [ 3 ]

3 голосов
/ 06 марта 2011

Во-первых, вам, вероятно, лучше построить существующую реализацию прокси-сервера Ruby HTTP. Один из них уже доступен в стандартной библиотеке Ruby, а именно WEBrick :: HTTPProxyServer . См., Например, этот связанный вопрос для реализации, основанной на том же классе: Прозрачный прокси Webrick .

Что касается прокси HTTPS, вы не можете сделать намного больше, чем просто передать необработанные байты. Поскольку HTTPS криптографически защищен, вы не можете проверить содержимое на уровне протокола HTTP. Это просто непрозрачный поток байтов.

1 голос
/ 13 февраля 2012

WEBrick блокирует ввод / вывод ... Это означает, что он не может передавать ответ. Например, если вы заходите на страницу YouTube, чтобы посмотреть видео, поток не будет перенаправлен в ваш браузер, пока прокси-сервер не загрузит все видео-видео. Если вы хотите, чтобы видео воспроизводилось в вашем браузере во время его загрузки, вам нужно искать неблокирующее решение ввода-вывода, такое как EventMachine. Для HTTPS решение немного сложнее, так как вам нужно разработать человека в середине прокси.

0 голосов
/ 09 июля 2016

Это был старый вопрос, но для полноты здесь приводится другой ответ.

Я реализовал прокси-сервер перехвата HTTP / HTTPS в Ruby, проект размещен в github .

Случай HTTP очевиден, перехват HTTPS осуществляется через сервер HTTPS, который действует как обратный прокси-сервер (и обрабатывает рукопожатие TLS).Т.е.

Client(e.g. Browser) <--> Proxy1 <--> HTTPS Reverse Proxy <--> Target Server

Как уже упоминал Валько, когда клиент подключается к HTTPS-серверу через прокси-сервер, вы увидите поток зашифрованных байтов (поскольку SSL обеспечивает сквозное шифрование).Но не все зашифровано, прокси-сервер должен знать, кому должен быть направлен поток байтов, поэтому клиент отправляет запрос CONNECT host:port (который является телом запроса потока SSL).

Хитростьздесь первый прокси перенаправит этот запрос на HTTPS Reverse Proxy вместо реального целевого сервера.Этот обратный прокси-сервер будет обрабатывать согласование SSL с клиентом, иметь доступ к расшифрованным запросам и отправлять копии (необязательно измененные версии) этих запросов на реальный целевой сервер, действуя как обычный клиент.Он получит ответы от целевого сервера, (необязательно) изменит ответы и отправит их обратно клиенту.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...