试图编写代理服务器。内容长度管理问题

时间:2011-02-25 15:02:04

标签: c http streaming proxy-server

我正在尝试用Linux下的C语言编写代理服务器。它工作正常(我觉得它工作正常),直到我尝试流媒体。

Lemme首先告诉问题,然后我将跳转到流媒体。 要从网站读取传入数据并将其转发给实际客户端,我执行此操作

count = read(websitefd,buffer,BUFSIZ);

write(clientfd,buffer,count);` 

在一个连续的while循环中,直到我读取该套接字上的所有数据。

现在的问题是,如果实际网站发送内容长度字段为1025字节的HTTP数据包,而其他数据包中的其他数据部分仍然等待BUFSIZ(8192字节)然后我向客户端发送8192字节一起机器。对于普通octet-stream它工作正常,即使我知道它不是正确的方法,因为我应该转发与实际服务器相同的数据包。因此,如果实际服务器发送给我2个大小为1024和1024字节的数据包,我向客户端发送一个2048字节的数据包,其中第一个数据包带有HTTP标头,表示内容长度为900字节(其余全部是http标头假设)但实际上我将一个2048字节的数据包转发给客户端。对于内容类型:application / octet-stream,它只是下载整个内容并将其显示为图像或html文本或要求我保存它。

当客户端请求流媒体时,由于上述原因客户端无法播放视频。那我现在该怎么办?感谢您阅读我的问题。请帮帮我。 :)

2 个答案:

答案 0 :(得分:3)

首先,我强烈建议使用现有的代理服务器作为任何代理系统的基础。 HTTP标准非常复杂,远远超出您的意识。如果您要实现代理服务器,请先阅读RFC 2616至少三次。

其次,您的代理服务器必须解析HTTP标头以确定它必须发送多少。了解要发送多少数据的三种主要方法如下:

  • 如果存在Content-Length标头且不存在Transfer-Encoding标头:Content-Length标头指定以字节为单位传输的数据量。只需进入循环复制。
  • 如果存在Transfer-Encoding: chunked标头:您必须解析chunked transfer encoding块标头。此编码经常用于流数据,其中总大小未提前知道。它也经常用于脚本生成的动态数据。
  • 如果存在其他Transfer-Encoding标头:关闭连接并报告500错误,除非您知道该编码是什么。
  • 如果没有Content-Length标头,并且没有Transfer-Encoding标头:请检查Connection: close(必须在HTTP / 1.1中)和Connection: keep-alive(不得出现在HTTP / 1.0中)。如果违反了这些条件,则触发500错误。否则只是继续传递数据,直到服务器关闭连接。

我故意让这个有点笨拙 - 如果你从头开始实现代理服务器,你必须阅读标准,否则你肯定会引入浏览器不兼容性和/或安全漏洞!所以,请不要这样做。使用lighttpdvarnish或其他东西作为核心代理服务器,只需为您需要的任何功能编写插件。

答案 1 :(得分:1)

我认为媒体是以块的形式传输的,即不存在Content-Length,数据发送直到完成。 正如bdonlan所说,请阅读分块数据的工作原理,

我同意HTTP非常讨厌(由于许多变化和解释及时)