प्रतियोगियों को रहस्यों को उजागर किए बिना किसी को PHP वेब एप्लिकेशन को सुरक्षित रूप से कैसे डिबग करना चाहिए?


11

हाल ही में मैंने एक कार्यक्रम बनाया। मैं कोड की 2 लाइन हटाना भूल जाता हूं। उस गलती ने मुझे हर दिन प्रति दिन $ 800 का खर्च दिया।

मैं PHP के साथ प्रोग्रामिंग कर रहा था। यदि कोई विज़िटर प्रॉक्सी का उपयोग करता है तो वह कहीं और रीडायरेक्ट होता है। डीबगर का उपयोग करना असंभव था क्योंकि कुछ कोड में आयनक्यूब होता है। क्योंकि कार्यक्रम बस कहीं और पुनर्निर्देशित करता है कोई फर्क नहीं पड़ता कि क्या, यह देखना मुश्किल है कि कोड के किस हिस्से को निष्पादित किया जाता है।

तो मैं हर जगह एक गुच्छा डिबगिंग जानकारी डाल दिया। मुझे लगा कि मैं उन्हें बाद में हटा दूँगा।

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

मैंने डिबगिंग मोड पर विचार किया। हालांकि, मुझे डर है कि मैं डिबगिंग जानकारी को हटाना भूल जाऊंगा।

मैंने डिबगिंग मोड होने पर विचार किया यदि उपयोगकर्ता उदाहरण के लिए डिबगिंगमोड = 1 करता है। हालाँकि, मैं पागल था कि किसी तरह मेरे प्रतियोगी गुप्त कीवर्ड का अनुमान लगा सकते हैं।

मैंने अधिकांश डिबगिंग जानकारी हटा दी है। मैं किसी एक को हटाना भूल जाता हूं और यह केवल वही दिखाता है यदि उपयोगकर्ता सही देश से प्रॉक्सी का उपयोग करते हैं। पता चलता है कि मेरे पास सही देश से प्रॉक्सी नहीं है और इसका एहसास नहीं है। कार्यक्रम के 24 घंटे काम करने के बाद, मैंने उसे अपने मुख्य डोमेन पर अपलोड कर दिया।

मेरे प्रतियोगी, प्रॉक्सी का उपयोग करके, डिबगिंग कोड देखें। उन्होंने इस विचार की नकल की और इसी तरह मैंने प्रति दिन $ 800 खो दिए।

पूर्वव्यापी में, मेरे पास वास्तव में एक कठिन समय है जहां मैं गलत हो गया था। मैं सुपर सावधान हो गया हूँ। फिर भी ऐसा हुआ।

प्रतियोगियों को रहस्यों को उजागर किए बिना किसी को PHP वेब एप्लिकेशन को सुरक्षित रूप से कैसे डिबग करना चाहिए?


5
किसी भी चीज के बारे में पूरी तरह से निश्चित नहीं है, अकेले बगफ्री सॉफ्टवेयर को दें।
टार

1
कार्यक्रम / अनुप्रयोग में किए गए प्रत्येक परिवर्तन के बाद भी बार-बार परीक्षण करना, भले ही यह बहुत छोटा परिवर्तन हो।
रॉलिंग कोह

16
"प्रतियोगियों को रहस्य उजागर किए बिना किसी वेब अनुप्रयोग को सुरक्षित रूप से कैसे डिबग करना चाहिए?" - एक परीक्षण वातावरण बनाकर जो आपके उत्पादन वातावरण की नकल करता है। लाइव डिबगिंग वास्तव में बहुत कम ही आवश्यक होना चाहिए।
कोडकेस्टर

8
मुझे आश्चर्य है कि डिबगिंग कोड की दो लाइनों के बारे में इतना महत्वपूर्ण क्या हो सकता है कि इसकी कीमत प्रति दिन $ 800 है। क्या यह आपकी निजी क्रिप्टोग्राफ़िक कुंजी को डंप करता है?
फिलिप

2
यदि आप इससे पहले कुछ समय के लिए प्रति दिन $ 800 से अधिक कमा रहे थे ... क्या इससे भी कोई फर्क पड़ता है? लेकिन हाँ डिबग कोड को लाइव पर न डालें! आपके पास किसी फ़ाइल में एक डिबग मोड बूलियन हो सकता है। डिबग कोड केवल प्रिंट करें यदि डिबग == सच है। यह कम से कम एक त्वरित और गंदा तरीका है, जवाब देने के योग्य नहीं है!
Anon343224user

