How can I find out whether a server supports the R

2019-01-08 23:04发布

问题:

I have been trying to stream audio from a particular point by using the Range header values but I always get the song right from the beginning. I am doing this through a program so am not sure whether the problem lies in my code or on the server.

How can I find out whether the server supports the Range header param?

Thanks.

回答1:

The way the HTTP spec defines it, if the server knows how to support the Range header, it will. That in turn, requires it to return a 206 Partial Content response code with a Content-Range header, when it returns content to you. Otherwise, it will simply ignore the Range header in your request, and return a 200 response code.

This might seem silly, but are you sure you're crafting a valid HTTP request header? All too commonly, I forget to specify HTTP/1.1 in the request, or forget to specify the Range specifier, such as "bytes".

Oh, and if all you want to do is check, then just send a HEAD request instead of a GET request. Same headers, same everything, just "HEAD" instead of "GET". If you receive a 206 response, you'll know Range is supported, and otherwise you'll get a 200 response.



回答2:

Although I am a bit late in answering this question, I think my answer will help future visitors. Here is a python method that detects whether a server supports range queries or not.

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


回答3:

One way is just to try, and check the response. In your case, it appears the server doesn't support ranges.

Alternatively, do a GET or HEAD on the URI, and check for the Accept-Ranges response header.



回答4:

This is for others searching how to do this. You can use curl:

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

In the header you should see

Accept-Ranges: bytes

You can go further and test retrieving a range

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

and in the headers you should see

HTTP/1.1 206 Partial Content

and

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

[instead of 10000000 you'll see the length of the file]



回答5:

  • You can use GET method with 0-0 Range request header, and check whether the response code is 206 or not, which will respond with the first and last bytes of the response body
  • You also can use HEAD method do the same thing as the first session which will get the same response header and code without response body

Furthermore, you can check Accept-Ranges on the response header to judge whether it can support range, but please notice if the value is none on Accept-Ranges field, it means it can't support range, and if the response header doesn't have Accept-Ranges field you also can't finger out it can't support range from it.

There is another thing you have to know if you are using 0- Range on the request header with GET method to check the response code, the response body message will be cached automatically on the TCP receive window until the cache is full.