HTTP रेंज हेडर


81

मैं http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35 पढ़ रहा था और यह जानने की कोशिश कर रहा था कि फ़ाइल डाउनलोड कैसे जारी रखी जाए।

उदाहरण के लिए, मान लीजिए कि एक फाइल 100 बाइट्स की है और मेरे पास सभी 100 बाइट्स हैं। हालाँकि, मुझे नहीं पता कि अपेक्षित फ़ाइल आकार क्या होना चाहिए, इसलिए मैं फ़ाइल माँगता हूँ और इस तरह दिखने वाला एक श्रेणी शीर्षलेख निर्दिष्ट करता हूँ:

Range: bytes=100-

क्या यह एक मान्य रेंज अनुरोध है?


5
एर्म, इसके तहत उदाहरण 'बाइट्स = 9500-' को वैध के रूप में उद्धृत करता है, इसलिए ....
विक्रांत

1
सबसे वर्तमान रेफरी RFC7233 है - httpwg.github.io/specs/rfc7233.html
मार्क नॉटिंघम

2
आप पहले एक HEAD अनुरोध कर सकते हैं और फ़ाइल की लंबाई की जांच कर सकते हैं।
मैथ्यूस रोचा

जवाबों:


55

यह एक वाक्यात्मक रूप से मान्य अनुरोध है, लेकिन संतोषजनक अनुरोध नहीं है। यदि आप उस अनुभाग को आगे देखते हैं जो आप देखते हैं:

यदि एक वाक्यात्मक रूप से मान्य बाइट-रेंज-सेट में कम से कम एक बाइट-रेंज-स्पेक शामिल है जिसका पहला बाइट-पॉस इकाई-बॉडी की वर्तमान लंबाई से कम है, या एक गैर के साथ कम से कम एक प्रत्यय-बाइट-रेंज-कल्पना है। - शून्य प्रत्यय-लंबाई, तो बाइट-रेंज-सेट संतोषजनक है। अन्यथा, बाइट-रेंज-सेट असंतोषजनक है। यदि बाइट-रेंज-सेट असंतोषजनक है, तो सर्वर SHOULD 416 की स्थिति के साथ प्रतिक्रिया लौटाता है (अनुरोधित रेंज संतोषजनक नहीं है) । अन्यथा, सर्वर SHOULD 206 की स्थिति (आंशिक सामग्री) के साथ एक प्रतिक्रिया लौटाता है जिसमें इकाई-निकाय की संतोषजनक रेंज होती है।

इसलिए मुझे लगता है कि आपके उदाहरण में, सर्वर को 416 वापस करना चाहिए क्योंकि यह उस फाइल के लिए वैध बाइट रेंज नहीं है।


तो क्या कोई ऐसा तरीका है जिससे कोई क्लाइंट बिना डाउनलोड किए रिज्यूम को फिर से शुरू कर सकता है ताकि पहले कंटेंट की लंबाई का पता लगाया जा सके और फिर गणित किया जाए और वास्तविक कंटेंट निकाला जाए? मेरा मतलब है किसी तरह के खुले संबोधन जैसे "मुझे इस तरह के और बाइट के बाद सभी बाइट्स दें ..."
druvbird

5
क्लाइंट को पहले से ही पता होगा कि क्या उसके पास मूल अनुरोध के सभी डेटा हैं - उसे मूल प्रतिक्रिया में एक सामग्री-लंबाई शीर्षलेख प्राप्त होना चाहिए, या यदि उसे एन्कोडिंग किया गया था, तो उसे इंगित करने के लिए शून्य-लंबाई वाला हिस्सा मिला होगा। प्रतिक्रिया पूर्ण थी। यदि आपने इस राज्य को नहीं बचाया है और बस डिस्क पर बाइट्स का एक हिस्सा है, तो हाँ आपको या तो एक HEAD अनुरोध करना होगा या बाइट रेंज के लिए पूछने के लिए रेंज हेडर का उपयोग करना होगा, और यदि आपको 416 वापस मिलता है प्रतिक्रिया आपको पता है कि आपके पास सभी बाइट्स हैं।
मार्क नोवाकोव्स्की