जवाबों:


37

मेरे पास वास्तव में एक कठिन समय है जहां मैं गलत हो गया था

बड़ी गलती यह थी कि आपने पहिया को फिर से स्थापित किया। लॉगिंग के लिए डिफ़ॉल्ट mecanism का उपयोग करने के बजाय, आपने अपना स्वयं का आविष्कार किया , जिसने पृष्ठ के भीतर जानकारी प्रदर्शित की। लॉगिंग फ़्रेमवर्क लॉग फ़ाइलों में लॉग को संग्रहीत करेगा, आपको सर्वर से SSHing द्वारा बाद में उन लॉग से परामर्श करने की अनुमति देता है।

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

■ देखें वे फास्ट कंपनी पत्रिका में सही सामान लिखते हैं
लेख में नासा में उपयोग की जाने वाली कार्यप्रणाली का वर्णन है, साथ ही इस तरह से सॉफ्टवेयर के निर्माण की लागत भी है।

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

यह कहा जा रहा है, सॉफ्टवेयर गुणवत्ता सुनिश्चित करने के लिए व्यावसायिक अनुप्रयोगों के लिए उपयोग की जाने वाली तकनीकों का एक समूह है। वे शामिल हैं, लेकिन इन तक सीमित नहीं हैं:

  • अनौपचारिक कोड समीक्षा,
  • औपचारिक कोड निरीक्षण,
  • परिक्षण,
  • कोड की व्यक्तिगत डेस्क-जाँच,
  • आदि।

कोड को पूरा देखें (मैककोनेल 2004), प्रोग्रामिंग प्रोडक्टिविटी (जोन्स 1986 ए), सॉफ्टवेयर दोष-निष्कासन दक्षता (जोन्स 1996), और फाइटिंग डिफेक्ट्स (शूल एट अल 2002) के बारे में हमने क्या सीखा है

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

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


13

आपको कभी भी उत्पादन में डिबग नहीं करना चाहिए।

आपके पास हमेशा एक परीक्षण वातावरण होना चाहिए जो वहां के उत्पादन वातावरण और डीबग के समान हो।

जब आपको परीक्षण वातावरण में कोड बदलने की आवश्यकता होती है (जैसे डिबगिंग स्टेटमेंट जोड़ने के लिए), तो आपको यह सुनिश्चित करना चाहिए कि वे उत्पादन में नहीं जाते हैं।

एक पेशेवर सेटअप आमतौर पर इस तरह दिखता है:

Production
   ^
Staging
   ^
Development

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

जब आपको किसी समस्या का विश्लेषण करने की आवश्यकता होती है, तो आप "विकास" में ऐसा करते हैं। डिबग कथनों के साथ मेस करें और अपने इच्छित सभी प्रयोग करें। जब आपको कोई समाधान मिला, तो आप उस कोड को "स्टेजिंग" में अपरिवर्तित कोडबेस पर लागू करते हैं और यह सत्यापित करते हैं कि फिक्स काम करता है। फिर आप "प्रोडक्शन" को ठीक करने को बढ़ावा देते हैं।

एक उचित संस्करण नियंत्रण और निर्माण प्रबंधन प्रणाली आपकी सहायता कर सकती है।


1
वही मैंने किया। मैं पहले अन्य डोमेन में डीबग करता हूं। उसके बाद, मैं नए लोगों के लिए कदम। हालाँकि, उस अन्य डोमेन पर बग अभी भी था।
user114310

1
@ user114310, आपका विकास / परीक्षण वातावरण केवल बाहरी दुनिया (या तो लोकलहोस्ट होने या वीपीएन, या इसी तरह की आवश्यकता) द्वारा सुलभ नहीं होना चाहिए। यदि आपने कुछ डिबग कोड डाला है और उत्पादन पर धकेलने से पहले इसे नहीं हटाया है, तो यह मानवीय त्रुटि है और ऐसा कुछ भी तकनीकी नहीं है जो इसके विरुद्ध सुरक्षा कर सके; बस और अधिक सावधान रहें।
ब्रायन एस

