प्रतिनिधि इंटरव्यू विषय

फ्रंटेंड इंटरव्यू: Compression Streams के साथ बड़ी फ़ाइलों को सुरक्षित रूप से कैसे प्रोसेस करेंगे?

फ्रंटएंडकठिन
Offer.cc संपादकीय टीमप्रकाशित अपडेट किया गया

प्रश्न

एक ब्राउज़र को कम मेमोरी, कैंसिलेशन और दुर्भावनापूर्ण इनपुट से सुरक्षा के साथ बड़े अपलोड को gzip करना और डाउनलोड को डीकंप्रेस करना होगा। स्ट्रीम पाइपलाइन डिज़ाइन करें और फॉर्मेट्स, बैकप्रेशर, एरर्स और सुरक्षा सीमाओं की व्याख्या करें।

प्रॉम्प्ट और संदर्भ

एक ब्राउज़र को कम मेमोरी, कैंसिलेशन और दुर्भावनापूर्ण इनपुट से सुरक्षा के साथ बड़े अपलोड को gzip करना और डाउनलोड को डीकंप्रेस करना होगा। स्ट्रीम पाइपलाइन डिज़ाइन करें और फॉर्मेट्स, बैकप्रेशर, एरर्स और सुरक्षा सीमाओं की व्याख्या करें।

Compression Streams API, Web Streams पाइपलाइन में बाइनरी चंक्स के लिए CompressionStream और DecompressionStream प्रदान करता है। मानक brotli, deflate, deflate-raw और gzip को परिभाषित करता है; यह ट्रांसफॉर्म प्रदान करता है, न कि साइज़ की सीमाएं, प्रमाणीकरण (authentication), या व्यावसायिक अखंडता (integrity) जांच।

इंटरव्यूअर क्या टेस्ट कर रहा है

Readable/Writable/TransformStream कंपोज़िशन, बैकप्रेशर और कतारें (queues), फ्लश, फॉर्मेट सीमाएं, डीकंप्रेशन एरर्स, कैंसिलेशन प्रोपेगेशन, मेमोरी बजट, डीकंप्रेशन बम और लंबाई वाले साइड चैनल, प्रोग्रेसिव एन्हांसमेंट, और सर्वर नेगोशिएशन को कवर करें।

30-सेकंड का उत्तर ढांचा

“मैं एक Blob स्ट्रीम या रिस्पॉन्स बॉडी को pipeThrough के साथ CompressionStream से कनेक्ट करूँगा ताकि बैकप्रेशर बना रहे, और AbortSignal के साथ कैंसिलेशन को प्रोपेगेट करूँगा। डाउनलोड पर, DecompressionStream को पार्सर में फीड करने से पहले कंप्रेस्ड साइज़, डीकंप्रेस्ड बाइट्स और प्रोसेसिंग समय को सीमित करूँगा; फॉर्मेट या इंटीग्रिटी एरर्स पर एबॉर्शन (abort) करूँगा। यदि ब्राउज़र में क्षमता का अभाव है, तो सर्वर कंप्रेशन पर फॉलबैक करूँगा। यह API कोई सुरक्षा स्कैनर या इंटीग्रिटी सत्यापनकर्ता नहीं है।”

चरण-दर-चरण विस्तृत विश्लेषण

चरण 1: इनपुट और आउटपुट स्ट्रीम चुनें

अपलोड Blob.stream() से और डाउनलोड Response.body से शुरू हो सकते हैं। एक CompressionStream फेच बॉडी, फ़ाइल सिंक या पार्सर के लिए एक ReadableStream उत्पन्न करता है; पूरी फ़ाइल को पहले ArrayBuffer में लोड न करें।

चरण 2: एक ट्रांसफॉर्म कनेक्ट करें

एक न्यूनतम अपलोड पाइपलाइन है:

javascript
async function uploadGzip(blob, signal) {
  const compressed = blob.stream().pipeThrough(
    new CompressionStream("gzip"),
    { signal },
  );
  return fetch("/upload", {
    method: "POST",
    body: compressed,
    signal,
    headers: { "Content-Encoding": "gzip" },
  });
}

वास्तविक प्रोटोकॉल को अनुरोध की लंबाई, पुनः प्रयास (retry) सिमेंटिक्स, और क्या सर्वर स्ट्रीमिंग रिक्वेस्ट बॉडी स्वीकार करता है, इसे परिभाषित करना चाहिए।

