در این مقاله به بررسی مفاهیم اولیه HTTP می پردازیم.
اما چرا HTTP؟
شاید از خودتان بپرسید چرا باید درباره HTTP مطالعه کنم؟
خوب، اگر توسعهدهنده نرمافزار هستید، با یادگیری نحوه برقراری ارتباط بین اپلیکیشنها، نحوه نوشتن بهتر آنها را درک خواهید کرد. همچنین اگر معمار سیستم یا مدیر شبکه هستید، دانش عمیق تری در مورد طراحی معماری های پیچیده شبکه کسب خواهید کرد.
REST، که امروزه یک سبک معماری بسیار مهم است، کاملاً بر استفاده از ویژگی های HTTP تکیه دارد، به طوری که درک HTTP را بیش از پیش مهم قلمداد می کند. اگر می خواهید اپلیکیشنهای RESTful عالی بسازید، ابتدا باید HTTP را درک کنید.
باید توجه داشته باشم که REST فقط به HTTP متکی نیست. میتوان آن را با استفاده از پروتکلهای دیگر نیز پیادهسازی کرد، اما به نظر میرسد که HTTP با اختلاف نسبتا خوبی در این نبرد پیروز شده است و به سختی پیادهسازی REST را با استفاده از پروتکلهای دیگر پیدا خواهید کرد.
بنابراین آیا مایلید فرصت درک و یادگیری مفاهیم بنیادی شبکه جهانی وب و ارتباطات شبکه را نادیده بگیرید؟
امیدوارم که اینطور نباشد.
این مقاله بر روی مهمترین بخشهای HTTP تمرکز میکند و سعی میکند تا حد امکان آنها را به سادگی توضیح دهد. نیت این است که تمام اطلاعات مفید در مورد HTTP را در یک یکجا سازماندهی کنیم تا در زمان شما برای مرور کتاب ها و RFC ها جهت یافتن اطلاعات مورد نیاز شما صرفه جویی شود.
این اولین مقاله از سری آموزشی HTTP است. این مقاله، مقدمه ای کوتاه بر مفاهیم پایه HTTP میباشد.
شما عناوین زیر را یاد خواهید گرفت:
- تعریف HTTP
- منابع
- نحوه تبادل پیام بین یک سرویس گیرنده وب و یک وب سرور
- تعدادی از نمونه پیامها
- MIME Type ها
- متدهای Request
- Header ها
- Status Code ها
بدون هیچگونه معطلی، کار خود را شروع میکنیم.
تعریف HTTP
بنیانگذار Tim Berners-Lee ،HTTP است (کسی که او را مخترع شبکه جهانی وب نیز میدانند). از دیگر نامهای مهم برای توسعه
Roy Fielding ،HTTP نیز است که مبتکر سبک معماری REST است.
Hypertext Transfer Protocol، پروتکلی است که برنامه ها از آن برای برقراری ارتباط با یکدیگر استفاده می کنند. در اصل، HTTP وظیفه تفویض تمام فایل های رسانه ای اینترنت را بین کلاینتها و سرورها بر عهده دارد. این فایلها، شامل HTML، تصاویر، فایلهای متنی، فیلمها و همه چیز در این بین میباشد. و این کار را به سرعت و با اطمینان انجام می دهد.
HTTP پروتکل اپلیکیشن است و نه پروتکل انتقال. زیرا ما از آن برای ارتباط در لایه اپلیکیشن استفاده می کنیم. برای بهتر جا افتادن این موضوع، این را در نظر داشته باشید که پشته شبکه چطور به نظر می رسد.
از این تصویر، به وضوح می توانید ببینید که HTTP پروتکل اپلیکیشن است و TCP بر روی لایه transport کار می کند.
منابع
همه چیز در اینترنت یک منبع یا resource است و HTTP با منابع کار می کند. این شامل فایلها، stream ها، service ها و هر چیز دیگری میشود. یک صفحه HTML یک منبع است، یک ویدیوی یوتیوب یک منبع است، spreadsheet کارهای روزانه شما در یک برنامه وب یک منبع است… نکته را گرفتید!
و چگونه یک منبع را از منبع دیگر متمایز می کنید؟
با دادن URL به آنها (Uniform resource locators).
یک URL به مکان منحصر به فردی که منبع در آن قرار دارد اشاره می کند.
نحوه تبادل پیام بین یک سرویس گیرنده وب و یک وب سرور
هر بخش از محتوا، هر منبعی روی تعدادی وب سرور (سرور HTTP) قرار میگیرند. این سرورها منتظر درخواستهایی برای این منابع هستند.
اما چگونه می توان یک منبع را از یک وب سرور درخواست کرد؟
البته شما اینجا به یک client نیاز دارید.
شما در حال حاضر از یک HTTP Client برای خواندن این مقاله استفاده می کنید. مرورگرهای وب، HTTP Client ها هستند. این Client ها، با سرورهای HTTP ارتباط برقرار می کنند تا منابع را به رایانه شما برسانند. برخی از محبوب ترین Client ها، کروم گوگل، فایرفاکس موزیلا، اپرا، سافاری اپل و متاسفانه هنوز اینترنت اکسپلورر بدنام میباشند.
تعدادی از نمونه پیامها
بنابراین یک پیام HTTP چگونه به نظر می رسد؟
بدون اینکه زیاد در مورد آن صحبت کنیم، در اینجا چند نمونه از پیام های HTTP آورده شده است:
GET request
1 2 3 4 5 |
GET /repos/CodeMazeBlog/ConsumeRestfulApisExamples HTTP/1.1 Host: api.github.com Content-Type: application/json Authorization: Basic dGhhbmtzIEhhcmFsZCBSb21iYXV0LCBtdWNoIGFwcHJlY2lhdGVk Cache-Control: no-cache |
POST request
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
POST /repos/CodeMazeBlog/ConsumeRestfulApisExamples/hooks?access_token=5643f4128a9cf974517346b2158d04c8aa7ad45f HTTP/1.1 Host: api.github.com Content-Type: application/json Cache-Control: no-cache { "url": "http://www.example.com/example", "events": [ "push" ], "name": "web", "active": true, "config": { "url": "http://www.example.com/example", "content_type": "json" } } |
در اینجا نمونه ای از یک درخواست GET و یک درخواست POST آورده شده است. اجازه دهید به سرعت قسمت های مختلف این درخواست ها را با هم بررسی کنیم.
خط اول request به عنوان request line رزرو شده است. این شامل نام request URI، request method و ورژن HTTP میباشد.
چند خط بعدی، ارائه دهنده request header ها است. request header ها، اطلاعات بیشتری را برای request ها ارائه میکنند، مانند انواع محتوای مورد انتظار request در response، اطلاعات مجوز و غیره،
برای درخواست GET، داستان درست همین جا به پایان می رسد. یک درخواست POST همچنین میتواند دارای body نیز باشد و اطلاعات اضافی را در قالب یک پیام body دربر داشته باشد. در این موردی که در بالا آورده ایم، این یک پیام JSON با اطلاعات اضافی در مورد نحوه ایجاد وب هوک GitHub برای مخزن مشخص شده در URI است. این پیام برای ایجاد webhook مورد نظر مورد نیاز است، بنابراین ما از یک درخواست POST برای ارائه آن اطلاعات به API GitHub استفاده کرده ایم.
Reference برای درخواست HTTP:
https://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html
و چه چیزی را به عنوان response از این request ها دریافت میکنیم:
پیام Response:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
HTTP/1.1 200 OK Server: GitHub.com Date: Sun, 18 Jun 2017 13:10:41 GMT Content-Type: application/json; charset=utf-8 Transfer-Encoding: chunked Status: 200 OK X-RateLimit-Limit: 5000 X-RateLimit-Remaining: 4996 X-RateLimit-Reset: 1497792723 Cache-Control: private, max-age=60, s-maxage=60 [ { "type": "Repository", "id": 14437404, "name": "web", "active": true, "events": [ "push" ], "config": { "content_type": "json", "insecure_ssl": "0", "url": "http://www.example.com/example" }, "updated_at": "2017-06-18T12:17:15Z", "created_at": "2017-06-18T12:03:15Z", "url": "https://api.github.com/repos/CodeMazeBlog/ConsumeRestfulApisExamples/hooks/14437404", "test_url": "https://api.github.com/repos/CodeMazeBlog/ConsumeRestfulApisExamples/hooks/14437404/test", "ping_url": "https://api.github.com/repos/CodeMazeBlog/ConsumeRestfulApisExamples/hooks/14437404/pings", "last_response": { "code": 422, "status": "misconfigured", "message": "Invalid HTTP Response: 404" } }, ] |
ساختار پیام response تقریباً مشابه پیام request است، به جز خط اول، به نام خط status، که به طرز شگفت انگیزی حاوی اطلاعاتی در مورد response status است.
Response header ها و response body درست بعد از خط status قرار میگیرند.
Reference برای HTTP response:
https://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html
MIME Type ها
انواع MIME یک روش استاندارد برای توصیف انواع فایل در اینترنت است. مرورگر شما فهرستی از انواع MIME را دارد و همین امر در مورد سرورهای وب نیز صدق می کند. به این ترتیب میتوانیم فایلها را بدون در نظر گرفتن سیستمعامل به شیوهای رایج انتقال دهیم.
واقعیت جالب این است که MIME مخفف عبارت Multipurpose Mail Extension است زیرا در ابتدا برای ایمیل چندرسانه ای توسعه یافته بودند. آنها از آن زمان برای استفاده برای HTTP و چندین پروتکل دیگر سازگار شدند.
هر نوع MIME از یک subtype ،type و لیستی از پارامترهای اختیاری در قالب زیر تشکیل شده است:
پارامترهای اختیاری;type/subtype .
در اینجا چند نمونه آورده شده است:
1 2 3 |
Content-Type: application/json Content-Type: text/xml; charset=utf-8 Accept: image/gif |
می توانید لیستی از انواع MIME و زیرگونه های رایج مورد استفاده را در مرجع HTTP پیدا کنید.
متدهای Request
متدهای درخواست HTTP (که به آنها «verbs» نیز گفته میشود) action را که روی resource انجام میشود را تعریف میکند. HTTP چندین متد درخواست را تعریف می کند. متداولترین متدهای شناخته شده/استفاده شده، متدهای GET و POST هستند.
یک متد درخواست میتواند idempotent یا غیر idempotent باشد. این فقط یک اصطلاح فانتزی برای توضیح این است که متد safe/unsafe است که چندین بار در resource های مشابه فراخوانی شود. به عبارت دیگر، این بدان معناست که یک متد GET، که تنها هدف آن بازیابی اطلاعات است، به طور پیشفرض باید idempotent باشد. تماس مکرر با GET در یک resource نباید به پاسخ متفاوتی منجر شود. از طرف دیگر، متد POST یک متد idempotent نیست.
قبل از HTTP/1.1، فقط سه متد وجود داشت: GET، POST، و HEAD، و مشخصات HTTP/1.1 چند متد دیگر را نیز وارد بازی کرد: OPTIONS، PUT، DELETE، TRACE و CONNECT.
نحوه عملکرد هر یک از این متدها را در مرجع HTTP بیشتر بیابید.
Header ها
فیلدهای Header، فیلدهای name-value هستند که با کولون جدا میشوند که می توانید بلافاصله بعد از اولین خط یک درخواست یا پیام response آن را پیدا کنید. آنها context بیشتری را برای پیام ها فراهم می کنند و کلاینتها و سرورها را در مورد ماهیت request یا response آگاه می کنند.
پنج نوع header وجود دارد:
- header های عمومی: این header ها هم برای سرور و هم برای کلاینت مفید هستند. یک مثال خوب، فیلد header تاریخ است که اطلاعاتی در مورد زمان ایجاد پیام ارائه می دهد.
- header های Request: مخصوص پیام های request است. آنها اطلاعات اضافی را در اختیار سرور قرار می دهند. به عنوان مثال، فیلد هدر * /* :Accept به سرور اطلاع می دهد که کلاینت مایل به دریافت هر نوع رسانه ای است.
- header های Response: مخصوص پیام های response است. آنها اطلاعات اضافی را در اختیار کلاینت قرار می دهند. به عنوان مثال، فیلد هدر Allow: GET، HEAD، PUT به کلاینت اطلاع می دهد که کدام متدها برای resource درخواستی مجاز هستند.
- header های Entity: این هدرها با entity-body سروکار دارند. به عنوان مثال، هدر Content-Type: text/html به برنامه اجازه می دهد بداند که داده ها یک سند HTML هستند.
- header های Extension: اینها header های غیر استانداردی هستند که توسعه دهندگان برنامه می توانند بسازند. اگرچه آنها بخشی از HTTP نیستند، اما آنها را میپذیرند.
شما می توانید لیستی از request header ها و response header های رایج مورد استفاده را در مرجع HTTP بیابید.
Status Code ها
status code یک عدد سه رقمی است که نتیجه یک درخواست را نشان می دهد. توضیح کد وضعیت مورد نظر که قابل خواندن برای انسان است درست بعد از status code می آید.
برخی از این نمونه کدهذای وضعیت عبارتند از:
200 OK
404 Not Found
500 Internal Server Error
کدهای وضعیت بر اساس محدوده در پنج گروه مختلف طبقه بندی می شوند.
هم طبقه بندی کدهای وضعیت و هم کل لیست کدهای وضعیت و معنی آنها را می توانید در مرجع HTTP بیابید.
نتیجه گیری
اوه، این اطلاعات، اطلاعات زیادی بود.
دانشی که با یادگیری مفاهیم اولیه HTTP به دست می آورید، آن گونه نیست که به شما در حل مستقیم برخی از مشکلات کمک کند. اما به شما درک درستی از اصل اساسی ارتباطات اینترنتی می دهد که می توانید تقریباً برای هر مشکل دیگری در سطحی بالاتر از HTTP اعمال کنید. خواه REST، API، توسعه web application یا شبکه باشد، اکنون می توانید در حل این نوع مشکلات، حداقل کمی اعتماد به نفس بیشتری داشته باشید.
البته، HTTP یک موضوع بسیار بزرگی برای صحبت کردن است و هنوز مفاهیم اولیه خیلی بیشتری در مورد آن وجود دارد.