Browser এ URL লিখলে কী হয়
একটা request এর পুরো যাত্রা
Browser এ https://shop.example.com.bd/products/42 লিখে Enter চাপলে আধা সেকেন্ডের মধ্যে পেজ চলে আসে। এই আধা সেকেন্ডে পর্দার আড়ালে কয়েক ডজন ধাপ ঘটে যায়, আর পৃথিবীর কয়েকটা দেশের computer এতে অংশ নেয়। System design এর প্রায় সব বিষয় (DNS, load balancer, cache, CDN, database) এই একটা যাত্রার কোনো না কোনো জায়গায় বসে আছে। তাই এই অধ্যায়টা পুরো course এর মানচিত্র।
তোমার Flutter app যখন dio.get('https://api.example.com/orders') চালায়, তখনও ঠিক এই একই ধাপগুলো ঘটে। পার্থক্য শুধু শেষে: browser HTML আঁকে, আর তোমার app JSON পড়ে widget বানায়।
#পুরো যাত্রা এক নজরে
ধাপগুলো সংক্ষেপে:
- URL ভাঙা: কোন protocol, কোন domain, কোন path
- DNS lookup: domain এর নাম থেকে IP address বের করা
- TCP connection: server এর সাথে নির্ভরযোগ্য সংযোগ তৈরি
- TLS handshake: সংযোগটা encrypt করা (HTTPS এর "S")
- HTTP request পাঠানো: "আমাকে
/products/42দাও" - Server এর ভেতরের কাজ: load balancer, app server, cache, database
- HTTP response ফেরত: status code, header, body
- Browser এ আঁকা: HTML, CSS, JavaScript থেকে পেজ তৈরি
এখন একটা একটা করে দেখি।
#ধাপ ১: URL ভাঙা
https://shop.example.com.bd:443/products/42?color=red#reviews
└─┬─┘ └────────┬────────┘└┬┘└────┬─────┘└───┬───┘└──┬──┘
scheme host port path query fragment- scheme (
https): কোন নিয়মে কথা হবে।httpsমানে encrypt করা HTTP। - host (
shop.example.com.bd): কোন computer এর সাথে কথা বলবো। - port (
443): সেই computer এর কোন "দরজা"। HTTPS এর default 443, HTTP এর 80। Default হলে লেখা লাগে না। - path (
/products/42): server এর কাছে কোন জিনিস চাই। - query (
?color=red): বাড়তি তথ্য, filter এর মতো। - fragment (
#reviews): শুধু browser এর জন্য, পেজের কোন অংশে যাবে। Server এ এটা যায়ই না।
#ধাপ ২: DNS, নাম থেকে ঠিকানা
Computer গুলো নাম চেনে না, চেনে IP address (যেমন 203.0.113.10)। ফোনের contact list এ যেমন নাম লিখলে নম্বর বের হয়, DNS (Domain Name System) ঠিক সেই কাজ করে।
Browser প্রথমে কয়েকটা cache এ দেখে, কোথাও পেলে আর বাইরে যায় না:
- Browser cache: এই tab বা আগের কোনো tab এ সম্প্রতি এই domain দেখা হয়েছে?
- OS cache: Mac নিজে মনে রেখেছে কিনা
- Router
- ISP এর DNS resolver (বা তুমি যদি
1.1.1.1বা8.8.8.8ব্যবহার করো, সেটা)
কোথাও না পেলে resolver নিজে খুঁজতে বের হয়:
প্রতিটা উত্তরের সাথে একটা TTL (Time To Live) থাকে, যেমন ৩০০ সেকেন্ড। মানে "৫ মিনিট এই উত্তর মনে রাখতে পারো"। তাই বেশিরভাগ সময় পুরো খোঁজাখুঁজি লাগে না, cache থেকেই উত্তর আসে।
#ধাপ ৩ ও ৪: TCP আর TLS handshake
IP পাওয়ার পর browser server এর সাথে সংযোগ তৈরি করে। এখানে দুইটা "হাত মেলানো" (handshake) হয়। নিচের ছবিতে উপর থেকে নিচে সময় বাড়ছে:
TCP handshake (৩ ধাপ): Browser বলে "কথা বলতে চাই" (SYN), server বলে "ঠিক আছে, আমিও" (SYN-ACK), browser বলে "চলো শুরু করি" (ACK)। TCP নিশ্চিত করে যে data ক্রম ঠিক রেখে, হারানো ছাড়া পৌঁছাবে।
TLS handshake: Server তার certificate দেখায়। এটা একটা ডিজিটাল পরিচয়পত্র, যেটা কোনো বিশ্বস্ত প্রতিষ্ঠান (Certificate Authority) sign করেছে। Browser যাচাই করে যে সত্যিই shop.example.com.bd এর সাথে কথা হচ্ছে, কোনো প্রতারকের সাথে না। তারপর দুই পক্ষ মিলে একটা গোপন key ঠিক করে, যা দিয়ে বাকি সব কথা encrypt হবে। এরপর মাঝপথে কেউ (যেমন public WiFi এর মালিক) data পড়তে পারবে না।
#ধাপ ৫: HTTP request
সংযোগ তৈরি হলে browser একটা লেখা পাঠায়। HTTP আসলে খুব সাধারণ text:
GET /products/42?color=red HTTP/1.1
Host: shop.example.com.bd
User-Agent: Mozilla/5.0 (Macintosh; ...)
Accept: text/html
Accept-Language: bn-BD,bn;q=0.9,en;q=0.8
Cookie: session_id=a8f3c...- প্রথম লাইন: method (
GET), path, আর HTTP version - বাকিগুলো header: বাড়তি তথ্য।
Cookieদিয়ে server বোঝে তুমি কে (login করা আছো কিনা)। POSTবাPUTrequest হলে header এর পরে একটা ফাঁকা লাইন, তারপর body (যেমন JSON) থাকে।
তোমার Flutter app এ Authorization: Bearer eyJhbGci... header দিয়ে token পাঠাও, সেটাও এই একই জিনিস।
#ধাপ ৬: Server এর ভেতরে
Request টা server এ পৌঁছানোর পর বড় system এ সাধারণত এই পথে যায়:
- CDN বা edge: Request যদি static file (ছবি, CSS) এর হয়, আর CDN এর কাছে copy থাকে, তাহলে এখান থেকেই ফেরত যায়। মূল server পর্যন্ত যায়ই না।
- Load balancer: অনেকগুলো app server এর মধ্যে কোনটা এই request সামলাবে ঠিক করে। (Load Balancer অধ্যায়)
- Reverse proxy / API gateway: TLS খোলা, rate limit, authentication check। অনেক সময় load balancer এই কাজও করে। (Proxy ও Gateway অধ্যায়)
- App server: তোমার FastAPI বা Laravel code এখানে চলে। Route মিলিয়ে ঠিক function চালায়।
- Cache: Product 42 এর তথ্য Redis এ আছে? থাকলে সেখান থেকে নাও (১ ms এরও কম)।
- Database: Cache এ না থাকলে PostgreSQL থেকে নাও (কয়েক ms থেকে কয়েকশো ms), তারপর পরের বারের জন্য cache এ রেখে দাও।
#ধাপ ৭: HTTP response
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 18342
Cache-Control: max-age=60
Set-Cookie: cart_id=77b1...; HttpOnly; Secure
<!doctype html>
<html>...Status code হলো উত্তরের সারাংশ:
| Code | মানে | কখন দেখবে |
|---|---|---|
200 OK |
সব ঠিক | সাধারণ সফল request |
201 Created |
নতুন জিনিস তৈরি হয়েছে | POST /orders সফল |
301 / 302 |
অন্য ঠিকানায় যাও | http থেকে https এ পাঠানো |
304 Not Modified |
তোমার কাছে যা আছে সেটাই ঠিক আছে | Browser cache এর copy এখনো চলবে |
400 Bad Request |
তোমার পাঠানো data ভুল | Form এর ভুল field |
401 Unauthorized |
আগে login করো | Token নেই বা মেয়াদ শেষ |
403 Forbidden |
Login আছে, কিন্তু অনুমতি নেই | সাধারণ user admin পেজে |
404 Not Found |
এমন কিছু নেই | ভুল URL |
429 Too Many Requests |
খুব বেশি request পাঠাচ্ছো | Rate limit |
500 Internal Server Error |
Server এর code এ সমস্যা | Bug, exception |
502 / 503 / 504 |
পেছনের server সাড়া দিচ্ছে না বা ব্যস্ত | Server down, overload, timeout |
মনে রাখার সহজ নিয়ম: 4xx মানে client এর ভুল, 5xx মানে server এর ভুল।
Cache-Control: max-age=60 header বলছে "এই উত্তর ৬০ সেকেন্ড পর্যন্ত আবার ব্যবহার করা যাবে"। Caching এর অনেকটাই এই header দিয়ে নিয়ন্ত্রিত হয়।
#ধাপ ৮: Browser এ পেজ আঁকা
HTML পাওয়ার পর browser:
- HTML পড়ে DOM tree বানায় (Flutter এর widget tree এর মতো)
- CSS পড়ে style বের করে
- JavaScript চালায়, যা DOM বদলাতে পারে
- Layout: কোন জিনিস কোথায়, কত বড়
- Paint: পর্দায় pixel আঁকা
HTML এর ভেতরে যত ছবি, CSS, JS file এর link থাকে, প্রতিটার জন্য আবার request যায় (বেশিরভাগ সময় একই সংযোগে বা CDN এ)। তাই একটা পেজ খুলতে আসলে ৫০-১০০টা request হওয়া স্বাভাবিক। Chrome এর DevTools → Network tab খুললে সব দেখতে পাবে।
তোমার Flutter app এ এই ধাপটা নেই। App টা JSON নিয়ে নিজেই widget বানায়, কারণ app এর UI আগে থেকেই phone এ install করা। এটাই mobile app এর একটা বড় সুবিধা: প্রতিবার শুধু data আসে, পুরো পেজ না।
#নিজে দেখো: হাতে-কলমে
Terminal এ:
# DNS: domain এর IP বের করো
dig +short github.com
nslookup google.com
# পুরো request-response দেখো (header সহ)
curl -v https://example.com 2>&1 | head -40
# প্রতিটা ধাপে কত সময় লাগলো
curl -o /dev/null -s -w "DNS: %{time_namelookup}s\nTCP: %{time_connect}s\nTLS: %{time_appconnect}s\nপ্রথম byte: %{time_starttransfer}s\nমোট: %{time_total}s\n" https://example.comশেষ command টা কয়েকবার চালাও। দ্বিতীয়বার DNS এর সময় কমে যাবে কিনা দেখো (cache)। তারপর দূরের কোনো site (যেমন আমেরিকার কোনো ছোট site) আর কাছের কোনো site এর সময় তুলনা করো।
#অনুশীলন
#নিজেকে যাচাই করো
URL এর `#reviews` অংশটা কি server এ যায়?
না। Fragment (# এর পরের অংশ) শুধু browser ব্যবহার করে, পেজের কোন অংশে scroll করবে বোঝাতে। HTTP request এ এটা পাঠানো হয় না।
DNS এর TTL কী? Server বদলানোর আগে কেন TTL কমানো হয়?
TTL হলো DNS উত্তর কতক্ষণ cache এ রাখা যাবে তার সময়। TTL বেশি হলে server এর IP বদলানোর পরও অনেক user অনেকক্ষণ পুরনো IP তে যেতে থাকবে। তাই migration এর কয়েক দিন আগে TTL কমিয়ে (যেমন ৬০ সেকেন্ড) রাখা হয়, যাতে বদল দ্রুত সবার কাছে পৌঁছায়।
401 আর 403 এর পার্থক্য কী?
401 মানে server জানে না তুমি কে, আগে login করো বা সঠিক token দাও। 403 মানে server জানে তুমি কে, কিন্তু এই কাজের অনুমতি তোমার নেই।
Flutter app এ প্রতিটা request এর জন্য নতুন `Dio()` বানালে কী সমস্যা হতে পারে?
প্রতিবার নতুন connection তৈরি হতে পারে, ফলে প্রতিটা request এ আবার TCP আর TLS handshake এর round trip লাগে। একটা Dio instance রেখে দিলে connection reuse হয় আর request দ্রুত হয়। তাছাড়া interceptor (token যোগ করা ইত্যাদি) এক জায়গায় রাখা যায়।
একটা পেজ খুলতে প্রথম byte আসতে (TTFB) অনেক সময় লাগছে, কিন্তু DNS আর connection দ্রুত। সমস্যা কোথায় খুঁজবে?
Server এর ভেতরে। মানে app server এর code ধীর, বা database query ধীর, বা cache কাজ করছে না। Network এর অংশ (DNS, TCP, TLS) ঠিক আছে বলে সমস্যা server-side processing এ।
চিহ্ন দিলে sidebar আর রোডম্যাপে এই অধ্যায়ের station ভরে যাবে।