teaching_web_development

Resources on HTTP

HTTP — a practical chapter for PHP & web programming

This chapter explains the Hypertext Transfer Protocol (HTTP) at a level suitable for undergraduate web programming students who are using PHP. It mixes conceptual material with hands-on PHP examples and practical debugging tips.

Coursera HTTP: A video lecture on HTTP from the associated Coursera course.


1. What is HTTP?

HTTP is an application-level protocol for exchanging messages between clients (usually browsers or API clients) and servers (web servers + application code). It is request → response: a client sends a request and the server returns a response.

Key ideas:


2. Anatomy of an HTTP request and response

Raw HTTP request (example)

GET /index.php?q=php-http HTTP/1.1
Host: example.com
User-Agent: curl/8.0
Accept: text/html
Cookie: session=abcd1234

Raw HTTP response (example)

HTTP/1.1 200 OK
Date: Tue, 16 Dec 2025 12:00:00 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 142

<!doctype html>
<html><body><h1>Hello</h1></body></html>

Sections:


3. Important HTTP methods and semantics

Idempotent: same request repeated yields same result (e.g., PUT, GET).


4. Common response status codes (quick reference)

Use the correct code to make APIs predictable for clients.


5. Headers you meet often (request & response)


6. Request & response lifecycle (high level)

  1. Client resolves domain → DNS → IP.
  2. TCP (and TLS if HTTPS) handshake.
  3. Client sends HTTP request.
  4. Server (webserver or reverse proxy) routes request to application (PHP-FPM, CGI, built-in server).
  5. Application processes request and returns headers + body.
  6. Connection closed or re-used (keep-alive).
  7. Client processes response (render, cache, call next API).

URL (Uniform Resource Locator) components

Here is a diagram illustrating the components of a URL:

   +--------+    +------------------+    +------+    +------------------+
   | Scheme | -> |      Host        | -> | Port | -> |      Path        |
   +--------+    +------------------+    +------+    +------------------+
       |               |                    |                |
     http://       www.example.com         :80          /index.php?q=test

Port

In web programming, a port is a number that identifies which service or application on a computer should receive network traffic.

Think of a computer as a large building with many doors:

So when data arrives over the internet, the port tells the computer which program should handle it.

A port is a logical endpoint used by the operating system to route incoming and outgoing network data to the correct application.

A single machine can run many network services at the same time:

Ports allow all of these to coexist on one IP address without confusion.

Port Purpose
80 HTTP (standard web pages)
443 HTTPS (secure web pages)
3000 Common for development servers (Node.js)
3306 MySQL database
5432 PostgreSQL database

Ports appear after the hostname, separated by a colon:

http://localhost:3000
https://example.com:443

If no port is specified, the browser assumes the default:

A port tells your computer which program should receive the network request, just like a door number tells you which room to enter.

7. Testing & debugging tools

Examples:

# simple GET
curl -i http://localhost:8000/index.php?q=test

# POST JSON
curl -i -X POST http://localhost:8000/api.php \
  -H "Content-Type: application/json" \
  -d '{"name":"Alice"}'

8. PHP server basics & handling requests

Start built-in server (dev)

# from your project directory
php -S localhost:8000

Reading GET and POST

// GET parameters
$q = $_GET['q'] ?? null;

// POST form-encoded
$name = $_POST['name'] ?? null;

// Raw body (for JSON APIs)
$raw = file_get_contents('php://input');
$data = json_decode($raw, true);

Sending headers and status codes

// set a status code
http_response_code(201);

// set custom header
header('Content-Type: application/json');

// send JSON response
echo json_encode(['id' => 123, 'name' => 'Alice']);

Redirect

header('Location: /login.php');
http_response_code(302);
exit;
setcookie('session', $sessionId, [
  'expires' => time() + 3600,
  'path' => '/',
  'httponly' => true,
  'secure' => true,       // only over HTTPS
  'samesite' => 'Lax',
]);

9. Building a tiny REST endpoint in PHP

api.php

<?php
// simple router
$method = $_SERVER['REQUEST_METHOD'];
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

if ($path === '/api/notes' && $method === 'GET') {
    header('Content-Type: application/json');
    echo json_encode(['notes' => [['id'=>1,'text'=>'Intro to HTTP']]]);
    exit;
}

if ($path === '/api/notes' && $method === 'POST') {
    $raw = file_get_contents('php://input');
    $body = json_decode($raw, true);
    if (!isset($body['text'])) {
        http_response_code(400);
        echo json_encode(['error' => 'text required']);
        exit;
    }
    // pretend to create note...
    http_response_code(201);
    header('Content-Type: application/json');
    echo json_encode(['id' => 2, 'text' => $body['text']]);
    exit;
}

http_response_code(404);
echo "Not found";

Test with curl:

curl -i http://localhost:8000/api/notes
curl -i -X POST http://localhost:8000/api/notes \
  -H "Content-Type: application/json" \
  -d '{"text":"Learn HTTP"}'

10. Content negotiation & APIs

Clients declare Accept; servers choose response format. For simple APIs, support JSON (application/json) only and return 415 Unsupported Media Type if Content-Type is wrong.

Example content-type check:

if ($_SERVER['CONTENT_TYPE'] !== 'application/json') {
    http_response_code(415);
    echo json_encode(['error' => 'Expected application/json']);
    exit;
}

11. Caching basics

Example:

header('Cache-Control: public, max-age=3600');

12. Security basics for HTTP

Always use HTTPS in production

Cookies

CORS (Cross-Origin Resource Sharing)

header('Access-Control-Allow-Origin: https://your-frontend.example');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');

Handle OPTIONS preflight by returning allowed headers and methods with 204 No Content.

CSRF (Cross-Site Request Forgery)

Input validation & escaping


13. File uploads (multipart/form-data)

HTML form:

<form method="post" enctype="multipart/form-data" action="/upload.php">
  <input type="file" name="avatar">
  <button>Upload</button>
</form>

PHP handling:

if (!empty($_FILES['avatar']) && $_FILES['avatar']['error'] === UPLOAD_ERR_OK) {
    $tmp = $_FILES['avatar']['tmp_name'];
    $name = basename($_FILES['avatar']['name']);
    $dest = __DIR__ . '/uploads/' . $name;
    move_uploaded_file($tmp, $dest);
    echo "Saved";
} else {
    echo "Upload failed";
}

Security: validate MIME type and file extensions, store outside web root or with randomized names, limit size.


14. Advanced topics (brief)


15. Common mistakes & pitfalls


16. Exercises (quick, with suggested answers)

Exercise 1 — GET vs POST

Q: Why should form submissions that change server state use POST instead of GET? A: GET is intended for safe retrieval and can be cached/bookmarked/appears in logs/URL. POST signals non-idempotent change and hides payload from URL.

Exercise 2 — Implement JSON API

Task: Write a PHP endpoint /api/echo that accepts JSON {"message":"..."} and returns {"echo":"..."} with status 200. Suggested answer (skeleton):

$raw = file_get_contents('php://input');
$data = json_decode($raw, true);
if (!isset($data['message'])) {
  http_response_code(400);
  echo json_encode(['error'=>'message required']);
  exit;
}
header('Content-Type: application/json');
echo json_encode(['echo' => $data['message']]);

Exercise 3 — CORS preflight

Q: What response should the server send to an OPTIONS preflight request? A: Return 204 No Content (or 200) with Access-Control-Allow-Origin, Access-Control-Allow-Methods, and Access-Control-Allow-Headers including whatever the client requested.


17. Further reading & resources

Next: GET and POST methods