Самый точный способ перенаправления HttpRequests - PullRequest
0 голосов
/ 24 января 2012

Я работаю над решением для перенаправления http-запросов из моего браузера на другой компьютер. В двух словах: есть ли более точный способ отправки входящего запроса HttpListenerRequest в виде запроса HttpRequest клиенту?

Справочная информация. Браузер отправляет http-запросы 127.0.0.1:9666 (да, click'n'load), на которые должна ответить программа загрузки. В моем случае программа загрузки не работает на компьютере, на котором работает браузер. Такие инструменты переадресации портов у меня не работают: http://www.quantumg.net/portforward.php Поэтому я решил написать специальный редиректор click'n'load в C #. Моя проблема - перенаправить запрос браузера. ATM, я слушаю 127.0.0.1:9666, отправляю некоторую информацию клиенту, клиент перенаправляет ее в программу загрузчика, которая отвечает. (долгосрочная краткосрочная: это перенаправлено в браузер). Но использование предопределенных случаев для перенаправления только основной информации мне не совсем подходит. Должна быть возможность перенаправить весь запрос. Поэтому мне не нужно различать разные случаи, и это должно быть более точным. Есть ли другой способ перенаправить этот запрос, кроме копирования всех заголовков и свойств?

Сервер использует HttpListener для прослушивания запросов браузера. Затем сервер отправляет HttpReqest клиенту. Клиент использует HttpListener для прослушивания запросов сервера. Клиент отправляет HttpRequest в Downloader, использует GetResponse и отправляет его в качестве ответа на сервер, который отвечает браузеру. Я просмотрел некоторые функции в MSDN, но не нашел хорошего способа «скопировать весь запрос».

Так вот мой код проблемы:

Thread.Sleep(1500);
//Read client's/JDownloader's stream, send to browser/redirector
do
{
    Read = Outstream.Read(Buffer, 0, Buffer.Length);
    Totalr += Read;
    Instream.Write(Buffer, 0, Read);
    Sent += Read;
    // Bufferstr += ASCIIEncoding.ASCII.GetString(Buffer, 0, Read); debugging
} while (Read != 0);

Без Thread.Sleep, первое чтение возвращает 171 байт, которые были прочитаны (просто и точно HTTP-заголовок, длина буфера составляет 1024 байт). вторая итерация: при выполнении Outstream.Read ничего не происходит. Независимо от того, как долго я жду. Кажется, читатель ожидает трафика для получения, но нет трафика для приема (странно ...) Когда поток спит в течение 500-1500 мс, первое чтение возвращает 351 байт, которые были прочитаны (полный запрос http), а затем опять вторая итерация, ничего. Это происходит при чтении из NetworkStream браузера или JDownloader. Они никогда не возвращают 0. Грязный метод для получения этой работы состоит в том, чтобы заменить аргумент while на Read == Buffer.Length, грязный, потому что он потерпит неудачу, когда будут получены именно байты Buffer.Length (бесконечное ожидание снова, ура). Свойство DataAvailable также не всегда кажется правильным, иногда оно устанавливается в false, когда программа даже не читала что-то из потока, но были байты для приема (также странно ...) Любые другие идеи для правильного получения петель?


Nobody? краткое изложение моей проблемы: ни поток запросов браузера, ни поток ответов JDownloaders не возвращают 0. При попытке еще одного чтения программа просто ожидает получения большего количества байтов. Так что я не знаю отказоустойчивого метода для чтения всего потока. Простое повторение, пока количество считанных байтов не станет меньше длины буфера, приведет к ранее упомянутому бесконечному ожиданию байтов, когда streamlength% bufferlength == 0.

Кроме того, похоже, что JDownloader требуется больше времени для генерации ответа и записи его в поток, чем моя программа пытается прочитать поток. Так что я получу только часть потока. Еще одна попытка чтения приведет к, ура, бесконечному ожиданию байтов. Есть ли другой способ получить весь поток без статической задержки (через спящий поток)?

Ответы [ 2 ]

1 голос
/ 25 января 2012

То, что вы просите, - это в основном реализация прокси - создание хорошо работающего прокси - задача не из простых, так как вам придется понимать и обрабатывать HTTP и т. Д. В обоих направлениях.

Я бы порекомендовал использовать для этого ИЛИ существующую библиотеку ИЛИ какой-нибудь настраиваемый прокси:

1 голос
/ 25 января 2012

Можете ли вы просто открыть TcpListener и переслать необработанные байты? Таким образом, вам вообще не нужно беспокоиться о HTTP.

...