2010-07-21 4 views
67

http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35 을 읽고 파일 다운로드를 계속하는 방법을 알아 내려고했습니다.HTTP 범위 헤더

예를 들어, 파일의 길이가 100 바이트이고 모든 100 바이트가 있다고 가정합니다. 그러나, 나는 예상 파일 크기가해야 모르는, 그래서 파일에 대한 요청이처럼 보이는 Range 헤더 지정

Range: bytes=100- 

을이 유효한 범위 요청입니다?

+5

Erm, 'bytes = 9500-'을 유효한 것으로 인용 했으므로 ... – Wrikken

+1

가장 최근의 참조는 RFC7233 - http://httpwg.github.io/specs/rfc7233.html –

+0

입니다. 먼저 HEAD 요청을 만들고 파일 길이를 확인할 수 있습니다. –

답변

45

문법적으로 유효한 요청이지만 만족할만한 요청은 아닙니다. 이 섹션을 자세히 살펴보면 다음을 볼 수 있습니다 :

구문 상 유효한 바이트 범위 세트에는 첫 번째 바이트 위치가 엔터티의 현재 길이보다 작은 바이트 범위 지정이 하나 이상 포함되어 있으면 본문 또는 접미어 길이가 0이 아닌 접미사 바이트 범위 사양이 하나 이상 있으면 바이트 범위 집합이 만족 될 수 있습니다. 그렇지 않으면 바이트 범위 세트가 만족스럽지 않습니다. 바이트 범위 세트가 만족스럽지 않으면 서버는 416 (요청 된 범위는 만족할 만하지 않음) 상태의 응답을 반환해야합니다 (SHOULD). 그렇지 않으면, 서버는 entity-body의 만족할만한 범위를 포함하는 206 (부분적인 내용)의 상태를 가진 응답을 반환해야한다.

그래서 내 생각에 서버는 해당 파일의 유효한 바이트 범위가 아니기 때문에 416을 반환해야한다고 생각합니다.

+0

그래서 클라이언트가 먼저 HEAD 호출을하지 않고 다운로드를 다시 시작하여 콘텐츠 길이를 계산 한 다음 수학을 수행하고 실제 콘텐츠를 가져 오는 방법이 있습니까? "같은 바이트 다음에 나에게 모든 바이트를 줘 ..."와 같은 일종의 공개 주소 지정을 의미합니다. – dhruvbird

+5

클라이언트는 원래 요청의 모든 데이터를 가지고 있는지 이미 알고 있습니다. Content-Length 헤더를 받았거나 원래 응답에서 또는 청크 분할 인코딩 인 경우 길이가 0 인 청크를 수신하여 응답이 완료되었음을 나타냅니다. 이 상태를 저장하지 않고 디스크에 바이트 청크가있는 경우 HEAD 요청을 수행하거나 Range 헤더를 사용하여 바이트 범위를 요청해야합니다. 모든 바이트가 있다는 것을 알면 416 응답. –

+0

나는 Expect-Continue를 사용하여 원하는대로 스트리밍 덩어리를 만들 수 있다고 생각 하는가? – MJB

115

Wrikken으로 제안되었으므로 유효한 요청입니다. 클라이언트가 미디어를 요청하거나 다운로드를 다시 시작하는 경우에도 매우 일반적입니다.

클라이언트는 서버가 Accept-Ranges 응답을 찾는 것 이외의 원거리 요청을 처리하는지 종종 테스트합니다. Chrome 항상은 동영상에 대한 첫 번째 GET 요청과 함께 Range: bytes=0-을 전송하므로 무시할 수없는 내용입니다.

클라이언트가 요청에 Range:을 포함 할 때마다 형식이 잘못 되었더라도 부분 콘텐츠 (206) 응답이 필요합니다. HTML5 동영상 재생 중에 앞으로 탐색 할 때 브라우저는 시작 지점 만 요청합니다. 예를 들어 :

Range: bytes=3744- 

그래서 제대로 비디오를 재생하는 클라이언트에 대한 순서, 서버가 이러한 불완전 범위 요청을 처리 할 수 ​​있어야합니다.

두 가지 방법으로 당신이 당신의 질문에 지정된 '범위'의 유형을 처리 할 수 ​​

첫째, 당신은 응답에 주어진 요구 출발점으로 응답 수, 파일 하나를 뺀의 다음 전체 길이 (요청 된 바이트 범위는 0으로 인덱싱됩니다). 예를 들면 :

요청 :

GET /BigBuckBunny_320x180.mp4 
Range: bytes=100- 

응답 :

206 Partial Content 
Content-Type: video/mp4 
Content-Length: 64656927 
Accept-Ranges: bytes 
Content-Range: bytes 100-64656926/64656927 

둘째, 당신은 요청 및 개방형 파일 길이 (크기)에 주어진 출발점으로 응답 할 수있다. 전체 길이를 알 수없는 웹 캐스트 또는 기타 미디어 용입니다.예를 들면 :

요청 :

GET /BigBuckBunny_320x180.mp4 
Range: bytes=100- 

응답 :