3
@ user114310 क्षमा करें, मुझे समझ नहीं आया। आपने मंचन में बग को ठीक किया लेकिन जब आपने लागू किया कि बग का उत्पादन ठीक करना है? इसका मतलब यह होगा कि आपने बग को सही ढंग से पुन: पेश नहीं किया और गलती से कुछ और तय कर दिया। जब आप विकास में बग को पुन: पेश करने में असमर्थ होते हैं, तो इसका मतलब है कि आपका विकास पर्यावरण उत्पादन वातावरण के समान नहीं है। जब आपको पता चलता है कि बग को ठीक से अनुसंधान करने से पहले आपको उसे ठीक करना होगा।
फिलिप

4

यह शायद ही कभी किया जाता है क्योंकि प्रयास सार्थक नहीं है। यहां तक ​​कि अगर आप एक दिन में $ 800 खो देते हैं, तो प्रोग्राम को सही साबित करने का प्रयास जल्दी से बड़ा हो जाता है, जिसका अर्थ है कि ऐसा करने के लिए कोई व्यावसायिक मामला नहीं है।

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


1
यहां तक ​​कि नासा को भी यह गलत लगता है। आप जितना चाहें उतना प्रयास कर सकते हैं, लेकिन कुछ चीजें बस मानवीय समझ से परे हैं और इस तरह आश्वासन देना बहुत मुश्किल है।
फोसिी

1
+1: औपचारिक सत्यापन एक चीज़ है, अगर आप इसके बारे में अधिक विस्तार से जा सकते हैं तो अच्छा होगा। मुझे पता है कि यह एक बात है, लेकिन मेरे पास अधिक विस्तार खोजने के लिए शब्द नहीं हैं। उदाहरण के लिए सभी निविष्टियों का परीक्षण करके, स्टेटमीचिन को परिमित करने के लिए कमी, पहले आदेश तर्क में कमी। इसके लिए शब्द क्या है? क्या यह सत्यापन द्वारा प्रमाण है? मुझे लगता है ऐसा है।
लिंडन व्हाइट

औपचारिक सत्यापन है, लेकिन यह भी है कि निश्चित सत्यापन नहीं है, जबकि कुछ निश्चित स्तर पर सत्यापन प्रदान कर सकता है। मुझे कॉलेज से विषय पर ज्यादा याद नहीं है, लेकिन एक उपकरण जिसका हमने पाठ्यक्रम में उपयोग किया था वह था स्पिन जिसे मैं मानता हूं कि संपूर्ण सत्यापन में भी सक्षम है। इस पर कुछ विवरण उत्तर दे सकते हैं कि सही शब्द क्या है।
रिग

2

कभी-कभी आपको लाइव सिस्टम को डीबग करने की आवश्यकता होती है। हां, आपके पास एक डेवलपमेंट या स्टेजिंग कॉपी होनी चाहिए। लेकिन हमेशा मतभेद रहने वाला है। यह विशेष रूप से सच है यदि कोड ग्राहक हार्डवेयर पर जंगली में चल रहा है। या संभावित रूप से, कई अलग-अलग ग्राहक स्थापनाएं।

मैंने पूर्व में & debugging = 1 तकनीक का उपयोग किया है। मुझे संदेह है कि अधिकांश PHP डेवलपर्स के पास है। उस कोड में एक स्विच फ़्लिप हो गया जो अनुप्रयोग में अधिक क्रिया डिबगिंग को सक्षम करता है। वह जानकारी आमतौर पर एक लॉग फ़ाइल में डाल दी जाएगी - आमतौर पर अपाचे लॉग (error_log () का उपयोग करके)। लेकिन, आप इसे आउटपुट भी कर सकते हैं। हमारे प्रोफाइलर, उदाहरण के लिए, जानकारी इकट्ठा करेंगे और फिर पृष्ठ के निचले भाग में विभिन्न बेंचमार्क का उत्पादन करेंगे। आप डिबगिंग जानकारी को एक HTML टिप्पणी के रूप में या एक छिपे हुए तत्व में भी आउटपुट कर सकते हैं यदि आप पृष्ठ स्रोत को देखते हैं।

