Как я могу узнать, поддерживает ли сервер заголовок Range?
Я пытался транслировать аудио из определенной точки, используя значения заголовка Range, но я всегда получаю песню с самого начала. Я делаю это через программу, поэтому не уверен, что проблема заключается в моем коде или на сервере.
Как я могу узнать, поддерживает ли сервер параметр заголовка Range?
Благодарю.
5 ответов
Как спецификация HTTP определяет это, если сервер знает, как поддерживать Range
заголовок, так и будет. Это, в свою очередь, требует, чтобы он возвращал код ответа 206 Partial Content с Content-Range
заголовок, когда он возвращает контент для вас. В противном случае он будет просто игнорировать Range
заголовок в вашем запросе и верните код ответа 200.
Это может показаться глупым, но вы уверены, что создаете правильный заголовок HTTP-запроса? Слишком часто я забываю указывать HTTP/1.1 в запросе или забываю указывать спецификатор Range, например, "байты".
Да, и если все, что вы хотите сделать, это проверить, то просто отправьте запрос HEAD вместо запроса GET. Те же заголовки, все то же самое, просто "ГОЛОВА" вместо "ПОЛУЧИТЬ". Если вы получаете 206
ответ, вы будете знать Range
поддерживается, и в противном случае вы получите 200
ответ.
Это для других, ищущих, как это сделать. Вы можете использовать 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 вы увидите длину файла]
Хотя я немного опоздал с ответом на этот вопрос, я думаю, что мой ответ поможет будущим посетителям. Вот метод 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
Один из способов - просто попробовать и проверить ответ. В вашем случае кажется, что сервер не поддерживает диапазоны.
В качестве альтернативы, выполните GET или HEAD для URI и проверьте заголовок ответа Accept-Ranges.
- Ты можешь использовать
GET
метод с0-0
Range
Заголовок запроса и проверьте, является ли код ответа 206 или нет, который ответит первым и последним байтами тела ответа. - Вы также можете использовать
HEAD
метод делает то же самое, что и первый сеанс, который получает тот же заголовок и код ответа без тела ответа
Кроме того, вы можете проверить
Accept-Ranges
в заголовке ответа, чтобы определить, может ли он поддерживать диапазон, но, пожалуйста, обратите внимание, если значениеnone
наAccept-Ranges
поле, это означает, что он не может поддерживать диапазон, и если заголовок ответа не имеетAccept-Ranges
поле, которое вы также не можете найти, оно не может поддерживать диапазон от него.
Есть еще одна вещь, которую вы должны знать, если вы используете 0-
Range
в заголовке запроса с GET
Для проверки кода ответа сообщение тела ответа будет автоматически кэшироваться в окне приема TCP до тех пор, пока кэш не заполнится.