206 Partial Content 
Content-Type: video/mp4 
Content-Length: 64656927 
Accept-Ranges: bytes 
Content-Range: bytes 100-64656926/* 

팁 :

당신은 항상 범위에 포함 된 콘텐츠 길이 응답해야합니다.

요청 : : 범위 : 범위는 끝까지 시작으로, 완료되면, 다음 콘텐츠 길이는 단순히 차이 바이트 = 500-1000

응답 : 내용-범위 : 바이트 500-1000/123456

그래서 Range: bytes=0-999 실제로 1000 바이트가 아닌 999를 요청, 범위가 제로 인덱스는 것을 기억하십시오, 그래서 같은 응답 :

Content-Length: 1000 
Content-Range: bytes 0-999/123456 

또는 :

Content-Length: 1000 
Content-Range: bytes 0-999/* 

그러나 일부 미디어 플레이어는 파일 크기에서 기간을 알아 내려하기 때문에 가능하면 후자의 방법을 사용하지 마십시오. 내 직감 인 미디어 콘텐츠에 대한 요청 인 경우 응답 기간에 포함시켜야합니다. 이 형식은 다음 형식으로 이루어집니다.

X-Content-Duration: 63.23 

부동 소수점이어야합니다. Content-Length과 달리이 값은 정확할 필요는 없습니다. 이것은 플레이어가 비디오를 찾을 때 도움이됩니다. 웹 캐스트를 스트리밍하고 얼마나 오랫동안 지속될 것인지에 대한 일반적인 생각 만 갖고있는 경우 예상 기간을 포함시키지 말고이를 모두 무시하는 것이 좋습니다. 그래서, 두 시간 웹 캐스트를 들어, 같은 것을 포함 할 수있다 :

Content-Type: video/webm 

: 같은 WEBM 같은 일부 용지 종류와

X-Content-Duration: 7200.00 

을, 당신은 또한 다음과 같은 내용 유형을 포함해야 이 모든 것은 미디어가 제대로 재생되는 데 필수적이며, 특히 HTML5에서 그렇습니다. 지속 시간을 지정하지 않으면 플레이어는 파일 크기에서 재생을 허용 할 수있는 시간을 알아낼 수도 있지만 정확하지는 않습니다. 웹 캐스트 또는 라이브 스트리밍에는 적합하지만 비디오 파일 재생에는 이상적이지 않습니다. FFMPEG와 같은 소프트웨어를 사용하여 기간을 추출하고 데이터베이스 또는 파일 이름으로 저장할 수 있습니다.

X-Content-DurationContent-Duration을 단계적으로 제거하고 있으므로이를 포함시킬 수도 있습니다.

HTTP/1.1 206 Partial Content 
Date: Sun, 08 May 2013 06:37:54 GMT 
Server: Apache/2.0.52 (Red Hat) 
Accept-Ranges: bytes 
Content-Length: 3980 
Content-Range: bytes 0-3979/3980 
Content-Type: video/webm 
X-Content-Duration: 2054.53 
Content-Duration: 2054.53 

또 하나 개의 포인트 :는 "0-"요청에 대한 기본 응답은 다음과 같은 이상이 포함됩니다 크롬은 항상과의 첫 번째 비디오 요청을 시작하는 다음

Range: bytes=0- 

일부 서버를 것입니다 받아 들일 수있는 일반 200 응답을 응답으로 보내지 만 (재생 옵션은 제한됨) 서버 대신 범위를 표시하도록 206을 보내십시오. RFC 2616은 범위 헤더를 무시하는 것이 허용된다고 말합니다.

+1

누가 컨텐츠 - 기간의 정의 작업을하고 있습니까? 링크? –

+0

콘텐츠의 길이가 고정되어 있지 않은 라이브 비디오 스트림 인 경우 어떻게합니까? –

+0

@Joel, 모르는 사람이라해도 일정 기간 동안 답장을 보내야합니다. 이 경우 0.0을 사용해보십시오. 클라이언트의 경우 보통 라이브 스트림을 스캔 할 수 없기 때문에 지속 시간은 중요하지 않습니다. 0.0이 작동하지 않는다면 1000000.00과 같은 정말 높은 것을 사용해보십시오. –

7

마크 노바 코프 스키 (Mark Novakowski)의 답변과는 달리, 어떤 이유로 든 많은 이유로 찬성표를 던졌지 만 유효하고 만족스러운 요청입니다.

위클켄 (Wrikken)이 지적한 바와 같이 사실 표준은 바로 그런 예입니다. 실제로 파이어 폭스는 (206 코드로) 예상과 같은 요청에 응답하며, 이것은 점진적 다운로드를 구현하기 위해 사용하는 것입니다. 즉, 폴링을 통해 실시간으로 커지는 긴 로그 파일의 꼬리 만 가져옵니다.

+2

Marc Novakowki의 답변을 다시 읽으십시오. "satisfiable"은 그가 인용 한 RFC에서 특별한 의미가 있습니다. 요청 된 바이트가 파일 길이를 초과하므로이 요청은 만족스럽지 않습니다. –