Пытаюсь написать прокси сервер.Проблема управления длиной контента - PullRequest
0 голосов
/ 25 февраля 2011

Я пытаюсь написать прокси-сервер на языке C под Linux.Это работало нормально (у меня было ощущение, что оно работало нормально), пока я не попробовал его для потоковой передачи мультимедиа.

Позвольте мне сначала рассказать о проблеме, а затем я перейду к потоковой передаче мультимедиа.Чтобы прочитать входящие данные с веб-сайта и переслать их фактическому клиенту, я делаю это

count = read(websitefd,buffer,BUFSIZ);

write(clientfd,buffer,count);` 

в непрерывном цикле while, пока не прочитаю все данные в этом сокете.

Сейчаспроблема заключается в том, что если реальный веб-сайт отправляет HTTP-пакет с полем длины контента в 1025 байтов и другой частью данных в других пакетах, то все равно я всегда жду BUFSIZ (8192 байта), а затем отправляю 8192 байта клиентской машине вместе.для обычного octet-stream он работает нормально, хотя я знаю, что это неправильный метод, потому что я должен пересылать пакеты так же, как и на реальном сервере.Таким образом, если реальный сервер отправляет мне 2 пакета размером 1024 и 1024 байта, я отправляю клиенту пакет из 2048 байтов с первым пакетом с заголовком HTTP, говорящим, что длина контента составляет 900 байтов (остальное все при условии заголовка http), но на самом делеЯ пересылаю пакет из 2048 байтов клиенту.Для типа контента: application / octet-stream он просто загружает все содержимое и отображает его в виде изображения или html-текста или просит меня сохранить его.

Когда клиент запрашивает потоковое мультимедиа, по вышеуказанной причине клиент не может воспроизвести видео.Так что мне теперь делать?Спасибо за чтение моего вопроса.Пожалуйста, помогите мне.:)

Ответы [ 2 ]

3 голосов
/ 25 февраля 2011

Во-первых, я настоятельно рекомендую использовать существующий прокси-сервер в качестве основы любой прокси-системы. Стандарт HTTP довольно сложен, гораздо больше, чем вы думаете. Если вы собираетесь внедрить прокси-сервер, сначала прочитайте RFC 2616 как минимум три раза.

Во-вторых, ваш прокси-сервер должен анализировать заголовки HTTP, чтобы выяснить, сколько он должен отправить. Три основных способа узнать объем передаваемых данных:

  • Если присутствует заголовок Content-Length, а заголовок Transfer-Encoding отсутствует: Заголовок Content-Length указывает объем данных, передаваемых в байтах. Просто зайдите в цикл копирования.
  • Если присутствует заголовок Transfer-Encoding: chunked: необходимо проанализировать заголовки фрагментов кодированной передачи . Это кодирование часто используется для потоковой передачи данных, когда общий размер заранее неизвестен. Он также часто используется для динамических данных, генерируемых скриптами.
  • Если присутствует какой-либо другой заголовок Transfer-Encoding: закройте соединение и сообщите об ошибке 500, если только вы не знаете, что это за кодировка.
  • Если заголовок Content-Length отсутствует, а заголовок Transfer-Encoding отсутствует: проверьте наличие Connection: close (должно присутствовать в HTTP / 1.1) и Connection: keep-alive (НЕ должно присутствовать в HTTP / 1.0 ). Если эти условия нарушаются, вызвать ошибку 500. В противном случае просто продолжайте передавать данные, пока сервер не закроет соединение.

Я намеренно делаю это немного обыденным - вы ДОЛЖНЫ прочитать стандарт, если внедряете прокси-сервер с нуля, или вы наверняка столкнетесь с несовместимостью браузера и / или пробелами в безопасности! Поэтому, пожалуйста, не делайте этого. Используйте lighttpd или лак или что-то в качестве основного прокси-сервера и просто напишите плагин для любой необходимой вам функциональности.

1 голос
/ 25 февраля 2011

Я полагаю, что мультимедиа передается порциями, т. Е. Отсутствует Content-Length и данные отправляются до завершения.Как сказал bdonlan, пожалуйста, прочитайте, как работают фрагментированные данные,

И я согласен, что HTTP довольно неприятен (из-за множества изменений и интерпретаций во времени)

...