【问题标题】:Http range header requests entire fileHttp范围标头请求整个文件
【发布时间】:2018-01-30 21:05:01
【问题描述】:

我正在使用 codeplex 1.1 版中的 c# webserver。我已经实现了 Accept-Range 标头并且它确实有效。但是,当我使用 wireshark(版本 1.4.1(SVN Rev 34476 from /trunk-1.4))捕获流量时,我看到以下内容:

GET /movies/i_am_legend%20dvd/main.m4v HTTP/1.1
Host: 10.100.1.199:8081
Accept: */*
Range: bytes=0-1
Accept-Encoding: identity
Connection: keep-alive
User-Agent: AppleCoreMedia/1.0.0.9B206 (iPad; U; CPU OS 5_1_1 like Mac OS X; nl_nl)
X-Playback-Session-Id: 9CED81CC-BFAE-4CF6-A477-0EA62B2C652F

HTTP/1.1 206 PartialContent
Content-Range: bytes 0-1/652965648
Accept-Ranges: bytes
ETag: "0daA8D4/wgt4MFvxdNIPLw=="
Date: Wed, 13 Jun 2012 09:10:18 GMT
Content-Length: 2
Content-Type: video/x-m4v
Server: Tiny WebServer
Connection: keep-alive

..  << 2 bytes data

GET /movies/i_am_legend%20dvd/main.m4v HTTP/1.1
Host: 10.100.1.199:8081
Accept: */*
Range: bytes=0-652965647
Accept-Encoding: identity
Connection: keep-alive
User-Agent: AppleCoreMedia/1.0.0.9B206 (iPad; U; CPU OS 5_1_1 like Mac OS X; nl_nl)
X-Playback-Session-Id: 9CED81CC-BFAE-4CF6-A477-0EA62B2C652F

HTTP/1.1 206 PartialContent
Content-Range: bytes 0-652965647/652965648
Accept-Ranges: bytes
ETag: "0daA8D4/wgt4MFvxdNIPLw=="
Date: Wed, 13 Jun 2012 09:10:18 GMT
Content-Length: 652965648
Content-Type: video/x-m4v
Server: Tiny WebServer
Connection: keep-alive

网络服务器将尝试发送整个文件(>600MB),wireshark 显示整个会话为 159774 字节。如果我对 IIS 做同样的事情,我会得到类似的标题

GET /ipod/main.m4v HTTP/1.1
Host: 10.100.1.199
User-Agent: AppleCoreMedia/1.0.0.9B206 (iPad; U; CPU OS 5_1_1 like Mac OS X; nl_nl)
Accept: */*
Range: bytes=0-1
Accept-Encoding: identity
X-Playback-Session-Id: C5BBF91D-78AB-42BA-ACE0-D74AB9D845CE
Connection: keep-alive

HTTP/1.1 206 Partial Content
Content-Type: video/x-m4v
Last-Modified: Mon, 11 Jun 2012 10:33:41 GMT
Accept-Ranges: bytes
ETag: "7243cabbd47cd1:0"
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Wed, 13 Jun 2012 09:21:03 GMT
Content-Length: 2
Content-Range: bytes 0-1/652965648

..  << 2 bytes of data

GET /ipod/main.m4v HTTP/1.1
Host: 10.100.1.199
User-Agent: AppleCoreMedia/1.0.0.9B206 (iPad; U; CPU OS 5_1_1 like Mac OS X; nl_nl)
Accept: */*
Range: bytes=0-652965647
Accept-Encoding: identity
X-Playback-Session-Id: C5BBF91D-78AB-42BA-ACE0-D74AB9D845CE
Connection: keep-alive

HTTP/1.1 206 Partial Content
Content-Type: video/x-m4v
Last-Modified: Mon, 11 Jun 2012 10:33:41 GMT
Accept-Ranges: bytes
ETag: "7243cabbd47cd1:0"
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Wed, 13 Jun 2012 09:21:03 GMT
Content-Length: 652965648
Content-Range: bytes 0-652965647/652965648

Wireshark 显示整个会话为 175615 字节。

我已经搜索了有关 Accept-Range 标头的更多信息,到目前为止我只能发现服务器必须发送请求的范围。但我不敢相信它是打算使用范围请求来一次请求一个巨大的文件。