यदि आपकी साइट में 'उपयोगकर्ता' हैं, तो आप डीबगिंग को केवल किसी विशेष उपयोगकर्ता तक सीमित कर सकते हैं। इस तरह से यदि कोई डिबगिंग को सक्षम करने का प्रयास करता है, तो यह तब तक कार्य नहीं करेगा जब तक कि वे उस उपयोगकर्ता के रूप में लॉग इन न हों।

अब, आपने उल्लेख किया कि आप सर्वर से जुड़ने के लिए FileZilla का उपयोग कर रहे थे। एक डेवलपर को सर्वर पर वास्तव में SSH का उपयोग करना चाहिए। यह आपके लिए डिबगिंग को बहुत आसान बना देगा। उदाहरण के लिए, यदि आप अपाचे त्रुटि लॉग में अपने डिबगिंग स्टेटमेंट को आउटपुट करने के लिए थे, उदाहरण के लिए, आप तब आसानी से उस फ़ाइल को अपने आईपी पते के लिए तैयार कर सकते हैं, और अपने अंतिम पृष्ठ अनुरोध द्वारा उत्पन्न डिबगिंग जानकारी देख सकते हैं।


1

बाकी सभी ने पहले से ही सामान्य मामले को कवर किया है:

औपचारिक मान्यता (/ सिद्ध कोड): वास्तविक विश्व कार्यक्रमों के लिए संभव नहीं है, हालांकि एक 4000 लाइन ओएस कर्नेल है, जो औपचारिक रूप से सिद्ध था, इसमें कई रूसी सीएस पीएचडी छात्रों को कई महीने लगे (कृपया इस परियोजना का नाम याद रखें टिप्पणी करें)

CI परीक्षण << स्वचालित परीक्षण << परीक्षण : सुनिश्चित करें कि आप अपने परीक्षण मामलों की 100% कवरेज की जाँच करने के लिए एक कवरेज उपकरण का उपयोग करते हैं।

डिबग कोड को उत्पादन में छोड़ने के आपके विशिष्ट मामले के लिए, मेरे पास 2 विकल्प हैं, दोनों को एक नए (स्टेजिंग / फाइनल टेस्टिंग) वातावरण में तैनाती के हिस्से के रूप में स्रोत कोड को फिर से जोड़ने की आवश्यकता है।

  1. इसे संकलन समय पर निकालें। #ifdef DEBUGबिल्ड लक्ष्य, (या तो डीबग या रिलीज़) की जाँच करने और उन्हें संकलन समय पर स्वचालित रूप से निकालने के लिए C # और C जैसी संरचनाओं में डिबग कोड लपेटें ।

  2. इसे डिपो समय पर चिह्नित करें। कोड के पास एक टिप्पणी रखें जो वास्तविक वातावरण में नहीं चलना चाहिए। उदाहरण के लिए //TODO: Remove This Before Deployment, तब जब कोड संकलित करने से पहले, यह स्टेजिंग के लिए माइग्रेट (तैनात) किया जाता है, तो इसे एक सरल स्क्रिप्ट के माध्यम से चलाएं, जो यह सुनिश्चित करने के लिए जांचता है कि //TODO:स्रोत कोड में कोई ध्वज टिप्पणी (उदाहरण ) नहीं बची है।

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


0

जैसा कि दूसरों ने मुझसे पहले कहा है, बहुत सारे परीक्षण (यूनिट और कार्यात्मक), यदि संभव हो तो स्वचालित और अच्छे कोड कवरेज के साथ ज्यादातर बग-मुक्त सॉफ़्टवेयर होने की कुंजी है।

यदि मुझे आपकी समस्या का वर्णन अच्छी तरह से समझ में आता है, तो डिबगिंग जानकारी आपके सर्वर द्वारा दिए गए पृष्ठ पर दिखाई जाती है। यदि ऐसा है, तो आपको उस जानकारी को अपने सर्वर पर उचित लॉग में डालने पर विचार करना चाहिए। इस तरह से इसे अंतिम उपयोगकर्ता को कभी नहीं दिखाया जाता है, भले ही आप उत्पादन के लिए 'वर्बोज़' संस्करण को तैनात करते हों। यह कुछ ऐसा है जो आप जिस भी परियोजना पर काम कर रहे हैं, उसे करना अच्छा है जब तक कि आपके पास अन्यथा करने के लिए बहुत अच्छे कारण न हों।


0