मुझे लगता है कि एक्सपेक्ट-कंटिन्यू से आप वांछित की तरह स्ट्रीमिंग कम या ज्यादा कर सकते हैं?
MJB

@MarcNovakowski वास्तव में, wc के मामले में और -c ध्वज का उपयोग करने पर विचार करें। चूँकि wget पूरा होने के बारे में किसी भी मेटाडेटा को बनाए नहीं रखता है, मान लीजिए कि डिस्क पर फ़ाइल का आकार 99 बाइट्स है। wget बाइट रेंज "100-" का अनुरोध करेगा, और मुझे लगता है कि सर्वर को 0 लंबाई की प्रतिक्रिया के साथ जवाब देना चाहिए क्योंकि अनुरोध फ़ाइल के अंत में सिर्फ 1 अतीत है।
druvbird

148

जैसा कि वैरिकेन ने सुझाव दिया है, यह एक वैध अनुरोध है। जब ग्राहक मीडिया से अनुरोध कर रहा है या डाउनलोड को फिर से शुरू कर रहा है तो यह काफी सामान्य है।

एक क्लाइंट अक्सर यह देखने के लिए परीक्षण करेगा कि क्या सर्वर केवल एक Accept-Rangesप्रतिक्रिया की तलाश के अलावा अन्य अनुरोधों को संभालता है । Chrome हमेशाRange: bytes=0- एक वीडियो के लिए अपना पहला GET अनुरोध भेजता है , इसलिए यह ऐसा कुछ है जिसे आप खारिज नहीं कर सकते।

जब भी कोई ग्राहक Range:अपने अनुरोध में शामिल होता है, भले ही यह विकृत हो, यह एक आंशिक सामग्री (206) प्रतिक्रिया की उम्मीद कर रहा है। जब आप एचटीएमएल 5 वीडियो प्लेबैक के दौरान आगे बढ़ते हैं, तो ब्राउज़र केवल शुरुआती बिंदु का अनुरोध करता है। उदाहरण के लिए:

Range: bytes=3744-

इसलिए, क्लाइंट के लिए वीडियो को ठीक से चलाने के लिए, आपके सर्वर को इन अधूरी श्रेणी के अनुरोधों को संभालने में सक्षम होना चाहिए।

आप अपने प्रश्न में निर्दिष्ट 'श्रेणी' के प्रकार को दो तरीकों से संभाल सकते हैं:

सबसे पहले, आप प्रतिक्रिया में दिए गए अनुरोध किए गए शुरुआती बिंदु के साथ जवाब दे सकते हैं, फिर फ़ाइल की कुल लंबाई माइनस एक (अनुरोधित बाइट रेंज शून्य-अनुक्रमित है)। उदाहरण के लिए:

निवेदन:

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, इस मूल्य का सटीक होना आवश्यक नहीं है। इसका उपयोग खिलाड़ी को वीडियो के आसपास तलाश करने में मदद करने के लिए किया जाता है। यदि आप एक वेबकास्ट स्ट्रीमिंग कर रहे हैं और केवल एक सामान्य विचार है कि यह कब तक होगा, तो अपनी अनुमानित अवधि को पूरी तरह से अनदेखा करने के बजाय इसे शामिल करना बेहतर है। इसलिए, दो घंटे के वेबकास्ट के लिए, आप कुछ इस तरह शामिल कर सकते हैं:

X-Content-Duration: 7200.00 

कुछ मीडिया प्रकारों जैसे, वेबम के साथ, आपको सामग्री-प्रकार भी शामिल करना होगा, जैसे:

Content-Type: video/webm 