चरण 3: बैकप्रेशर और फ्लश को समझें

Streams API डाउनस्ट्रीम कतार और राइट गति के आधार पर अपस्ट्रीम रीड्स को समायोजित करता है। प्रत्येक चंक को एक अनबाउंडेड ऐरे में न जोड़ें; एक धीमे सिंक को पाइपलाइन को स्वाभाविक रूप से रोकना चाहिए। राइटेबल पक्ष को बंद करने से अंतिम कंप्रेस्ड ब्लॉक और चेकसम को फ्लश किया जाना चाहिए।

चरण 4: फॉर्मेट्स पर नेगोशिएट करें

कंस्ट्रक्टर एक समर्थित फॉर्मेट स्ट्रिंग स्वीकार करता है और असमर्थित स्ट्रिंग के लिए थ्रो करता है। क्लाइंट और सर्वर को Content-Encoding या किसी बिज़नेस फ़ील्ड पर सहमत होना चाहिए। deflate, deflate-raw, और gzip में अलग-अलग रैपर होते हैं; बिना नेगोशिएशन के Brotli न भेजें।

चरण 5: डीकंप्रेशन को सीमित (bounded) बनाएं

कंप्रेस्ड इनपुट बहुत बड़े आउटपुट में विस्तारित हो सकता है। आउटपुट बाइट्स, फ़ाइल प्रविष्टियों, प्रोसेसिंग समय और समवर्ती (concurrent) कार्यों की गणना करें; बजट पार होते ही रद्द या एबॉर्शन करें। डीकंप्रेस्ड सामग्री को अभी भी MIME, पथ, और कंटेंट-सुरक्षा जांच की आवश्यकता होती है। एक सफल ट्रांसफॉर्म का मतलब भरोसा नहीं है।

चरण 6: एरर्स और कैंसिलेशन को प्रोपेगेट करें

फॉर्मेट या चेकसम की विफलताएं ट्रांसफॉर्म को एक एरर स्थिति में डाल देती हैं। pipeTo, fetch और रीडर्स से आने वाली एरर्स को कैच करें, और यूज़र कैंसिलेशन को रिक्वेस्ट, रीडर्स, राइटर्स और ट्रांसफॉर्म में प्रोपेगेट करें। अस्थायी Blobs, लॉक्स और UI प्रोग्रेस स्थिति को रिलीज़ करें ताकि कोई भी रीड पेंडिंग न रहे।

चरण 7: गोपनीयता और अखंडता की रक्षा करें

कंप्रेस्ड लंबाई रहस्यों (secrets) और हमलावर-नियंत्रित टेक्स्ट के बीच संबंधों को उजागर कर सकती है। दोनों को एक ही कंप्रेशन संदर्भ में न रखें। महत्वपूर्ण फ़ाइलों के लिए स्वतंत्र हस्ताक्षर (signatures) या हैश का उपयोग करें; कंप्रेशन बाइट्स को एनकोड करता है लेकिन स्रोत को प्रमाणित नहीं करता है या छेड़छाड़ को रोकता नहीं है।

चरण 8: अनुकूलता (compatibility) और फॉलबैक प्रदान करें

स्टार्टअप पर कंस्ट्रक्टर्स और फॉर्मेट्स की जांच करें, और मुख्य थ्रेड की सुरक्षा के लिए Worker में बड़े कार्य चलाएं। यदि असमर्थित है, तो सर्वर कंप्रेशन को सौंपें या समान कैंसिलेशन, साइज़ और एरर सिमेंटिक्स के साथ अनकंप्रेस्ड अपलोड करें; केवल आधुनिक ब्राउज़रों पर ही वेलिडेट न करें।

ट्रेड-ऑफ और सीमाएं

क्लाइंट CPU बनाम नेटवर्क बचत

कंप्रेशन बाइट्स बचाता है लेकिन CPU, बैटरी और समय की खपत करता है। मोबाइल पर, फ़ाइल प्रकार, नेटवर्क गुणवत्ता और बैटरी द्वारा चयन करें; पहले से कंप्रेस किए गए फॉर्मेट्स को आमतौर पर फिर से कंप्रेस नहीं किया जाना चाहिए।

स्ट्रीमिंग बनाम रिट्राई सरलता