उत्पादन में डिबगिंग के बारे में अन्य लोग जो कहते हैं वह सही है। लेकिन मैंने इसे कभी भी किया है। और मुझे लगता है कि आपकी तुलना में यह सुरक्षित तरीके हैं, हालांकि कुछ भी मूर्ख नहीं है।

मुझे खुद ऐसी उच्च सुरक्षा की आवश्यकता नहीं है, मैं नहीं चाहता कि उपयोगकर्ता अपनी स्क्रीन पर जिबरिश का एक गुच्छा देखें।

$debug = true;
$allowed_ips = array('192.168.0.220','173.46.89.255'); // limit to your own ip's. If your competitor knows them, though, he can spoof it! But if your stuff is not top secret, it's ok. 

if(!in_array($_SERVER['REMOTE_ADDR'],$allowed_ips) ) {
  $debug = false;
}

if($debug) {
  echo '<pre>' . print_r($some_variable) . '</pre>';
}

अब उपयोगकर्ता आपके डिबगिंग को तब तक नहीं देखेंगे जब तक कि वे वास्तव में नहीं चाहते हैं। यदि आपका $ 800 / दिन इस डिबग जानकारी को गुप्त रखने पर निर्भर करता है, तो उपरोक्त कोड का उपयोग न करें । लेकिन अगर जानकारी इतनी संवेदनशील नहीं है, तो उपरोक्त जीईटी चर के आधार पर या अपने रहस्यों को पूरे देश में प्रकट करने से बेहतर होगा।

वैकल्पिक रूप से, आप एक debugवर्ग या फ़ंक्शन बना सकते हैं जो यह जांच करेगा कि मुद्रण की अनुमति दी गई है या आपके मानदंडों के आधार पर नहीं। यही तो मैं करता हूं।

कुछ इस तरह:

class debug {
  public $on = false;
  public static function print($variable) {
    if($on) {
      echo '<pre>' . print_r($some_variable) . '</pre>';
    }
  }
}

debug::print($some_variable); // class checks if printing is allowed. If not, no printing occurs.

मेरे कार्यक्रम के लिए जो मुझे $ 800 / दिन (विकास में) देगा, मैं साइट के किसी भी हिस्से तक पहुंचने के लिए एक पासवर्ड की आवश्यकता के लिए अपाचे आधुनिक माध्यम का उपयोग करता हूं, साथ ही साथ कुछ आईपी को डिबग जानकारी को प्रतिबंधित करता हूं। आपका सवाल मुझे लगता है कि मुझे बेहतर सुरक्षा में देखना चाहिए।


0

दरअसल, मेरे यहाँ दो अतिरिक्त सत्यापन होंगे। एक यह है &debug=1अनुरोध में पैरामीटर। आप कुछ विशेष सत्र चर या कुकी सेटअप का भी उपयोग कर सकते हैं, जिसे आप केवल "गुप्त" पृष्ठ पर कॉल के माध्यम से सक्रिय कर सकते हैं (अधिमानतः प्रमाणीकरण के साथ)।

दूसरी मान्यता कॉन्फ़िगरेशन फ़ाइल में होगी, जिसमें एक श्रेणी IPs की श्रेणी होती है और केवल उस IP में किसी कॉल से डीबगिंग कार्यक्षमता को ट्रिगर किया जा सकता है। कुछ इस तरह

विन्यास में:

$debugAllowedIPs = array('127.0.0.1', '192.168.0.1', /* add more IPs here */);

निम्नलिखित विधि कहीं है जहाँ इसे विश्व स्तर पर पहुँचा जा सकता है:

function getClientIp() {
    if (!empty($_SERVER['HTTP_CLIENT_IP']))  return $_SERVER['HTTP_CLIENT_IP'];
    if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) return $_SERVER['HTTP_X_FORWARDED_FOR'];
    return $_SERVER['REMOTE_ADDR'];
}

और आपके कोड में कुछ इस तरह से कॉल करें:

if (in_array(getClientIp(), $debugAllowedIPs)) { /* show debug info here */ }

कृपया ध्यान रखें कि getClientIp()विधि में कोड सुरक्षित नहीं है क्योंकि मूल्य $_SERVER['HTTP_X_FORWARDED_FOR']आसानी से खराब हो गया है, हालांकि यह आपके प्रश्न के लिए बिंदु प्राप्त करने के उद्देश्य की सेवा करना चाहिए।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.