ये सभी मीडिया को ठीक से चलाने के लिए आवश्यक हैं, विशेष रूप से HTML5 में। यदि आप एक अवधि नहीं देते हैं, तो खिलाड़ी अपने फ़ाइल आकार से अवधि (मांगने के लिए अनुमति देने) का पता लगाने की कोशिश कर सकता है, लेकिन यह सही नहीं होगा। यह ठीक है, और वेबकास्ट या लाइव स्ट्रीमिंग के लिए आवश्यक है, लेकिन वीडियो फ़ाइलों के प्लेबैक के लिए आदर्श नहीं है। आप FFMPEG जैसे सॉफ़्टवेयर का उपयोग करके अवधि निकाल सकते हैं और इसे डेटाबेस या फ़ाइलनाम में भी सहेज सकते हैं।

X-Content-Durationके पक्ष में चरणबद्ध किया जा रहा है Content-Duration, इसलिए मैं उसे भी शामिल करूंगा। एक मूल, "0-" अनुरोध के जवाब में कम से कम निम्नलिखित शामिल होंगे:

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

एक और बिंदु: क्रोम हमेशा निम्नलिखित के साथ अपना पहला वीडियो अनुरोध शुरू करता है:

Range: bytes=0-

कुछ सर्वर एक उत्तर के रूप में एक नियमित 200 प्रतिक्रिया भेजेंगे, जिसे वह स्वीकार करता है (लेकिन सीमित प्लेबैक विकल्पों के साथ), लेकिन अपने सर्वर के हैंडल रेंज की तुलना में दिखाने के लिए 206 भेजने की कोशिश करें। RFC 2616 का कहना है कि रेंज हेडर को अनदेखा करना स्वीकार्य है।


यदि सामग्री एक लाइव वीडियो स्ट्रीम है जिसमें निश्चित अवधि नहीं है तो आप क्या करते हैं?
जोएल बारसोटी

@ जॉयल, आपको एक अवधि के साथ उत्तर देने की आवश्यकता है, भले ही आप इसे नहीं जानते हों। उस स्थिति में, केवल 0.0 का प्रयास करें। क्लाइंट के लिए, अवधि वैसे भी मायने नहीं रखती है क्योंकि आप आमतौर पर एक लाइव स्ट्रीम स्कैन नहीं कर सकते हैं। यदि 0.0 काम नहीं करता है, तो बस 1000000.00 की तरह वास्तव में कुछ उच्च प्रयास करें।
विक्टर स्टोडार्ड

@VictorStoddard स्ट्रीमिंग को नियमित फ़ाइल डाउनलोड पर लागू किया जा सकता है जहां क्लाइंट अनुरोध में कोई रेंज हेडर मौजूद नहीं है? उस मामले में सर्वर को कैसे जवाब देना चाहिए?
gkiko

@gkiko Chunked Transfer एन्कोडिंग में सामग्री-लंबाई के बजाय स्थानांतरण-एन्कोडिंग शीर्षलेख का उपयोग करने के अलावा कोई अन्य अंतर नहीं है। चंक्स एक सिंगल फाइल से आ सकते हैं और सर्वर चंक साइज़ सेट कर सकता है। ग्राहक को बफर और टुकड़े को एक साथ मिला देना चाहिए जैसा कि वे प्राप्त करते हैं। वैकल्पिक रूप से, HTTP स्ट्रीमिंग मीडिया फ़ाइल के पूर्वगामी सेगमेंट का उपयोग करता है, जहां वे सर्वर पर अलग-अलग हिस्सों (फाइलों की फाइल) के रूप में सहेजे जाते हैं। इन खंडों को नियमित रूप से HTTP फ़ाइल GET अनुरोधों को एक इंडेक्स फ़ाइल से प्राप्त करके उपयोग किया जाता है। मैंने पाया है कि यह मुश्किल था, लेकिन यह वर्षों पहले था।
विक्टर स्टोडार्ड

सामग्री-लंबाई: 64656927 स्वीकार-रंग: बाइट्स सामग्री-श्रेणी: बाइट्स 100-64656926 सामग्री-लंबाई '64656827' क्यों नहीं है?
आईविंड

7

मार्क नोवाकोव्स्की उत्तर के विपरीत, जो किसी कारण से कई लोगों द्वारा उखाड़ा गया है, हाँ, यह एक मान्य और संतोषजनक अनुरोध है।

