---
title: "ओपनरेस्टी डायनामिक अनुरोध और प्रतिक्रियाओं के साथ उन्नत NGINX है - API7.ai"
description: "OpenResty डायनामिक अनुरोध और प्रतिक्रियाओं के साथ संवर्धित NGINX है, और यह लेख OpenResty में अनुरोध और प्रतिक्रिया को संचालित करने के लिए API को समझाता है, जैसे \"ngx.req.set_method\", \"ngx.req.set_uri_args\", \"ngx.req.set_header\", आदि।"
url: "https://api7.ai/hi/learning-center/openresty/handling-requests-responses-dynamically"
---

# ओपनरेस्टी डायनामिक अनुरोध और प्रतिक्रियाओं के साथ उन्नत NGINX है

API7.ai

October 23, 2022

[OpenResty (NGINX + Lua)](https://api7.ai/learning-center/openresty)

पिछले परिचय के बाद, आप OpenResty की अवधारणा और इसे कैसे सीखना है, यह समझ गए होंगे। यह लेख हमें यह बताएगा कि OpenResty क्लाइंट अनुरोधों और प्रतिक्रियाओं को कैसे संभालता है।

हालांकि OpenResty एक NGINX-आधारित वेब सर्वर है, यह NGINX से मूल रूप से अलग है: NGINX स्थिर कॉन्फ़िगरेशन फ़ाइलों द्वारा संचालित होता है, जबकि OpenResty Lua API द्वारा संचालित होता है, जो अधिक लचीलापन और प्रोग्रामेबिलिटी प्रदान करता है।

मैं आपको Lua API के लाभों के बारे में बताऊंगा।

## API श्रेणियाँ

सबसे पहले, हमें यह जानना होगा कि OpenResty API को निम्नलिखित व्यापक श्रेणियों में विभाजित किया गया है।

- अनुरोध और प्रतिक्रिया प्रसंस्करण।
- SSL-संबंधित।
- साझा डिक्ट।
- Cosocket।
- चार स्तरों के ट्रैफ़िक को संभालना।
- प्रक्रिया और कार्यकर्ता।
- NGINX वेरिएबल्स और कॉन्फ़िगरेशन तक पहुंच।
- स्ट्रिंग, समय, कोडेक, और अन्य सामान्य कार्य, आदि।

यहां, मैं सुझाव देता हूं कि आप OpenResty का Lua API दस्तावेज़ भी खोलें और [API सूची](https://github.com/openresty/lua-nginx-module/#nginx-api-for-lua) के साथ इसे जांचें कि क्या आप इस श्रेणी से संबंधित हो सकते हैं।

OpenResty API केवल lua-nginx-module प्रोजेक्ट में ही नहीं हैं, बल्कि lua-resty-core प्रोजेक्ट में भी हैं, जैसे `ngx.ssl`, `ngx.base64`, `ngx.errlog`, `ngx.process`, `ngx.re.split`, `ngx.resp.add_header`, `ngx.balancer`, `ngx.semaphore`, `ngx.ocsp`, और अन्य API।

जो API lua-nginx-module प्रोजेक्ट में नहीं हैं, उन्हें उपयोग करने के लिए आपको अलग से require करना होगा। उदाहरण के लिए, यदि आप split फ़ंक्शन का उपयोग करना चाहते हैं, तो आपको इसे निम्नानुसार कॉल करना होगा।

```
$ resty -e 'local ngx_re = require "ngx.re"
 local res, err = ngx_re.split("a,b,c,d", ",", nil, {pos = 5})
 print(res)
 '
```

बेशक, यह आपको भ्रमित कर सकता है: `lua-nginx-module` प्रोजेक्ट में, `ngx.re.sub`, `ngx.re.find`, आदि से शुरू होने वाले कई API हैं। फिर क्यों केवल `ngx.re.split` API को उपयोग करने से पहले require करने की आवश्यकता है?

जैसा कि हमने पिछले `lua-resty-core` अध्याय में उल्लेख किया था, नए OpenResty API को `lua-rety-core` रिपॉजिटरी में FFI के तरीके से लागू किया गया है, इसलिए इसमें विखंडन की भावना अनिवार्य रूप से है। मैं भविष्य में `lua-nginx-module` और `lua-resty-core` प्रोजेक्ट्स को मर्ज करके इस समस्या को हल करने की उम्मीद कर रहा हूं।

## अनुरोध

अगला, आइए देखें कि OpenResty क्लाइंट अनुरोधों और प्रतिक्रियाओं को कैसे संभालता है। सबसे पहले, आइए अनुरोधों को संभालने के लिए API को देखें, लेकिन `ngx.req` से शुरू होने वाले 20 से अधिक API हैं, तो हम कैसे शुरू करें?

हम जानते हैं कि HTTP अनुरोध संदेश तीन भागों से बना होता है: अनुरोध लाइन, अनुरोध हेडर, और अनुरोध बॉडी, इसलिए मैं इन तीन भागों में API का परिचय दूंगा।

### अनुरोध लाइन

पहले अनुरोध लाइन है, जिसमें HTTP के लिए अनुरोध विधि, URI, और HTTP प्रोटोकॉल संस्करण शामिल होता है। NGINX में, आप इस मान को एक बिल्ट-इन वेरिएबल का उपयोग करके प्राप्त कर सकते हैं, जबकि OpenResty में, यह `ngx.var.*` API से मेल खाता है। आइए दो उदाहरण देखें।

- बिल्ट-इन वेरिएबल `$scheme`, जो NGINX में प्रोटोकॉल का नाम दर्शाता है, या तो `http` या `https` होता है; OpenResty में, आप `ngx.var.scheme` का उपयोग करके उसी मान को वापस कर सकते हैं।
- `$request_method` अनुरोध विधि जैसे `GET`, `POST`, आदि को दर्शाता है; OpenResty में, आप `ngx.var.request_method` के माध्यम से उसी मान को वापस कर सकते हैं।

आप NGINX आधिकारिक दस्तावेज़ पर जाकर NGINX बिल्ट-इन वेरिएबल्स की पूरी सूची प्राप्त कर सकते हैं: <http://nginx.org/en/docs/http/ngx_http_core_module.html#variables>.

तो सवाल उठता है: जब आप `ngx.var.*` जैसे वेरिएबल के मान को वापस करके अनुरोध लाइन में डेटा प्राप्त कर सकते हैं, तो OpenResty अनुरोध लाइन के लिए एक अलग API क्यों प्रदान करता है?

इसके परिणाम में कई कारक शामिल हैं:

- सबसे पहले, `ngx.var` को बार-बार पढ़ने की सिफारिश नहीं की जाती है क्योंकि इसकी प्रदर्शन क्षमता कम होती है।
- दूसरा, प्रोग्राम-अनुकूल पहलू को ध्यान में रखते हुए, `ngx.var` एक स्ट्रिंग वापस करता है, न कि एक Lua ऑब्जेक्ट। जब `args` प्राप्त करते हैं, जो कई मान वापस कर सकता है, तो इसे संभालना मुश्किल होता है।
- तीसरा, लचीलेपन के पहलू से, `ngx.var` का अधिकांश भाग केवल पढ़ने योग्य होता है, और केवल कुछ वेरिएबल्स लिखने योग्य होते हैं, जैसे `$args` और `limit_rate`। हालांकि, हमें अक्सर विधि, URI, और args को संशोधित करने की आवश्यकता होती है।

इसलिए, OpenResty अनुरोध लाइन को संशोधित करने के लिए कई API प्रदान करता है, जो अनुरोध लाइन को पुनः लिख सकते हैं ताकि पुनर्निर्देशन जैसे बाद के ऑपरेशन किए जा सकें।

आइए देखें कि API के माध्यम से HTTP प्रोटोकॉल संस्करण संख्या कैसे प्राप्त करें। OpenResty API `ngx.req.http_version` NGINX `$server_protocol` वेरिएबल के समान कार्य करता है: HTTP प्रोटोकॉल का संस्करण संख्या वापस करना। हालांकि, इस API का रिटर्न वैल्यू एक स्ट्रिंग नहीं है बल्कि संख्यात्मक प्रारूप में है, जिसके संभावित मान `2.0`, `1.0`, `1.1`, और `0.9` हैं। यदि परिणाम इन मानों की सीमा से बाहर है तो `Nil` वापस आता है।

आइए अनुरोध लाइन में अनुरोध विधि प्राप्त करने की विधि देखें। जैसा कि उल्लेख किया गया है, `ngx.req.get_method` और NGINX के `$request_method` वेरिएबल्स की भूमिका और रिटर्न वैल्यू समान हैं: स्ट्रिंग प्रारूप में।

हालांकि, वर्तमान HTTP अनुरोध विधि `ngx.req.set_method` का पैरामीटर प्रारूप एक स्ट्रिंग नहीं है बल्कि बिल्ट-इन संख्यात्मक स्थिरांक है। उदाहरण के लिए, निम्नलिखित कोड अनुरोध विधि को POST में बदल देता है।

```
ngx.req.set_method(ngx.HTTP_POST)
```

यह सत्यापित करने के लिए कि बिल्ट-इन स्थिरांक, `ngx.HTTP_POST` वास्तव में एक संख्या है और स्ट्रिंग नहीं है, आप इसका मान प्रिंट कर सकते हैं और देख सकते हैं कि आउटपुट 8 है या नहीं।

```
resty -e 'print(ngx.HTTP_POST)'
```

इस तरह, `get` विधि का रिटर्न वैल्यू एक स्ट्रिंग है, जबकि `set` विधि का इनपुट वैल्यू एक संख्या है। यह ठीक है जब सेट विधि एक भ्रमित करने वाला मान पास करती है क्योंकि API क्रैश हो सकता है और `500` त्रुटि के साथ रिपोर्ट कर सकता है। हालांकि, निम्नलिखित निर्णय लॉजिक में:

```
if (ngx.req.get_method() == ngx.HTTP_POST) then
    -- कुछ करें
 end
```

इस तरह का कोड ठीक काम करता है, कोई त्रुटि रिपोर्ट नहीं करता है, और कोड समीक्षा के दौरान भी इसे ढूंढना मुश्किल होता है। मैंने पहले एक समान गलती की थी और अभी भी इसे याद कर सकता हूं: मैंने पहले ही दो राउंड की कोड समीक्षा और अधूरे टेस्ट केस को कवर करने की कोशिश की थी। अंत में, एक ऑनलाइन वातावरण में असामान्यता ने मुझे समस्या का पता लगाया।

ऐसी समस्या को हल करने के लिए कोई व्यावहारिक तरीका नहीं है सिवाय इसके कि अधिक सावधान रहें या एक और परत जोड़ें। जब आप अपने व्यवसाय API को डिज़ाइन करते हैं, तो आप `get` और `set` विधियों के सुसंगत पैरामीटर प्रारूप को भी ध्यान में रख सकते हैं, भले ही आपको कुछ प्रदर्शन का त्याग करना पड़े।

इसके अलावा, अनुरोध लाइन को पुनः लिखने की विधियों में, `ngx.req.set_uri` और `ngx.req.set_uri_args` दो API हैं, जिनका उपयोग URI और args को पुनः लिखने के लिए किया जा सकता है। आइए इस NGINX कॉन्फ़िगरेशन को देखें।

```
rewrite ^ /foo?a=3? break;
```

तो, हम इसे समकक्ष Lua API के साथ कैसे हल कर सकते हैं? उत्तर निम्नलिखित दो लाइनों का कोड है।

```
ngx.req.set_uri_args("a=3")
ngx.req.set_uri("/foo")
```

यदि आपने आधिकारिक दस्तावेज़ पढ़ा है, तो आप पाएंगे कि `ngx.req.set_uri` का दूसरा पैरामीटर: `jump`, जो डिफ़ॉल्ट रूप से "false" है। यदि आप इसे "true" के रूप में सेट करते हैं, तो यह `rewrite` कमांड के फ्लैग को `last` के बजाय `break` के रूप में सेट करने के बराबर है, जैसा कि ऊपर के उदाहरण में है।

हालांकि, मुझे `rewrite` कमांड के फ्लैग कॉन्फ़िगरेशन पसंद नहीं है क्योंकि यह अप्राप्य और अज्ञात है और कोड की तुलना में कम सहज और रखरखाव योग्य है।

### अनुरोध हेडर

जैसा कि हम जानते हैं, HTTP अनुरोध हेडर `key : value` प्रारूप में होते हैं, उदाहरण के लिए:

```
  Accept: text/css,*/*;q=0.1
  Accept-Encoding: gzip, deflate, br
```

OpenResty में, आप `ngx.req.get_headers` का उपयोग करके अनुरोध हेडर को पार्स और प्राप्त कर सकते हैं, और रिटर्न वैल्यू प्रकार टेबल है।

```
local h, err = ngx.req.get_headers()
  if err == "truncated" then
      -- कोई यहां वर्तमान अनुरोध को अनदेखा या अस्वीकार करने का विकल्प चुन सकता है
  end
  for k, v in pairs(h) do
      ...
  end
```

यह डिफ़ॉल्ट रूप से पहले 100 हेडर वापस करता है। यदि संख्या 100 से अधिक है, तो यह एक `truncated` त्रुटि रिपोर्ट करेगा, जिसे डेवलपर को यह तय करने के लिए छोड़ दिया जाता है कि इसे कैसे संभाला जाए। आप सोच सकते हैं कि इसे इस तरह क्यों लिया गया है, जिसका उल्लेख मैं बाद में सुरक्षा कमजोरियों के अनुभाग में करूंगा।

हालांकि, हमें ध्यान देना चाहिए कि OpenResty किसी विशिष्ट अनुरोध हेडर को प्राप्त करने के लिए कोई विशिष्ट API प्रदान नहीं करता है, जिसका अर्थ है कि `ngx.req.header['host']` जैसा कोई रूप नहीं है। यदि आपके पास ऐसी आवश्यकता है, तो आपको NGINX वेरिएबल `$http_xxx` पर निर्भर रहना होगा। फिर OpenResty में, आप इसे `ngx.var.http_xxx` के माध्यम से प्राप्त कर सकते हैं।

अब आइए देखें कि हमें अनुरोध हेडर को पुनः लिखने और हटाने के लिए कैसे करना चाहिए। दोनों ऑपरेशन के लिए API काफी सहज हैं:

```
ngx.req.set_header("Content-Type", "text/css")
ngx.req.clear_header("Content-Type")
```

बेशक, आधिकारिक दस्तावेज़ में अनुरोध हेडर को हटाने के अन्य तरीकों का भी उल्लेख किया गया है, जैसे कि शीर्षक के मान को `nil` पर सेट करना, आदि। हालांकि, मैं अभी भी कोड की स्पष्टता के लिए `clear_header` का उपयोग करने की सिफारिश करता हूं।

### अनुरोध बॉडी

अंत में, आइए अनुरोध बॉडी को देखें। प्रदर्शन कारणों से, OpenResty सक्रिय रूप से अनुरोध बॉडी को नहीं पढ़ता है जब तक कि आप `nginx.conf` में `lua_need_request_body` निर्देश को सक्षम नहीं करते हैं। इसके अलावा, बड़े अनुरोध बॉडी के लिए, OpenResty सामग्री को डिस्क पर एक अस्थायी फ़ाइल में सहेजता है, इसलिए अनुरोध बॉडी को पढ़ने की पूरी प्रक्रिया इस तरह दिखती है।

```
ngx.req.read_body()
local data = ngx.req.get_body_data()
if not data then
    local tmp_file = ngx.req.get_body_file()
     -- io.open(tmp_file)
     -- ...
 end
```

इस कोड में डिस्क फ़ाइल को पढ़ने के लिए एक IO-ब्लॉकिंग ऑपरेशन है। आपको `client_body_buffer_size` (64-बिट सिस्टम पर डिफ़ॉल्ट रूप से 16 KB) के कॉन्फ़िगरेशन को समायोजित करना चाहिए ताकि ब्लॉकिंग ऑपरेशन को कम से कम किया जा सके; आप `client_body_buffer_size` और `client_max_body_size` को समान रूप से कॉन्फ़िगर कर सकते हैं और उन्हें पूरी तरह से मेमोरी में संभाल सकते हैं, यह आपकी मेमोरी के आकार और आपके द्वारा लिए जाने वाले समवर्ती अनुरोधों की संख्या पर निर्भर करता है।

इसके अलावा, अनुरोध बॉडी को पुनः लिखा जा सकता है। दो API `ngx.req.set_body_data` और `ngx.req.set_body_file` एक स्ट्रिंग और एक स्थानीय डिस्क फ़ाइल को इनपुट पैरामीटर के रूप में स्वीकार करते हैं ताकि अनुरोध बॉडी को पुनः लिखा जा सके। हालांकि, इस प्रकार का ऑपरेशन असामान्य है, और आप अधिक विवरण के लिए दस्तावेज़ देख सकते हैं।

## प्रतिक्रिया

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

### स्थिति लाइन

स्थिति लाइन में हम मुख्य रूप से स्थिति कोड के बारे में चिंतित हैं। डिफ़ॉल्ट रूप से, वापस आने वाला HTTP स्थिति कोड 200 है, जो OpenResty में बिल्ट-इन स्थिरांक `ngx.HTTP_OK` है। लेकिन कोड की दुनिया में, हमेशा सबसे असाधारण मामलों को संभालने वाला कोड होता है।

यदि आप अनुरोध संदेश का पता लगाते हैं और पाते हैं कि यह एक दुर्भावनापूर्ण अनुरोध है, तो आपको अनुरोध को समाप्त करने की आवश्यकता है:

```
ngx.exit(ngx.HTTP_BAD_REQUEST)
```

हालांकि, OpenResty के HTTP स्थिति कोड में एक विशेष स्थिरांक है: `ngx.OK`। `ngx.exit(ngx.OK)` की स्थिति में, अनुरोध वर्तमान प्रसंस्करण चरण से बाहर निकलता है और अगले चरण में चला जाता है, न कि सीधे क्लाइंट को वापस आता है।

बेशक, आप बाहर निकलने का विकल्प नहीं चुन सकते हैं और केवल स्थिति कोड को `ngx.status` का उपयोग करके पुनः लिख सकते हैं, जैसा कि निम्नलिखित तरीके से लिखा गया है।

```
ngx.status = ngx.HTTP_FORBIDDEN
```

यदि आप स्थिति कोड स्थिरांक के बारे में अधिक जानना चाहते हैं, तो आप [दस्तावेज़](https://github.com/openresty/lua-nginx-module/#http-status-constants) में उन्हें देख सकते हैं।

### प्रतिक्रिया हेडर

प्रतिक्रिया हेडर के संबंध में, आप इसे दो तरीकों से सेट कर सकते हैं। पहला तरीका सबसे सरल है।

```
ngx.header.content_type = 'text/plain'
ngx.header["X-My-Header"] = 'blah blah'
ngx.header["X-My-Header"] = nil -- हटाएं
```

यहां `ngx.header` प्रतिक्रिया हेडर जानकारी को रखता है, जिसे पढ़ा, संशोधित और हटाया जा सकता है।

प्रतिक्रिया हेडर सेट करने का दूसरा तरीका `ngx_resp.add_header` है, जो `lua-resty-core` रिपॉजिटरी से है, जो एक हेडर संदेश जोड़ता है, जिसे इस तरह कॉल किया जाता है:

```
local ngx_resp = require "ngx.resp"
ngx_resp.add_header("Foo", "bar")
```

पहले तरीके के साथ अंतर यह है कि `add_header` मौजूदा समान नाम के फ़ील्ड को ओवरराइट नहीं करता है।

### प्रतिक्रिया बॉडी

अंत में, प्रतिक्रिया बॉडी को देखें। OpenResty में, आप `ngx.say` और `ngx.print` का उपयोग करके प्रतिक्रिया बॉडी को आउटपुट कर सकते हैं।

```
ngx.say('hello, world')
```

दोनों API की कार्यक्षमता समान है, केवल अंतर यह है कि `ngx.say` के अंत में एक लाइन फ़ीड होता है।

स्ट्रिंग जोड़ने की अक्षमता से बचने के लिए, `ngx.say / ngx.print` स्ट्रिंग और सरणी प्रारूप को पैरामीटर के रूप में समर्थन करता है।

```
$ resty -e 'ngx.say({"hello", ", ", "world"})'
 hello, world
```

यह विधि Lua स्तर पर स्ट्रिंग जोड़ने को छोड़ देती है और इसे C फ़ंक्शन को संभालने के लिए छोड़ देती है।

## सारांश

आइए आज की सामग्री की समीक्षा करें। हमने अनुरोध और प्रतिक्रिया संदेशों से संबंधित OpenResty API का परिचय दिया। जैसा कि आप देख सकते हैं, OpenResty API NGINX निर्देश से अधिक लचीला और शक्तिशाली है।

नतीजतन, क्या OpenResty द्वारा प्रदान किया गया Lua API आपकी आवश्यकताओं को पूरा करने के लिए पर्याप्त है जब आप HTTP अनुरोधों को संभाल रहे हैं? कृपया अपनी टिप्पणियाँ छोड़ें और इस लेख को अपने सहयोगियों और दोस्तों के साथ साझा करें ताकि हम एक साथ संवाद और सुधार कर सकें।

Share article link

Share

Related Posts

[![OpenResty FAQ | OpenResty का व्यवहारिक उपयोग कैसे किया जाता है](https://static.api7.ai/uploads/2023/02/12/jbv9M0zi_Hello%20World%20in%20OpenResty%20%283%29.png)](https://api7.ai/learning-center/openresty/faq-5)

## [OpenResty FAQ | OpenResty का व्यवहारिक उपयोग कैसे किया जाता है](https://api7.ai/learning-center/openresty/faq-5)

[![भाग 3: OpenResty का उपयोग करके एक Microservices API Gateway कैसे बनाएं](https://static.api7.ai/uploads/2023/02/07/3XJXY9Jy_45.png)](https://api7.ai/learning-center/openresty/how-to-build-a-microservices-api-gateway-part-3)

## [भाग 3: OpenResty का उपयोग करके एक Microservices API Gateway कैसे बनाएं](https://api7.ai/learning-center/openresty/how-to-build-a-microservices-api-gateway-part-3)

Table of Contents

- [API श्रेणियाँ](#api-%E0%A4%B6%E0%A5%8D%E0%A4%B0%E0%A5%87%E0%A4%A3%E0%A4%BF%E0%A4%AF%E0%A4%BE%E0%A4%81)

- [अनुरोध](#%E0%A4%85%E0%A4%A8%E0%A5%81%E0%A4%B0%E0%A5%8B%E0%A4%A7)

  - [अनुरोध लाइन](#%E0%A4%85%E0%A4%A8%E0%A5%81%E0%A4%B0%E0%A5%8B%E0%A4%A7-%E0%A4%B2%E0%A4%BE%E0%A4%87%E0%A4%A8)
  - [अनुरोध हेडर](#%E0%A4%85%E0%A4%A8%E0%A5%81%E0%A4%B0%E0%A5%8B%E0%A4%A7-%E0%A4%B9%E0%A5%87%E0%A4%A1%E0%A4%B0)
  - [अनुरोध बॉडी](#%E0%A4%85%E0%A4%A8%E0%A5%81%E0%A4%B0%E0%A5%8B%E0%A4%A7-%E0%A4%AC%E0%A5%89%E0%A4%A1%E0%A5%80)

- [प्रतिक्रिया](#%E0%A4%AA%E0%A5%8D%E0%A4%B0%E0%A4%A4%E0%A4%BF%E0%A4%95%E0%A5%8D%E0%A4%B0%E0%A4%BF%E0%A4%AF%E0%A4%BE)

  - [स्थिति लाइन](#%E0%A4%B8%E0%A5%8D%E0%A4%A5%E0%A4%BF%E0%A4%A4%E0%A4%BF-%E0%A4%B2%E0%A4%BE%E0%A4%87%E0%A4%A8)
  - [प्रतिक्रिया हेडर](#%E0%A4%AA%E0%A5%8D%E0%A4%B0%E0%A4%A4%E0%A4%BF%E0%A4%95%E0%A5%8D%E0%A4%B0%E0%A4%BF%E0%A4%AF%E0%A4%BE-%E0%A4%B9%E0%A5%87%E0%A4%A1%E0%A4%B0)
  - [प्रतिक्रिया बॉडी](#%E0%A4%AA%E0%A5%8D%E0%A4%B0%E0%A4%A4%E0%A4%BF%E0%A4%95%E0%A5%8D%E0%A4%B0%E0%A4%BF%E0%A4%AF%E0%A4%BE-%E0%A4%AC%E0%A5%89%E0%A4%A1%E0%A5%80)

- [सारांश](#%E0%A4%B8%E0%A4%BE%E0%A4%B0%E0%A4%BE%E0%A4%82%E0%A4%B6)
