HTTP vs HTTPS, ports and common protocols
40 min · Intermediate
Need help? Ask a tutor on WhatsApp (opens in a new tab)An interviewer fires "status code for not logged in?", "port for SSH?" and "what does the padlock mean?" back to back. This lesson is the quick revision that keeps those answers short, exact and ready.
HTTP methods and status codes at a glance
HTTP (HyperText Transfer Protocol) is the request-response protocol of the web. A request has a method, a path, headers and an optional body; the response has a status code, headers and a body.
Two examples: one sorts status codes into their classes, the other shows a raw HTTP request and response as plain text.
Example 1 · Classifying status codes
from http import HTTPStatus
KINDS = {1: "informational", 2: "success", 3: "redirect", 4: "client error", 5: "server error"}
def kind(code): return KINDS.get(code // 100, "invalid")
for code in [200, 201, 304, 401, 403, 404, 500, 503]: print(f"{code} {HTTPStatus(code).phrase:<22} {kind(code)}")200 OK success 201 Created success 304 Not Modified redirect 401 Unauthorized client error 403 Forbidden client error 404 Not Found client error 500 Internal Server Error server error 503 Service Unavailable server error
What this code does
- Integer division by 100 gives the first digit, which is all you need to name the class of any code, even one you have not memorised.
- Know the classic pairs: 401 means "who are you?" (not authenticated) while 403 means "I know you, but you may not" (not authorised).
Example 2 · A raw HTTP request and response
request = "\r\n".join([ "GET /results?roll=21 HTTP/1.1", "Host: exam.college.in", "Accept: text/html", "Cookie: session=abc123", "", "",])response = "\r\n".join([ "HTTP/1.1 200 OK", "Content-Type: text/html; charset=UTF-8", "Content-Length: 24", "", "<h1>Roll 21: 87/100</h1>",])
print(request.replace("\r\n", "\n"), end="")print("---")print(response.replace("\r\n", "\n"))status_line = response.split("\r\n")[0]print("---\nStatus code:", status_line.split()[1])GET /results?roll=21 HTTP/1.1 Host: exam.college.in Accept: text/html Cookie: session=abc123 --- HTTP/1.1 200 OK Content-Type: text/html; charset=UTF-8 Content-Length: 24 <h1>Roll 21: 87/100</h1> --- Status code: 200
What this code does
- HTTP/1.1 is plain text: a request line, headers, a blank line, then an optional body. Lines end with CR LF (
\r\n); the program swaps them for\nonly to print neatly. - Over plain HTTP anyone on the network path can read this text, including the cookie. HTTPS sends exactly the same text, but inside TLS encryption.
HTTP is stateless: each request stands alone, so logins use cookies or tokens to carry state. The method says what the client wants, and the status code is a three-digit number whose first digit gives the class of the answer.
Methods and codes:
- GET reads, POST creates, PUT replaces, PATCH updates part, DELETE removes. GET, PUT and DELETE are idempotent (repeating them has the same effect); POST is not.
- 1xx info, 2xx success (200 OK, 201 Created, 204 No Content), 3xx redirect (301 Moved Permanently, 302 Found, 304 Not Modified).
- 4xx client error: 400 Bad Request, 401 Unauthorized (not logged in), 403 Forbidden (no permission), 404 Not Found, 429 Too Many Requests.
- 5xx server error: 500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable, 504 Gateway Timeout.
HTTPS and TLS: certificates and encryption
HTTPS is HTTP sent inside an encrypted TLS connection. TLS gives confidentiality, integrity and authentication, and the authentication comes from a certificate signed by a certificate authority that the browser trusts.
The example checks the three things a browser verifies in a certificate: the name matches the URL, the dates are valid and a trusted authority signed it.
Example 3 · What a browser checks in a certificate
from datetime import date
TRUSTED_CAS = {"Let's Encrypt", "DigiCert", "GlobalSign"}
def check(url_host, domain, issuer, valid_until, today): if domain != url_host: return f"BLOCK: name mismatch ({domain})" if today > valid_until: return f"BLOCK: expired on {valid_until}" if issuer not in TRUSTED_CAS: return f"BLOCK: untrusted issuer {issuer}" return "OK: padlock shown"
today = date(2026, 10, 16)certs = [ ("netbanking.mybank.in", "DigiCert", date(2027, 3, 1)), ("mybank-login.xyz", "Let's Encrypt", date(2027, 1, 1)), ("netbanking.mybank.in", "DigiCert", date(2026, 9, 30)), ("netbanking.mybank.in", "Cafe Wi-Fi Proxy", date(2027, 1, 1)),]for domain, issuer, valid_until in certs: print(check("netbanking.mybank.in", domain, issuer, valid_until, today))OK: padlock shown BLOCK: name mismatch (mybank-login.xyz) BLOCK: expired on 2026-09-30 BLOCK: untrusted issuer Cafe Wi-Fi Proxy
What this code does
- A simplified model of three real checks: the name must match the URL, the date must be inside the validity period and the chain must lead to a trusted CA. Real browsers verify cryptographic signatures, not just the issuer name.
- The last case is what a man-in-the-middle looks like: a proxy shows its own certificate, which no trusted CA signed, so the browser warns the user.
TLS (Transport Layer Security; its old name was SSL) protects you in three ways: confidentiality (others on the Wi-Fi cannot read the data), integrity (data cannot be changed on the way without detection) and authentication (you are really talking to the bank). A certificate binds the domain name to the server's public key and is signed by a certificate authority (CA). In the handshake, asymmetric cryptography (a public and private key pair) verifies the server and agrees on a shared secret. The bulk data then uses fast symmetric encryption with that shared key.
Good to know:
- The browser checks: the name matches the URL, the certificate has not expired, and a trusted CA signed it.
- The padlock means the connection is encrypted and the name was verified, not that the site is honest.
- TLS 1.3 needs one round trip for a new handshake; TLS 1.2 needs two. Old SSL versions are insecure and disabled.
Order of execution
Order the TLS handshake
A browser opens https://bank.example.com. Put the steps in order.
Common ports: 20/21, 22, 25, 53, 80, 443, 3306
A port is a 16-bit number (0 to 65535) that identifies a service on a host. Ports 0 to 1023 are well-known ports for standard services; the client side uses a random high ephemeral port such as 51000.
The example looks up well-known ports in a map, the quick-fire list that interviewers use.
Example 4 · Well-known ports lookup
ports = { 21: "FTP control", 20: "FTP data", 22: "SSH / SFTP", 25: "SMTP", 53: "DNS", 80: "HTTP", 110: "POP3", 143: "IMAP", 443: "HTTPS", 3306: "MySQL",}for port in sorted(ports): print(f"{port:>5} {ports[port]}")
asked = 8080print(asked, "->", ports.get(asked, "not well-known (common dev server port)"))print("Well-known range: 0-1023, max port:", 2 ** 16 - 1)20 FTP data 21 FTP control 22 SSH / SFTP 25 SMTP 53 DNS 80 HTTP 110 POP3 143 IMAP 443 HTTPS 3306 MySQL 8080 -> not well-known (common dev server port) Well-known range: 0-1023, max port: 65535
What this code does
- A
TreeMapsorts the ports by number, which is a handy order for revision. Learn the pairs as "22 SSH", "443 HTTPS", "3306 MySQL". - 8080 is not a well-known port, but it is the default for Tomcat and FastAPI. Ports are 16-bit, so 65535 is the largest.
Interviewers often fire these as rapid questions, so learn them as pairs of number and name.
Ports to memorise:
- 20/21 FTP (data/control), 22 SSH (and SFTP), 23 Telnet, 25 SMTP, 53 DNS.
- 67/68 DHCP, 80 HTTP, 110 POP3, 143 IMAP, 443 HTTPS.
- 587 SMTP submission, 993 IMAPS, 3306 MySQL, 5432 PostgreSQL, 3389 RDP.
- Dev defaults: 8080 for Tomcat and FastAPI, 3000 for many Node and React dev servers, 6379 Redis.
Find the bug
Find the wrong port
Each list has one wrong line. Tap it, then check the fix.
A candidate lists common ports.
Round 1 of 2FTP, SMTP, SSH and other application protocols
An application protocol is the set of rules one kind of app uses to talk over the network, such as SSH for a remote terminal, SMTP for sending mail and FTP for files. Each usually has its own well-known port.
Each application protocol solves one job. FTP transfers files with two connections: control on port 21 and data on port 20 or a random port; it sends passwords in plain text, so SFTP (over SSH) or FTPS is used instead. SSH gives an encrypted remote terminal on port 22 and replaced the plain-text Telnet.
For email, SMTP sends and relays mail (25 between servers, 587 from your mail app), while POP3 downloads mail and usually removes it from the server, and IMAP keeps mail on the server and syncs folders across devices.
- Plain-text and outdated: Telnet, FTP, HTTP. Encrypted replacements: SSH, SFTP/FTPS, HTTPS.
- Push vs pull: SMTP pushes mail; POP3 and IMAP let the client pull it.
- Other names to know: DHCP (addresses), DNS (names), SNMP (device monitoring, UDP 161), NTP (time sync, UDP 123).
HTTP/1.1 vs HTTP/2 at a glance
Multiplexing means sending many requests and responses at the same time over one connection. HTTP/2 does it with binary frames; HTTP/1.1 handles one request at a time per connection.
The example counts the rounds needed to load ten files on HTTP/1.1 and on HTTP/2.
Example 5 · Requests on HTTP/1.1 vs HTTP/2
import math
def round_trips_http1(files, connections): return math.ceil(files / connections)
files, rtt_ms = 30, 40h1 = round_trips_http1(files, 6)h2 = 1print(f"Files to fetch: {files}, round trip: {rtt_ms} ms")print(f"HTTP/1.1, 6 connections: {h1} request rounds -> about {h1 * rtt_ms} ms")print(f"HTTP/2, 1 multiplexed connection: {h2} request round -> about {h2 * rtt_ms} ms")print("Handshakes: HTTP/1.1 opens 6 connections, HTTP/2 opens 1")Files to fetch: 30, round trip: 40 ms HTTP/1.1, 6 connections: 5 request rounds -> about 200 ms HTTP/2, 1 multiplexed connection: 1 request round -> about 40 ms Handshakes: HTTP/1.1 opens 6 connections, HTTP/2 opens 1
What this code does
- With HTTP/1.1 each connection handles one request at a time, so 30 files over 6 connections need 5 rounds. HTTP/2 sends all 30 at once on one connection.
- This is a simplified model: it ignores download time, bandwidth and server speed. It shows why multiplexing and fewer handshakes make pages with many files load faster.
HTTP/1.1 sends text messages, and browsers open about six connections per site to fetch files in parallel. It added keep-alive (reusing a connection) and the required Host header.
HTTP/2 keeps the same methods, headers and status codes but changes how they travel: binary frames, multiplexing and header compression (HPACK). HTTP/3 runs the same ideas over QUIC on UDP, avoiding TCP head-of-line blocking.
Next step
Check your understanding
12 quick questions