| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Сети > Не работает простой прокси-сервер |
| Автор: Gwynbleiddd 5.3.2012, 21:39 | ||||||||||
| Добрый вечер Написал простой прокси. Идея такова: 0. Запускаем Оперу и в настройках указываем наш прокси-сервер 1. Получаем запрос от клиента 2. Разбираем его по строчкам 3. "Склеиваем" новый запрос 2. Передаём этот запрос хосту 3. Принимаем ответ хоста 4. Передаём ответ клиенту Когда пробовал на Денвере - то всё прекрасно работает. Но вот когда пытаешься открыть www.ya.ru или www.rambler.ru, например, то ничего не выходит, браузер показывает просто белую страницу :( И вторая проблема: если после того, как отработает функция ParserRequest, вывести на экран массив totalbuf, то в нём содержится только первая строка запроса + User-Agent. Всё остальное как будто затирается. В чём может быть причина? Пример запроса от браузера:
Вот ответ www.ya.ru на этот запрос:
Далее идёт следующий запрос от браузера:
И соответственно ответ на него:
Вот код прокси:
Сразу пояснения: 1. Необходимо разбирать запрос 2. Если отсылать оригинальный запрос, то www.ya.ru отвечает "Bad Request, видимо - на отсутствие параметра Pragma. Поэтому когда "склеиваем" новый запрос, вставляем этот параметр вручную Буду признателен за помощь Спасибо. |
| Автор: boostcoder 5.3.2012, 21:55 |
| для начала, отформатируй код так, чтоб строки вмещались в ширину страницы. |
| Автор: Gwynbleiddd 5.3.2012, 22:23 |
| Поправил В будущем учту, спасибо |
| Автор: boostcoder 5.3.2012, 22:32 |
| если отключить все, оставив только перегонку трафа - браузер с проксей работает как надо? |
| Автор: Gwynbleiddd 5.3.2012, 23:08 | ||||||||
| Сейчас отключил функцию ParserRequest и UnionModifiedRequest Запрос от браузера:
Ответ сервера:
И следом идёт второй запрос от браузера:
И ответ на него:
|
| Автор: boostcoder 5.3.2012, 23:13 |
| лень вникать. скажи просто: да/нет? |
| Автор: Gwynbleiddd 6.3.2012, 06:28 |
| Нет, когда убираешь всё лишнее, то всё равно просто белая страница |
| Автор: boostcoder 6.3.2012, 09:33 |
| вот и славно. с этого и начнем. |
| Автор: boostcoder 6.3.2012, 13:41 | ||
что выводится в консоль этой строкой? |
| Автор: feodorv 6.3.2012, 15:25 |
+1 Слабо верится, что яндексовские куки ограничиваются одним yandexuid. Потом, HTTP работа с прокси немного отличается от прямого HTTP запроса. Поэтому стОит взглянуть на полный запрос от браузера... |
| Автор: feodorv 6.3.2012, 16:37 | ||
| Короче, на данном этапе всё портит 118 строка: Лечится так:
|
| Автор: Gwynbleiddd 21.3.2012, 15:46 | ||||||||
| Прошу прощения, остался без компьютера на 2 недели - только сейчас смог снова добраться до проекта. 1. Вот то, что выводиться в консоль строкой:
2. Поправил в коде
Но ничего не изменилось, по-прежнему просто белая страница. 3. По поводу одного чтения функцией
А как тогда сделать так, чтобы чтение происходило до тех пор, пока сервер посылает ответ? 4. Как можно избавиться от ошибочного кода? Голова уже кругом, не понимаю как наконец сделать работающую программу. В какую сторону копать, на что обратить внимание, что передать? Читал статьи по сетевому программированию, так же книгу Эффективное программирование TCP\IP Шнейдера - но везде либо самые основы по поводу использования функций accept, listen и т.д., либо совсем простые примеры типа эхо-сервера. |
| Автор: feodorv 22.3.2012, 16:55 | ||||
Даже не знаю, что сказать. У меня весьма успешно что-то отображается... Правда, не yandex.ru, а ya.ru.
Ох, для начала я бы посоветовал заняться заголовком Connection, чтобы исключить keep-alive. Во-воторых, стОит сделать цикл чтения-записи, пока есть данные. В-третьих, стОит подумать о многопоточности... Правда, тогда получается уже не простой прокси-сервер))) Ну и, конечно, принтфов побольше, а то непонятно, что происходит. |
| Автор: Gwynbleiddd 25.3.2012, 20:05 | ||
| Спасибо, будем разбираться. А ещё такой вопрос. Есть допустим у нас буффер размера 4096 байт: recvbuf[4096]. Мы выполняем команду
Т.е. пока будут идти данные, мы будем записывать их в наш буффер. Но если размер ответа от сервера будет больше, чем 4096 байт? Увеличить первоначальный размер буффера? Или можно как-то более эффективно организовать приём ответа? |
| Автор: feodorv 31.3.2012, 07:59 | ||||
Именно! Ну, Вы как-то пытаетесь всё запихнуть в один буфер за один присест. Зачем? Чем стандартная схема плоха:
И нет нужды читать по одному байту, можно сразу sizeof(buf) читать. Но, опять таки, обращаю Ваше внимание на keep-alive. Если он включён, то одно соездинение может обработать несколько запрос-ответов, и нужно анализировать заголовок Content-Length, чтобы понять, где проходит граница, ну и соединение не закрывать до тех пор, пока Connection не станет closed. Проще keep-alive не поддерживать. |
| Автор: Gwynbleiddd 15.4.2012, 13:23 | ||||
| Переписал частично код, старые проблемы ушли, появились новые (( С некоторыми сайтами, с тем же www.ya.ru, работает нормально. На всех остальных же выскакивает ошибка "Необработанное исключение в "0x775c15de" в "Proxy.exe": 0xC0000005: Access violation." вот в этом месте:
Правильно ли я понимаю, что ошибка связана с тем, что разные потоки пытаются одновременно работать с recvbuf и recvbuf2? Как можно исправить её? Код программы:
Дополнительные фцнкции по разбору запроса и созданию нового не стал включать, там всё просто |
| Автор: feodorv 15.4.2012, 23:25 | ||||
Ну так нужно же проверять на переполнение:
А то так можно читать и читать... до access violation)))) PS Смысла читать по-байтово - нет. Совсем нет... |
| Автор: Gwynbleiddd 17.4.2012, 21:46 | ||
Переделал. Если не побайтово - то значит вот так?
В таком случае если открываю рамблер или яндекс, то ноут во время загрузки начинает пищать системным динамиком раза 4. А когда сат загрузится, то программа вылетает. Вроде работает, но эти завершения работы непонятные не нравятся ( |
| Автор: feodorv 18.4.2012, 20:45 | ||||||||
Тааак))) Смотрим подпрограмму Recv:
Бог с ним, что в виндах используется select и всё такое. Интересно, а Вы смотрите на предупреждения, которые выдаёт компилятор?))) Если rc не 0, то return recv(clientsocket, recvbuf, size, 0); - очень хорошо. А если 0, то что возвращается? Мусор? Если rc случилась в виде SOCKET_ERROR, то возвращается -1, допустим. return recv(...), допустим. Но как это совмещается с таким использованием Recv:
Если из Recv вернётся -1 или SOCKET_ERROR, то цикл продолжится, а в его теле:
|