【问题标题】:How can I find out whether a server supports the Range header?如何确定服务器是否支持 Range 标头?
【发布时间】:2010-10-17 18:02:25
【问题描述】:

我一直在尝试使用 Range 标头值从特定点流式传输音频,但我总是从一开始就得到歌曲。我是通过程序执行此操作的,因此不确定问题出在我的代码还是服务器上。

如何判断服务器是否支持 Range 标头参数?

谢谢。

【问题讨论】:

标签: http http-headers


【解决方案1】:

HTTP spec 定义它的方式,如果服务器知道如何支持 Range 标头,它会。这反过来要求它在向您返回内容时返回带有Content-Range 标头的206 Partial Content 响应代码。否则,它将简单地忽略您请求中的 Range 标头,并返回 200 响应代码。

这可能看起来很愚蠢,但是您确定您正在制作一个有效的 HTTP 请求标头吗?太常见了,我忘记在请求中指定 HTTP/1.1,或者忘记指定范围说明符,例如“字节”。

哦,如果您只想检查,那么只需发送 HEAD 请求而不是 GET 请求。相同的标题,相同的一切,只是“HEAD”而不是“GET”。如果您收到206 响应,您将知道Range 受支持,否则您将收到200 响应。

【讨论】:

  • 使用 Python 请求,头部不会在我知道支持范围的服务器上返回 206,但响应头包含 Accept-Ranges
【解决方案2】:

这是供其他人搜索如何执行此操作的。你可以使用 curl:

curl -I http://exampleserver.com/example_video.mp4

在标题中你应该看到

Accept-Ranges: bytes

您可以进一步测试检索范围

curl --header "Range: bytes=100-107" -I http://exampleserver.com/example_vide0.mp4

在标题中你应该看到

HTTP/1.1 206 Partial Content

Content-Range: bytes 100-107/10000000
Content-Length: 8

[你会看到文件的长度而不是 10000000]

【讨论】:

【解决方案3】:

虽然我回答这个问题有点晚,但我认为我的回答会对未来的访客有所帮助。这是一个检测服务器是否支持范围查询的python方法。

def accepts_byte_ranges(self, effective_url):
    """Test if the server supports multi-part file download. Method expects effective (absolute) url."""
    import pycurl
    import cStringIO
    import re

    c = pycurl.Curl()
    header = cStringIO.StringIO()

    # Get http header
    c.setopt(c.URL, effective_url)
    c.setopt(c.NOBODY, 1)
    c.setopt(c.HEADERFUNCTION, header.write)
    c.perform()
    c.close()

    header_text = header.getvalue()
    header.close()

    verbose_print(header_text)

    # Check if server accepts byte-ranges
    match = re.search('Accept-Ranges:\s+bytes', header_text)
    if match:
        return True
    else:
        # If server explicitly specifies "Accept-Ranges: none" in the header, we do not attempt partial download.
        match = re.search('Accept-Ranges:\s+none', header_text)
        if match:
            return False
        else:
            c = pycurl.Curl()

            # There is still hope, try a simple byte range query
            c.setopt(c.RANGE, '0-0') # First byte
            c.setopt(c.URL, effective_url)
            c.setopt(c.NOBODY, 1)
            c.perform()

            http_code = c.getinfo(c.HTTP_CODE)
            c.close()

            if http_code == 206: # Http status code 206 means byte-ranges are accepted
                return True
            else:
                return False

【讨论】:

    【解决方案4】:

    一种方法是尝试并检查响应。在您的情况下,服务器似乎不支持范围。

    或者,对 URI 执行 GET 或 HEAD,并检查 Accept-Ranges response header

    【讨论】:

      【解决方案5】:
      • 可以使用GET方法和0-0Range请求头,检查响应码是否为206,会响应 响应正文的第一个和最后一个字节
      • 您也可以使用HEAD 方法执行与第一个会话相同的操作,这将获得相同的响应标头和代码而无需响应正文

      另外,你可以查看响应头上的Accept-Ranges来判断是否支持范围,但请注意如果Accept-Ranges字段的值为none,则表示不支持范围,如果响应标头没有Accept-Ranges 字段,您也无法指出它不支持范围。

      如果你在请求头上使用0- RangeGET 方法来检查响应代码,还有一件事你必须知道,响应正文消息将自动缓存在TCP接收窗口中,直到缓存已满。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-10-09
        • 2021-10-08
        • 1970-01-01
        • 2014-04-26
        • 1970-01-01
        • 1970-01-01
        • 2011-05-22
        相关资源
        最近更新 更多