我的网络服务器尝试发送整个文件,因为它已被请求,但我看到新的范围请求以更大的范围出现(只有从请求标头复制的 Range 标头。(@time .. .)是wireshark的时间

Range: bytes=2162688-652965647 (@ time == 1.646204)
Range: bytes=4980736-652965647 (@ time == 2.754322)
Range: bytes=6356992-652965647 (@ time == 2.922479)

在阅读this 之后,每当我收到整个文件的范围请求时,我都会尝试发送更短的范围。但它根本不起作用。

我想知道:

  1. 整个文件的范围请求是否是 iOS 中的某种错误(在 4.3.3 中也看到过)我本来预计 Range: bytes=0-1 和重播后类似 Range: bytes=0-65535/652965648
  2. 我能否以某种方式优雅地拒绝这个大请求并告诉请求我可以一次提供最大大小? (我在 RFC 中没有找到这个)
  3. IIS 是否只是在达到一定字节数后中止此请求?

编辑:对于数字 3:不是 IIS,但浏览器似乎只是简单地中止(并关闭)连接。之后提出新的请求。我无法想象范围请求是为了请求整个文件或文件的巨大部分。

编辑:在 iOS7 中它似乎发生了变化。第一个范围请求仍然相同(字节 0-1)。之后,我看到上面提到的 2 或 3 个范围请求,其中最后一个请求继续传输字节更长的时间。但是仍然完成了多个请求。

【问题讨论】:

  • 我是 observing similar behaviour,在我看来这是 iPad/iPhone 的问题。
  • @mindas 的确,你面临同样的事情。由于我使用的网络服务器的结构,我没有太多选择,需要重新抛出异常以停止处理范围请求。幸运的是,我同时只有 1 个客户端连接(但它也适用于 2 个或 3 个)。我希望你能得到一些有用的答案。
  • 我们在测试中看到的是 safari 请求前两个字节(范围 0-1),然后它请求整个文件并立即关闭连接,然后它请求 文件的最后几百千字节(我怀疑它包含重要的元数据。顺便说一下,Chrome 也做同样的事情),然后它开始从头到尾以小块的形式请求文件。我怀疑确切的模式会因视频格式而异。
  • @AbhiBeckert:感谢您的反馈。我从未见过在文件末尾要求字节的范围请求,但实际上正如您所提到的,它可能取决于视频文件格式。我们正在使用 .m4v 文件。你能反馈一下你使用什么类型的文件吗?

标签: http webserver


【解决方案1】:
  1. 整个文件的范围请求是否是 iOS 中的某种错误(在 4.3.3 中也可以看到) -65535/652965648

我不知道这是否是一个错误。但是,我可以想到媒体播放器在一个请求中请求整个文件的原因。通过这种方式,媒体播放器获得了一个数据流,它可以从中读取从头到尾的所有数据。

一旦媒体播放器从流中读取了足够的数据,它就可以开始播放媒体文件。然后它选择在播放媒体时它应该在后台缓冲多少数据。可能有几种不同的方法:

  • 急切地缓冲整个媒体文件。当带宽很便宜(用户不为数据传输支付或支付统一费率)时,这是一个很好的策略。假设用户想要查看/收听整个媒体文件。

  • 延迟缓冲刚好足以避免滞后。当带宽昂贵(用户按字节付费)时,这是一个很好的策略。

    在理想的设置中,媒体播放器根本不需要缓冲任何内容,而是在实时播放媒体时从流中解码数据。但是,这需要底层网络通道非常稳定,并且始终以所需的速度传输数据。

    情况并非如此,因此媒体播放器会选择提前几秒或几分钟缓冲。

请务必注意,无论选择何种策略,媒体播放器在单个请求中请求整个资源仍然是有意义的。

但是,在以下情况下,范围请求对媒体播放器至关重要:

  • 连接被中止(出于任何原因)。
  • 用户在媒体中向前跳跃。 (例如,想看电影 10 分钟后的内容)

然后媒体播放器可以关闭它最初打开的数据流并发送一个范围请求到所需的位置。

  1. 我能否以某种方式优雅地拒绝这个大请求并告诉请求我可以一次提供最大大小?

不,你不能。范围请求由客户端/浏览器发起,并且声明它支持范围请求(通过Accept-Ranges 标头)的服务器必须服从客户端并以它请求的任何范围进行响应。

您可以做的是发送带有Transfer-Encoding: chunked 标头的数据。这将使您的服务器能够控制它应传输的数据块的大小。但是,它仍然是通过单个 HTTP 连接完成的。

【讨论】:

  • 感谢您的广泛反应。我会将其标记为答案。
猜你喜欢
  • 2023-03-08
  • 2013-09-04
  • 1970-01-01
  • 2013-03-27
  • 2011-03-19
  • 1970-01-01
  • 1970-01-01
  • 2015-03-08
  • 1970-01-01
相关资源
最近更新 更多