वास्तव में, मानक, जैसा कि वैरिकेन ने इंगित किया है, बस एक ऐसा उदाहरण बनाता है। व्यवहार में, फ़ायरफ़ॉक्स अपेक्षा के अनुरूप (206 कोड के साथ) इस तरह का जवाब देता है, और यह वही है जो मैं प्रगतिशील डाउनलोड को लागू करने के लिए उपयोग करता हूं, अर्थात, केवल एक लंबी लॉग फ़ाइल की पूंछ प्राप्त करें जो मतदान के साथ वास्तविक समय में बढ़ती है।


2
कृपया मार्क नोवाकोवकी के उत्तर को फिर से पढ़ें। "संतोषजनक" का आरएफसी में एक विशेष अर्थ है, जिसे उन्होंने उद्धृत किया था। यह अनुरोध संतोषजनक नहीं है क्योंकि अनुरोधित बाइट्स फ़ाइल की लंबाई से परे हैं।
स्कॉट लैंब

1
फ़ायरफ़ॉक्स सॉफ्टवेयर तत्व नहीं है जो अनुरोध का जवाब देता है, यह एक http सर्वर है
कॉलिन डी

हां, क्षमा करें, मेरा मतलब था अपाचे
फ्रांसेस्को पोटोर्टो

5

उन लोगों के लिए जो 2019 में विक्टर स्टोडर्ड के उत्तर के ऊपर ठोकर खा रहे हैं, और आशावादी और डो आंखे बन गए हैं, ध्यान दें:

क) फ़ायरफ़ॉक्स 41 में एक्स-कंटेंट-अवधि के लिए समर्थन हटा दिया गया था: https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/41#HTTP

b) मुझे लगता है कि यह केवल .ogg ऑडियो और .ogv वीडियो के लिए समर्थित था, किसी अन्य प्रकार के लिए नहीं।

ग) मैं यह नहीं देख सकता कि यह क्रोम में कभी भी समर्थित था, लेकिन यह सिर्फ मेरी ओर से अनुसंधान की कमी हो सकती है। लेकिन लगता है कि इसकी उपस्थिति या अनुपस्थिति का कोई असर नहीं पड़ता है और क्रोम 71 में आज की तरह वेबम या ओवीवी वीडियो के लिए एक और तरीका है।

d) मुझे कहीं भी ऐसा नहीं मिल रहा है जहाँ 'Content-Duration' ने 'X-Content-Duration' को किसी भी चीज़ के लिए बदल दिया हो, मुझे नहीं लगता कि 'X-Content-Duration' एक उत्तराधिकारी हेडर नाम होने के लिए काफी समय तक जीवित था।

मुझे लगता है कि इसका मतलब है कि, आज के रूप में यदि आप वेब या ओगव कंटेनरों की सेवा करना चाहते हैं, जिनमें ऐसी धाराएँ हैं जो उनकी अवधि (उदाहरण के लिए एक ffpeg पाइप का उत्पादन) को क्रोम या एफएफ तक नहीं जानते हैं, और आप चाहते हैं कि वे स्क्रब करने योग्य हों एक HTML 5 वीडियो तत्व, आप शायद भाग्य से बाहर हैं। फ़ायरफ़ॉक्स 64.0 इन स्क्रब को बनाने के लिए आधे दिल से प्रयास करता है कि आप रेंज अनुरोधों के माध्यम से सेवा करते हैं या नहीं, लेकिन यह भ्रमित हो जाता है और एक चरखा को तब तक फेंकता है जब तक कि स्ट्रीम पूरी तरह से डाउनलोड न हो जाए जब तक कि आप इसे उचित समझें। क्रोम भी कोशिश नहीं करता है, यह सिर्फ बाहर nopes और नहीं दूँगी तुम सब पर साफ़ जब तक पूरे धारा समाप्त हो गया है खेल


यहाँ एफएफ डेवलपर्स से एक लंबी धागा है जो इस प्रकार की फ़ाइलों का समर्थन करने के बारे में बात कर रहा है। Bugzilla.mozilla.org/show_bug.cgi?id=657791
क्रिस मैकडोनो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.