Пытаюсь написать прокси сервер. Проблема управления длиной контента

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

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

count = read(websitefd,buffer,BUFSIZ);

write(clientfd,buffer,count);` 

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

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

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


person Durin    schedule 25.02.2011    source источник


Ответы (2)


Во-первых, я настоятельно рекомендую использовать существующий прокси-сервер в качестве основы любой прокси-системы. Стандарт 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. В противном случае просто продолжайте передавать данные, пока сервер не закроет соединение.

Я намеренно делаю это немного неопределенным - вы ДОЛЖНЫ прочитать стандарт, если вы внедряете прокси-сервер с нуля, иначе вы, безусловно, привнесете несовместимость браузера и/или дыры в безопасности! Так что, пожалуйста, не делай этого. Используйте http://redmine.lighttpd.net/wiki/1/Docs%3aModProxy или лак или что-то вроде основного прокси-сервера, и просто напишите плагин для любой необходимой вам функциональности.

person bdonlan    schedule 25.02.2011
comment
большое спасибо @bdonlan. Я действительно искал такой ответ, который все проясняет для меня. Обязательно прочту спецификацию. Спасибо еще раз. Если бы я мог, я проголосовал за этот ответ 10 раз. - person Durin; 25.02.2011
comment
На самом деле я принял решение написать свой собственный прокси, потому что не смог найти библиотеку прокси-сервера. Можете ли вы предложить мне несколько имен и ссылок? - person Durin; 25.02.2011
comment
@Anirudh, я добавил несколько ссылок в конце. Если этого недостаточно, пожалуйста, не стесняйтесь открывать еще один вопрос, запрашивая указатели - обязательно предоставьте некоторые подробности о том, для чего вы собираетесь использовать прокси, чтобы люди могли дать более конкретные советы :) - person bdonlan; 25.02.2011

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

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

person AbiusX    schedule 25.02.2011