Пытаюсь написать прокси сервер. Проблема управления длиной контента
Я пытаюсь написать прокси-сервер на языке 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-текста или просит меня сохранить его.
Когда клиент запрашивает потоковое мультимедиа, по вышеуказанной причине клиент не может воспроизвести видео. Так что мне теперь делать? Спасибо за чтение моего вопроса. Пожалуйста, помогите мне.:)
2 ответа
Во-первых, я настоятельно рекомендую использовать существующий прокси-сервер в качестве основы любой прокси-системы. Стандарт HTTP довольно сложен, гораздо больше, чем вы думаете. Если вы собираетесь внедрить прокси-сервер, сначала прочтите RFC 2616 как минимум три раза.
Во-вторых, ваш прокси-сервер должен анализировать заголовки HTTP, чтобы выяснить, сколько он должен отправить. Три основных способа узнать объем передаваемых данных:
- Если
Content-Length
заголовок присутствует и нетTransfer-Encoding
Заголовок присутствует:Content-Length
заголовок указывает, сколько данных для передачи в байтах. Просто зайдите в цикл копирования. - Если
Transfer-Encoding: chunked
присутствует заголовок: Вы должны проанализировать заголовки фрагментов кодировки передачи chunked. Это кодирование часто используется для потоковой передачи данных, когда общий размер не известен заранее. Он также часто используется для динамических данных, генерируемых скриптами. - Если какой-то другой
Transfer-Encoding
присутствует заголовок: закройте соединение и сообщите об ошибке 500, если вы не знаете, что это за кодировка. - Если
Content-Length
заголовка нету и нетуTransfer-Encoding
заголовок присутствует: проверьтеConnection: close
(должен присутствовать в HTTP/1.1) иConnection: keep-alive
(НЕ должно присутствовать в HTTP/1.0). Если эти условия нарушаются, вызвать ошибку 500. В противном случае просто продолжайте передавать данные, пока сервер не закроет соединение.
Я намеренно делаю это немного смутно - вы ДОЛЖНЫ прочитать стандарт, если внедряете прокси-сервер с нуля, или вы наверняка столкнетесь с несовместимостью браузера и / или пробелами в безопасности! Поэтому, пожалуйста, не делайте этого. Используйте lighttpd или лак или что-то в качестве основного прокси-сервера, и просто напишите плагин для любой необходимой вам функциональности.
Я полагаю, что мультимедиа передается порциями, т.е. Content-Length отсутствует, и данные отправляются до завершения. Как сказал bdonlan, пожалуйста, прочитайте, как работают чанкованные данные,
И я согласен, что HTTP довольно неприятный (из-за многих изменений и интерпретаций во времени)