HTTP Content-Length服务的大小不正确?

时间:2010-08-09 12:49:13

标签: c++ http qt http-headers httpresponse

我正在使用QTcpSocket通过HTTP在本地提供一些文件。我的问题是只有wget正确下载文件,firefox会在末尾添加四个额外的字节。这是我发送的标题:

  HTTP/1.0 200 Ok
  Content-Length: 382917;
  Content-Type: application/x-shockwave-flash;
  Content-Disposition: attachment; filename=file.swf;

这是用于发送响应的代码:

        QTextStream os(socket);
        os.setAutoDetectUnicode(true);

        QString name = tokens[1].right(tokens[1].length() - 1);
        QString resname = ":/" + name; // the served file is a Qt resource
        QFile f(resname); f.open(QIODevice::ReadOnly);

        os << "HTTP/1.0 200 Ok\r\n" <<
              "Content-Length: " << f.size() << ";\r\n" <<
              "Content-Type: application/x-shockwave-flash;\r\n" <<
              "Content-Disposition: attachment; filename=" << name << 
              ";\r\n\r\n";

        os.flush();

        QDataStream ds(socket);

        ds << f.readAll();

        socket->close();

        if (socket->state() == QTcpSocket::UnconnectedState)
        {
            delete socket;
        }

如上所述,wget正确无误并正确下载文件。问题是Firefox(和我的目标应用程序,一个Flash ActiveX实例)没有。

四个额外字节始终相同:4E E9 A5 F4

Hex dump http://www.freeimagehosting.net/uploads/a5711fd7af.gif

我的问题是我做错了什么,为了做到这一点我应该改变什么?提前谢谢。

3 个答案:

答案 0 :(得分:1)

您不应该用分号终止这些行。乍一看,这似乎是最可能的问题。

我对QDataStream(或一般的QT)了解不多,但是快速查看QDataStream文档提到了运算符&lt;&lt;(char const *)。如果您将一个以空字符结尾的字符串传递给QDataStream,那么您几乎肯定会越过最终缓冲区的末尾。

尝试使用QDataStream :: writeRawBytes()。

如果删除分号,则客户端应至少读取响应的正确字节数,并忽略最后四个字节。

我也忽略了“内容处理”。这是一个MIME事物,而不是HTTP事物。

答案 1 :(得分:1)

所以我找到了问题的整个解决方案,我认为有人可能需要它,所以这里是:

第一个问题是四个额外字节。这样做的原因是,根据QDataStream documentation,“写入流的每个项目都是以预定义的二进制格式编写的,这取决于项目的类型”。当QFile.readAll()返回QByteArray时,QDataStream.operator<<按以下格式编写了该对象:

  • 如果字节数组为空:0xFFFFFFFF(quint32)
  • 否则:数组大小(quint32)后跟数组字节,即大小字节

link

因此,四个额外字节是quint32的四个字节,表示数组大小。

根据janm的回答,解决方案是使用writeRawBytes()函数。

QDataStream ds(socket);
ds.writeRawData(f.readAll().data(), f.size());

Wget可能是第一次正确,因为它严格执行HTTP标头的Content-Length字段,而显然firefox没有。

第二个问题是,尽管有正确的标题和工作套接字,但Flashplayer根本没有显示所需的内容。我尝试了各种领域以使其工作,并注意到通过上传到真实的服务器,它可以正常工作。我从服务器和tadaa复制了标题!有用。这是标题:

  HTTP/1.1 200 OK
  Server: Apache/2.2.15 (Fedora)
  Accept-Ranges: bytes
  Content-Length: 382917
  Content-Type: application/x-shockwave-flash
  Keep-Alive: timeout=15, max=100
  Connection: Keep-Alive

起初我只尝试将版本设置为1.1,但这没有帮助。可能这是保持活力的事情,但老实说,只要它有效,我根本不关心:)。

答案 2 :(得分:0)

该行末尾不应有任何分号。

相关问题