2010-07-21 45 views
67

Tôi đã đọc http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35 và cố gắng tìm hiểu cách tiếp tục tải xuống tệp. Ví dụ: giả sử một tệp có chiều dài là 100 byte và tôi có tất cả 100 byte. Tuy nhiên, tôi không biết kích thước tệp mong muốn là gì, vì vậy tôi yêu cầu tệp và chỉ định tiêu đề Phạm vi như sau:Tiêu đề phạm vi HTTP

Range: bytes=100- 

Đây có phải là yêu cầu Phạm vi hợp lệ không?

+5

Erm, ví dụ dưới nó trích dẫn 'bytes = 9500-' là hợp lệ, vì vậy .... – Wrikken

+1

Ref mới nhất là RFC7233 - http://httpwg.github.io/specs/rfc7233.html –

+0

Bạn có thể thực hiện yêu cầu HEAD trước và kiểm tra độ dài tệp. –

Trả lời

45

Đó là yêu cầu hợp lệ về cú pháp, nhưng không phải là yêu cầu thỏa đáng. Nếu bạn nhìn xa hơn trong phần đó, bạn thấy:

Nếu tập hợp dải byte hợp lệ cú pháp bao gồm ít nhất một byte-spec-spec có vị trí byte đầu tiên nhỏ hơn độ dài hiện tại của thực thể- cơ thể, hoặc ít nhất một hậu tố-byte-phạm vi-spec với độ dài hậu tố không bằng không, sau đó byte-phạm vi-thiết lập là thỏa đáng. Nếu không, byte-phạm vi-thiết lập là không hài lòng. Nếu tập hợp dải byte không thỏa mãn, máy chủ NÊN trả lại phản hồi có trạng thái là 416 (Phạm vi được yêu cầu không thỏa mãn). Nếu không, máy chủ NÊN trả về một phản hồi với trạng thái 206 (một phần nội dung) có chứa các phạm vi thỏa đáng của thực thể-cơ thể.

Vì vậy, tôi nghĩ trong ví dụ của bạn, máy chủ phải trả lại 416 vì nó không phải là phạm vi byte hợp lệ cho tệp đó.

+0

Vậy có cách nào khách hàng có thể tiếp tục tải xuống mà không thực hiện cuộc gọi HEAD để tìm ra chiều dài nội dung và sau đó thực hiện toán học và tìm nạp nội dung thực tế không? Tôi có nghĩa là một số loại mở địa chỉ như "cung cấp cho tôi tất cả các byte sau đó và như vậy byte ..." – dhruvbird

+5

Khách hàng sẽ biết nếu nó có tất cả các dữ liệu từ yêu cầu ban đầu - nó phải có hoặc nhận được một tiêu đề Content-Length trong phản hồi ban đầu, hoặc nếu nó được mã hóa chunked nó sẽ nhận được một đoạn không dài để chỉ ra phản ứng đã hoàn thành. Nếu bạn chưa lưu trạng thái này và chỉ có một đoạn byte trên đĩa, thì bạn sẽ phải thực hiện yêu cầu HEAD hoặc sử dụng tiêu đề Phạm vi để yêu cầu phạm vi byte và nếu bạn quay lại một câu trả lời 416 bạn biết bạn có tất cả các byte. –

+0

Tôi nghĩ rằng Kỳ vọng-Tiếp tục cho phép bạn thực hiện các luồng trực tuyến nhiều hơn hoặc ít hơn như mong muốn? – MJB

115

Như được đề xuất là Wrikken, đó là yêu cầu hợp lệ. Nó cũng khá phổ biến khi khách hàng yêu cầu phương tiện hoặc tiếp tục tải xuống.

Một khách hàng thường sẽ kiểm tra xem máy chủ có xử lý các yêu cầu thay đổi khác ngoài chỉ tìm kiếm phản hồi Accept-Ranges hay không. Chrome luôn luôn gửi Range: bytes=0- với yêu cầu GET đầu tiên cho video, do đó, đó là điều bạn không thể bỏ qua.

Bất cứ khi nào khách hàng bao gồm Range: trong yêu cầu của nó, ngay cả khi yêu cầu không đúng định dạng, phản hồi một phần nội dung (206). Khi bạn tìm kiếm trong khi phát lại video HTML5, trình duyệt chỉ yêu cầu điểm xuất phát. Ví dụ:

Range: bytes=3744- 

Vì vậy, để khách hàng phát video đúng cách, máy chủ của bạn phải có khả năng xử lý các yêu cầu không đầy đủ này.

Bạn có thể xử lý các loại 'phạm vi' bạn chỉ định trong câu hỏi của bạn theo hai cách:

Đầu tiên, Bạn có thể trả lời với điểm xuất phát được yêu cầu đưa ra trong các phản ứng, sau đó tổng chiều dài của một tập tin trừ (phạm vi byte được yêu cầu không được lập chỉ mục). Ví dụ:

Yêu cầu:

GET /BigBuckBunny_320x180.mp4 
Range: bytes=100- 

đáp ứng:

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

