HTTP リクエストを手で書く
한국어 원문으로 표시합니다.
이 실습은 VM 에서 돕니다
python3 -m http.server 로 작은 웹 서버를 띄우고, 브라우저 없이 nc 로
요청을 직접 타이핑합니다. HTTP 는 텍스트라서 그것이 됩니다.
목표
요청 줄·헤더·빈 줄의 구조를 손으로 만들고, 200·301·404·501 응답을 직접
받아 보고, curl -v 가 보여 주는 것과 대조합니다.
왜 중요한가
HTTP 는 TCP 위의 텍스트입니다. 요청 한 줄, 헤더 몇 줄, 빈 줄 하나 — 그게
전부입니다. 이 구조를 손으로 만들어 본 사람은 프록시가 헤더를 바꿔치기할 때,
Host 가 틀려 엉뚱한 사이트가 나올 때, 리다이렉트가 돌 때 무엇을 봐야 할지
압니다. curl -v 의 > 와 < 를 읽을 줄 아는 것이 API 디버깅의 절반입니다.
단계
/root/http/www/index.html과/root/http/www/docs/guide.txt를 만들고/root/http/www를127.0.0.1:8080에서 서비스하는python3 -m http.server를 띄우세요(로그는/root/http/server.log로).nc로GET / HTTP/1.1요청을 직접 써서 보내고 응답 전체를/root/http/get.txt에 저장하세요.- 없는 경로
/missing을 요청해 404 응답을/root/http/notfound.txt에 저장하세요. HEAD /요청의 응답을/root/http/head.txt에 저장하세요. 헤더는 있고 본문은 없어야 합니다.- 끝에 슬래시가 없는
/docs를 요청해 301 과Location헤더가 담긴 응답을/root/http/redirect.txt에 저장하세요. curl -v로/docs/guide.txt를 받아 요청·응답 헤더가 모두 담긴 출력을/root/http/curl.txt에 저장하세요.curl -o /dev/null -w '%{http_code}'로/·/docs·/nope의 상태 코드를/root/http/codes.txt에경로=코드세 줄로 저장하세요./root/http/report.md에status_ok=·status_redirect=·status_missing=세 줄과 함께 요청의 세 부분(요청 줄·헤더·빈 줄)이 각각 무엇인지 적으세요.
참고
- 서버:
setsid python3 -m http.server 8080 --bind 127.0.0.1 --directory /root/http/www > /root/http/server.log 2>&1 < /dev/null &. - 요청 쓰기:
printf 'GET / HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n' | nc -q 1 127.0.0.1 8080. 줄 끝은\r\n, 헤더 뒤 빈 줄이 요청의 끝입니다. curl -v는>로 보낸 것,<로 받은 것을 표시합니다.- 흔한 실수: 마지막 빈 줄을 빼먹는 것. 서버는 요청이 끝나기를 계속 기다립니다.
작은 사이트
/root/http/www/index.html 과 /root/http/www/docs/guide.txt 를 만들고 /root/http/www 를 127.0.0.1:8080 에서 서비스하는 python3 -m http.server 를 띄우세요(로그는 /root/http/server.log 로).
index.html 에는 <h1> 태그 한 줄이면 됩니다. 서버는 --directory /root/http/www --bind 127.0.0.1 8080, 로그를 /root/http/server.log 로 보내세요. ss -ltn 에 8080 이 보여야 합니다.
GET 을 손으로
nc 로 GET / HTTP/1.1 요청을 직접 써서 보내고 응답 전체를 /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. 응답은 상태 줄, 헤더들, 빈 줄, 본문 순입니다. 200 OK 와 Content-type 과 <h1> 이 보여야 합니다.
없는 것을 달라고 하면
없는 경로 /missing 을 요청해 404 응답을 /root/http/notfound.txt 에 저장하세요.
2단계와 같은 요청에서 경로만 /missing 으로. 상태 줄이 404 여야 합니다. 서버는 살아 있고 자원만 없다는 뜻입니다 — TCP 는 성공했습니다.
HEAD
HEAD / 요청의 응답을 /root/http/head.txt 에 저장하세요. 헤더는 있고 본문은 없어야 합니다.
메서드만 HEAD 로 바꾸세요. Content-Length 는 그대로 오지만 본문은 안 옵니다. 큰 파일의 크기만 알고 싶을 때, 헬스 체크에 씁니다.
301 과 Location
끝에 슬래시가 없는 /docs 를 요청해 301 과 Location 헤더가 담긴 응답을 /root/http/redirect.txt 에 저장하세요.
경로 /docs(슬래시 없음). 디렉터리라서 서버가 301 과 Location: /docs/ 로 '저쪽으로 가라' 고 답합니다. 브라우저와 curl -L 은 이것을 따라갑니다.
curl -v 로 읽는다
curl -v 로 /docs/guide.txt 를 받아 요청·응답 헤더가 모두 담긴 출력을 /root/http/curl.txt 에 저장하세요.
curl -sv http://127.0.0.1:8080/docs/guide.txt > /root/http/curl.txt 2>&1. -v 의 출력은 표준 오류이니 2>&1. > GET /docs/guide.txt 와 < HTTP/1.0 200 OK, < Content-type: text/plain 이 보여야 합니다.
상태 코드만
curl -o /dev/null -w '%{http_code}' 로 /·/docs·/nope 의 상태 코드를 /root/http/codes.txt 에 경로=코드 세 줄로 저장하세요.
curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8080/docs 가 301 을 냅니다(-L 을 안 붙였으니 따라가지 않습니다). 세 줄: /=200, /docs=301, /nope=404.
무엇을 배웠나
/root/http/report.md 에 status_ok=·status_redirect=·status_missing= 세 줄과 함께 요청의 세 부분(요청 줄·헤더·빈 줄)이 각각 무엇인지 적으세요.
세 값은 7단계의 코드입니다. 본문에는 Host 헤더가 왜 필요한지와 빈 줄이 무슨 뜻인지가 들어가야 합니다. 서버 로그(/root/http/server.log)에 지금까지의 요청이 다 남아 있는지도 보세요.