179 lines
5.4 KiB
TypeScript
179 lines
5.4 KiB
TypeScript
import express from "express"
|
|
import { status } from "http-status"
|
|
|
|
const app = express()
|
|
|
|
app.use(express.urlencoded({ extended: true }))
|
|
app.use(express.json())
|
|
|
|
// Log every incoming request to the terminal
|
|
app.use((req, res, next) => {
|
|
console.log("\n" + "=".repeat(50))
|
|
console.log(`${req.method} ${req.url}`)
|
|
console.log("\n-- Headers --")
|
|
console.log(req.headers)
|
|
if (Object.keys(req.body || {}).length > 0) {
|
|
console.log("\n-- Body --")
|
|
console.log(req.body)
|
|
}
|
|
if (Object.keys(req.cookies || {}).length > 0) {
|
|
console.log("\n-- Cookies --")
|
|
console.log(req.cookies)
|
|
}
|
|
console.log("=".repeat(50))
|
|
next()
|
|
})
|
|
|
|
// Serve static files from the "public" directory (for CSS, images, etc.)
|
|
app.use(express.static("public"))
|
|
|
|
// Simple GET: echoes request info back as HTML
|
|
app.get("/", (req, res) => {
|
|
res.send(`
|
|
<link rel="stylesheet" href="/style.css" />
|
|
<h1>HTTP Echo Server</h1>
|
|
<p>Check your terminal — the server printed everything it received.</p>
|
|
<h2>Try these:</h2>
|
|
<ul>
|
|
<li><a href="/form">POST form demo</a></li>
|
|
<li><a href="/set-cookie">Set a cookie</a></li>
|
|
<li><a href="/show-cookies">Show cookies the server received</a></li>
|
|
<li><a href="/json">JSON response</a></li>
|
|
<li><a href="/delay">Delayed response</a></li>
|
|
<li><a href="/status">HTTP status codes</a></li>
|
|
</ul>
|
|
`)
|
|
})
|
|
|
|
// Form page: allows to submit a POST and see the body
|
|
app.get("/form", (req, res) => {
|
|
res.send(`
|
|
<link rel="stylesheet" href="/style.css" />
|
|
<h1>Login Form</h1>
|
|
<form method="POST" action="/login">
|
|
<label>Username: <input name="username" type="text" /></label>
|
|
<label>Password: <input name="password" type="password" /></label>
|
|
<button type="submit">Login</button>
|
|
</form>
|
|
<p>Submit this and watch the terminal. Also check DevTools → Network tab.</p>
|
|
`)
|
|
})
|
|
|
|
// Receives the POST: echoes the body back
|
|
app.post("/login", (req, res) => {
|
|
const { username, password } = req.body
|
|
res.send(`
|
|
<link rel="stylesheet" href="/style.css" />
|
|
<h1>Server received your POST</h1>
|
|
<p><strong>Username:</strong> ${username}</p>
|
|
<p><strong>Password:</strong> ${password}</p>
|
|
<p style="color:red">⚠️ Over plain HTTP, anyone between you and the server could read this.</p>
|
|
<a href="/form">Back</a>
|
|
`)
|
|
})
|
|
|
|
// Sets a cookie: shows Set-Cookie header in DevTools
|
|
app.get("/set-cookie", (req, res) => {
|
|
res.cookie("session", "abc123xyz", {
|
|
httpOnly: true,
|
|
maxAge: 60 * 60 * 1000, // 1 hour
|
|
})
|
|
res.send(`
|
|
<link rel="stylesheet" href="/style.css" />
|
|
<h1>Cookie Set</h1>
|
|
<p>The server sent a <code>Set-Cookie</code> header. Check DevTools → Network → Response Headers.</p>
|
|
<p>Now visit <a href="/show-cookies">show-cookies</a> — the browser will automatically send it back.</p>
|
|
`)
|
|
})
|
|
|
|
// Shows what cookies the server received
|
|
app.get("/show-cookies", (req, res) => {
|
|
const cookieHeader = req.headers["cookie"] || "none"
|
|
res.send(`
|
|
<link rel="stylesheet" href="/style.css" />
|
|
<h1>Cookies the server received</h1>
|
|
<p><code>Cookie: ${cookieHeader}</code></p>
|
|
<p>The browser sent this automatically — you didn't write any JavaScript for that.</p>
|
|
`)
|
|
})
|
|
|
|
// Returns JSON: shows Content-Type in action
|
|
app.get("/json", (req, res) => {
|
|
res.json({
|
|
message: "This is a JSON response",
|
|
method: req.method,
|
|
url: req.url,
|
|
headers: req.headers,
|
|
})
|
|
})
|
|
|
|
// Delayed response: simulates a slow server
|
|
app.get("/delay", (req, res) => {
|
|
setTimeout(() => {
|
|
res.send(`
|
|
<link rel="stylesheet" href="/style.css" />
|
|
<h1>Delayed Response</h1><p>This response was delayed by 5 seconds.</p>
|
|
`)
|
|
}, 5000)
|
|
})
|
|
|
|
// Show all the different HTTP status codes
|
|
app.get("/status", (req, res) => {
|
|
res.send(`
|
|
<link rel="stylesheet" href="/style.css" />
|
|
<h1>HTTP Status Codes</h1>
|
|
<h2>2xx Success</h2>
|
|
<ul>
|
|
${[200, 201, 202, 203, 204, 205, 206, 207, 208, 226]
|
|
.map(
|
|
(code) =>
|
|
`<li><a href="/status/${code}">${code} ${status[code as keyof typeof status]}</a></li>`,
|
|
)
|
|
.join("")}
|
|
</ul>
|
|
<h2>3xx Redirection</h2>
|
|
<ul>
|
|
${[300, 301, 302, 303, 304, 307, 308]
|
|
.map(
|
|
(code) =>
|
|
`<li><a href="/status/${code}">${code} ${status[code as keyof typeof status]}</a></li>`,
|
|
)
|
|
.join("")}
|
|
</ul>
|
|
<h2>4xx Client Errors</h2>
|
|
<ul>
|
|
${[
|
|
400, 401, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414,
|
|
415, 416, 417, 418, 421, 422, 423, 424, 425, 426, 428, 429, 431, 451,
|
|
]
|
|
.map(
|
|
(code) =>
|
|
`<li><a href="/status/${code}">${code} ${status[code as keyof typeof status]}</a></li>`,
|
|
)
|
|
.join("")}
|
|
</ul>
|
|
<h2>5xx Server Errors</h2>
|
|
<ul>
|
|
${[500, 501, 502, 503, 504, 505, 506, 507, 508, 510, 511]
|
|
.map(
|
|
(code) =>
|
|
`<li><a href="/status/${code}">${code} ${status[code as keyof typeof status]}</a></li>`,
|
|
)
|
|
.join("")}
|
|
</ul>
|
|
`)
|
|
})
|
|
|
|
// Demonstrates different status codes
|
|
app.get("/status/:code", (req, res) => {
|
|
const code = parseInt(req.params.code)
|
|
res.status(code).send(`
|
|
<link rel="stylesheet" href="/style.css" />
|
|
<h1>Status ${code}</h1><p>This response was sent with HTTP status ${code} (${status[code as keyof typeof status]}).</p>
|
|
`)
|
|
})
|
|
|
|
app.listen(3000, () => {
|
|
console.log("Echo server running on http://localhost:3000")
|
|
console.log("Watching for requests...\n")
|
|
})
|