Thứ hai, bạn có thể trả lời với điểm xuất phát được đưa ra trong yêu cầu và chiều dài tập tin mở (kích thước). Điều này dành cho webcast hoặc phương tiện khác, nơi tổng chiều dài không xác định.Ví dụ:

Yêu cầu:

GET /BigBuckBunny_320x180.mp4 
Range: bytes=100- 

đáp ứng:

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

Mẹo:

Bạn luôn luôn phải đối phó với chiều dài nội dung bao gồm trong phạm vi. Nếu phạm vi là hoàn chỉnh, với lúc bắt đầu đến kết thúc, sau đó chiều dài nội dung chỉ đơn giản là sự khác biệt:

Yêu cầu: Phạm vi: bytes = 500-1000

đáp ứng: Content-Phạm vi: byte 500-1000/123456

Hãy nhớ rằng phạm vi là zero-lập chỉ mục, vì vậy Range: bytes=0-999 thực sự là yêu cầu 1000 byte, không phải 999, vì vậy phản ứng với cái gì đó như:

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

Hoặc:

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

Nhưng, tránh phương pháp sau nếu có thể vì một số trình phát phương tiện cố gắng tìm ra thời lượng từ kích thước tệp. Nếu yêu cầu của bạn dành cho nội dung phương tiện, đó là linh cảm của tôi, thì bạn nên bao gồm thời lượng của nó trong phản hồi. Việc này được thực hiện theo định dạng sau:

X-Content-Duration: 63.23 

Đây phải là điểm nổi. Không giống như Content-Length, giá trị này không phải chính xác. Nó được sử dụng để giúp người chơi tìm kiếm xung quanh video. Nếu bạn đang phát trực tuyến một webcast và chỉ có ý tưởng chung về thời gian sẽ là bao lâu, thì tốt hơn nên bao gồm thời lượng ước tính của bạn thay vì bỏ qua nó hoàn toàn. Vì vậy, đối với một webcast hai tiếng đồng hồ, bạn có thể bao gồm một cái gì đó như:

X-Content-Duration: 7200.00 

Với một số loại phương tiện truyền thông, chẳng hạn như webm, bạn cũng phải bao gồm các nội dung kiểu như:

Content-Type: video/webm 

Tất cả những điều này là cần thiết để các phương tiện truyền thông có thể chơi đúng cách, đặc biệt là trong HTML5. Nếu bạn không đưa ra thời lượng, người chơi có thể cố gắng tìm ra thời lượng (để cho phép tìm kiếm) từ kích thước tệp của nó, nhưng điều này sẽ không chính xác. Điều này là tốt, và cần thiết cho webcast hoặc phát trực tuyến, nhưng không lý tưởng để phát lại các tệp video. Bạn có thể trích xuất thời lượng bằng cách sử dụng phần mềm như FFMPEG và lưu nó vào cơ sở dữ liệu hoặc thậm chí tên tệp.

X-Content-Duration đang được loại bỏ theo ưu tiên của Content-Duration, vì vậy tôi cũng sẽ bao gồm điều đó. Một cơ bản, đáp ứng với một "0-" yêu cầu sẽ bao gồm ít nhất như sau:

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 

Một điểm nữa: Chrome luôn bắt đầu yêu cầu video đầu tiên của mình như sau:

Range: bytes=0- 

Một số máy chủ sẽ gửi một phản hồi 200 thông thường như là một câu trả lời, nó chấp nhận (nhưng với các tùy chọn phát lại hạn chế), nhưng cố gắng gửi 206 để hiển thị hơn là các phạm vi xử lý máy chủ của bạn. RFC 2616 cho biết có thể chấp nhận bỏ qua tiêu đề phạm vi.

+1

Ai đang làm việc trên định nghĩa về Thời lượng nội dung? Liên kết? –

+0

Bạn sẽ làm gì nếu nội dung là luồng video trực tiếp không có thời lượng cố định? –

+0

@Jelel, bạn cần trả lời với thời lượng ngay cả khi bạn không biết. Trong trường hợp đó, chỉ cần thử 0.0. Đối với khách hàng, thời lượng không quan trọng vì bạn thường không thể quét luồng trực tiếp. Nếu 0.0 không hoạt động, chỉ cần thử một cái gì đó thực sự cao như 1000000.00. –

7

Trái với câu trả lời của Mark Novakowski, vì một số lý do đã được nhiều người tán thành, có, đó là yêu cầu hợp lệ và thỏa đáng.

Trong thực tế, tiêu chuẩn, như Wrikken đã chỉ ra, làm cho một ví dụ như vậy. Trong thực tế, Firefox đáp ứng các yêu cầu như mong đợi (với mã 206), và đây chính xác là những gì tôi sử dụng để thực hiện tải xuống liên tục, tức là chỉ nhận đuôi của tệp nhật ký dài phát triển trong thời gian thực bằng cuộc thăm dò ý kiến.

+2

Vui lòng đọc lại câu trả lời của Marc Novakowki. "thỏa đáng" có một ý nghĩa đặc biệt trong RFC, mà ông trích dẫn. Yêu cầu này không thỏa mãn vì các byte được yêu cầu vượt quá độ dài của tệp. –

Các vấn đề liên quan