स्ट्रीमिंग मेमोरी को कम रखती है लेकिन इसके लिए चंक-सचेत (chunk-aware) सर्वर और इडेम्पोटेंट रिट्राई की आवश्यकता होती है। रिज़्यूमेबल अपलोड के लिए, कंप्रेस्ड चंक्स को मल्टीपार्ट प्रोटोकॉल से बांधें; उपभोग की गई (consumed) ReadableStream को ऐसे पुनः प्रयास न करें मानो यह दोबारा चलाई जा सकती हो (replayable)।

ब्राउज़र बनाम सर्वर डीकंप्रेशन

ब्राउज़र डीकंप्रेशन सर्वर CPU को बचाता है लेकिन संसाधन और सुरक्षा बजट को डिवाइस पर ले जाता है। संवेदनशील या अत्यधिक विस्तारित होने वाले डेटा के लिए, सर्वर पर डीकंप्रेस करें और एक सीमित परिणाम लौटाएं जबकि क्लाइंट स्थिति और चंक्स का उपभोग करता है।

विफलता अभ्यास (failure drills) और विकास योजना

सिंक धीमा हो जाता है

अपलोड गति को थ्रॉटल करें और कतार व मेमोरी वक्रों का निरीक्षण करें। पुष्टि करें कि सभी चंक्स को बनाए नहीं रखा जा रहा है; यदि कतारें अभी भी बढ़ती हैं, तो समवर्तीता कम करें और पाइपलाइन को रुकने दें।

एक gzip स्ट्रीम बीच में कट (truncated) जाती है

कंप्रेस्ड इनपुट को छोटा करें और फ्लश या चेकसम वेलिडेशन के दौरान विफलता, एक पुनः प्रयास योग्य UI स्थिति, और रीडर्स, रिक्वेस्ट्स और अस्थायी ऑब्जेक्ट्स की रिहाई को सत्यापित करें।

आउटपुट अपने बजट से अधिक हो जाता है

एक उच्च-विस्तार (high-expansion) नमूने का उपयोग करें और सत्यापित करें कि बाइट सीमा तक पहुँचने पर पूर्ण आउटपुट को भौतिक (materialize) या बनाए रखने के बजाय तुरंत एबॉर्शन हो जाता है।

सामान्य गलतियाँ और फॉलो-अप

गलती 1: यह मान लेना कि API डीकंप्रेशन बम को रोकता है

फॉलो-अप: क्या कमी है? एप्लिकेशन-स्तरीय बाइट, समय, प्रविष्टि और समवर्तीता बजट; API केवल फॉर्मेट रूपांतरण करता है।

गलती 2: deflate को gzip मानना

फॉलो-अप: क्यों नहीं? रैपर अलग-अलग होते हैं, इसलिए प्रोटोकॉल नेगोशिएशन और मेल खाने वाले फॉर्मेट्स की आवश्यकता होती है।

गलती 3: उपभोग की गई (consumed) स्ट्रीम का पुनः प्रयास करना

फॉलो-अप: सही क्या है? एक रीप्ले करने योग्य Blob या चंक स्रोत से पाइपलाइन का पुनर्निर्माण करें और सर्वर के साथ एक इडेम्पोटेंट अपलोड पहचानकर्ता का समन्वय करें।

विस्तारित फॉलो-अप और मॉडल उत्तर

फ्लश क्यों महत्वपूर्ण है?

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

आप लंबाई वाले साइड-चैनल जोखिम को कैसे कम करते हैं?

हमलावर-नियंत्रित टेक्स्ट से रहस्यों को अलग करें, एक साझा कंप्रेशन संदर्भ से बचें, और प्रोटोकॉल पैडिंग या ऐसे डिज़ाइन का उपयोग करें जो संबंध को उजागर न करे।

कंप्रेशन को सर्वर पर कब रहना चाहिए?

पुराने ब्राउज़रों, कम बैटरी वाले उपकरणों, विशाल फ़ाइलों या संवेदनशील डेटा के लिए सर्वर-साइड प्रोसेसिंग का उपयोग करें। फिर भी डीकंप्रेस्ड आउटपुट को सीमित करें और क्लाइंट को देखने योग्य प्रगति प्रदर्शित करें।

सार्वजनिक स्रोत

संबंधित प्रश्न