Network Fundamentals — Hands-on in a Linux VM
Write HTTP Requests by Hand
This lab runs on a VM
You start a small web server with python3 -m http.server and, without a browser, type the requests
yourself with nc. That works because HTTP is text.
Goal
Build the structure of the request line, headers, and blank line by hand, receive 200, 301, 404, and 501
responses yourself, and compare them with what curl -v shows.
Why it matters
HTTP is text on top of TCP. One request line, a few header lines, one blank line — that is
all. Someone who has built this structure by hand knows what to look at when a proxy swaps out headers,
when a wrong Host brings up a different site, or when a redirect loops. Being able to read the > and < of curl -v
is half of API debugging.
Steps
- Create
/root/http/www/index.htmland/root/http/www/docs/guide.txt, and start apython3 -m http.serverthat serves/root/http/wwwon127.0.0.1:8080(send the log to/root/http/server.log). - Write and send a
GET / HTTP/1.1request yourself withnc, and save the whole response to/root/http/get.txt. - Request the nonexistent path
/missingand save the 404 response to/root/http/notfound.txt. - Save the response to a
HEAD /request to/root/http/head.txt. It must have headers and no body. - Request
/docswithout a trailing slash and save the response containing the 301 and theLocationheader to/root/http/redirect.txt. - Fetch
/docs/guide.txtwithcurl -vand save the output, which contains both the request and response headers, to/root/http/curl.txt. - With
curl -o /dev/null -w '%{http_code}', save the status codes of/,/docs, and/nopeto/root/http/codes.txtas three lines in the form경로=코드(path=code). - In
/root/http/report.md, write three lines,status_ok=·status_redirect=·status_missing=, together with what each of the three parts of a request (request line, headers, blank line) is.
Notes
- Server:
setsid python3 -m http.server 8080 --bind 127.0.0.1 --directory /root/http/www > /root/http/server.log 2>&1 < /dev/null &. - Writing the request:
printf 'GET / HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n' | nc -q 1 127.0.0.1 8080. Lines end with\r\n, and the blank line after the headers is the end of the request. curl -vmarks what was sent with>and what was received with<.- A common mistake: leaving out the last blank line. The server keeps waiting for the request to end.
A small site
Create /root/http/www/index.html and /root/http/www/docs/guide.txt, and start a python3 -m http.server that serves /root/http/www on 127.0.0.1:8080 (send the log to /root/http/server.log).
index.html needs only one line with an <h1> tag. For the server, use --directory /root/http/www --bind 127.0.0.1 8080 and send the log to /root/http/server.log. ss -ltn must show 8080.
GET by hand
Write and send a GET / HTTP/1.1 request yourself with nc, and save the whole response to /root/http/get.txt.
printf 'GET / HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n' | nc -q 1 127.0.0.1 8080 > /root/http/get.txt. The response is, in order, the status line, headers, a blank line, and the body. 200 OK, Content-type, and <h1> must be visible.
Asking for something that isn't there
Request the nonexistent path /missing and save the 404 response to /root/http/notfound.txt.
Use the same request as in step 2 but with the path /missing. The status line must be 404. It means the server is alive and only the resource is missing — TCP succeeded.
HEAD
Save the response to a HEAD / request to /root/http/head.txt. It must have headers and no body.
Change only the method to HEAD. Content-Length still arrives, but the body does not. You use it when you want to know only the size of a large file, and for health checks.
301 and Location
Request /docs without a trailing slash and save the response containing the 301 and the Location header to /root/http/redirect.txt.
The path is /docs (no slash). Because it is a directory, the server answers with 301 and Location: /docs/, saying "go over there". Browsers and curl -L follow this.
Read it with curl -v
Fetch /docs/guide.txt with curl -v and save the output, which contains both the request and response headers, to /root/http/curl.txt.
curl -sv http://127.0.0.1:8080/docs/guide.txt > /root/http/curl.txt 2>&1. The output of -v goes to standard error, hence 2>&1. > GET /docs/guide.txt, < HTTP/1.0 200 OK, and < Content-type: text/plain must be visible.
Status codes only
With curl -o /dev/null -w '%{http_code}', save the status codes of /, /docs, and /nope to /root/http/codes.txt as three lines in the form 경로=코드 (path=code).
curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8080/docs gives 301 (you did not add -L, so it does not follow). The three lines: /=200, /docs=301, /nope=404.
What you learned
In /root/http/report.md, write three lines, status_ok=·status_redirect=·status_missing=, together with what each of the three parts of a request (request line, headers, blank line) is.
The three values are the codes from step 7. The body must include why the Host header is needed and what the blank line means. Also check that the server log (/root/http/server.log) has kept all the requests so far.