Step 73. HTTP 완전 이해 — 웹의 대화 규칙

Step 73. HTTP 완전 이해 — 웹의 대화 규칙

Level 1 — 프로그래밍과 컴퓨터 내부 | 난이도 ★★★☆☆ | 예상 소요 시간 4시간

전제: Step 71~72를 마쳤다. 웹페이지의 구조(HTML)와 동작(JS)을 안다. 터미널(Git Bash 또는 PowerShell)에서 명령을 칠 수 있다.

  • 준비물: 브라우저, 터미널, curl(윈도우 10 이상은 기본 내장 — curl --version으로 확인), 파이썬(실습 서버용). 오늘의 실험 상대는 인터넷 어딘가가 아니라 여러분의 컴퓨터 안에 직접 띄우는 서버입니다.
  • 주의: 오늘 실습은 100% 안전합니다. 모든 통신은 127.0.0.1(내 컴퓨터를 가리키는 특별한 주소) 안에서만 일어나며, 외부 사이트에는 한 번도 접속하지 않습니다.

지난 두 챕터에서 우리는 페이지를 만들고 움직이게 했습니다. 그런데 그 페이지가 서버에서 우리 화면까지 어떻게 오는지는 아직 검은 상자입니다. 오늘 그 상자를 엽니다. 웹의 모든 통신은 단순한 규칙 하나로 돌아갑니다 — 클라이언트(손님)가 요청(request)을 내면 서버(주방)가 응답(response)을 돌려줍니다. 그리고 그 대화는 전부 사람이 읽을 수 있는 텍스트입니다. 오늘 우리는 그 대화를 엿보고, 직접 말을 걸고, 대답을 해석합니다.


1. 학습 목표

이 챕터를 끝내면 다음을 할 수 있습니다:

  • python -m http.server로 내 컴퓨터에 실습용 웹서버를 띄운다
  • 요청(메서드+경로+헤더+본문)과 응답(상태코드+헤더+본문)의 구조를 그릴 수 있다
  • curl -v로 통신의 날것을 읽고, >(요청)와 <(응답)를 구분한다
  • 상태코드 200/301/404/500의 의미와 그것이 왜 정보원인지 설명한다
  • GET과 POST의 차이를 "데이터가 실리는 위치"로 설명한다

2. 배경 지식 — 오늘의 도구와 개념

오늘의 도구 한눈에 보기

구분 내용
언어·환경 HTTP(웹 문서 전송 규약) — 브라우저와 서버가 대화하는 문법. 실습은 전부 localhost(127.0.0.1)
오늘의 도구 curl(터미널의 만능 통신 도구), python -m http.server(한 줄짜리 실습용 웹서버), 브라우저 개발자 도구 Network 탭
오늘의 명령 curl -v 주소, curl -I 주소, curl -A "..." 주소, curl -X POST -d "..." 주소
필요한 개념 요청/응답의 세 부분(첫 줄·헤더·본문), 메서드(GET/POST), 상태코드, 헤더(Host, User-Agent, Cookie)
오늘의 산출물 webroot/ 폴더의 실습 페이지들과, 통신 관찰 기록 노트

2-1. 요청의 해부학

브라우저가 서버에 보내는 요청은 세 부분으로 이뤄집니다.

GET /index.html HTTP/1.1
Host: 127.0.0.1:8001
User-Agent: curl/8.11.0
  • 첫 줄(요청 줄): 메서드 경로 버전 순서입니다. 메서드는 "무엇을 하고 싶은가" — GET(달라), POST(이 데이터를 처리해 줘) 등입니다. 경로는 "어느 페이지를", 버전은 "어느 문법으로 말하는가"입니다.
  • 헤더(header, 머리글)들: 둘째 줄부터 이어지는 이름: 값 목록입니다. 봉투 겉 표시들입니다. Host(어느 사이트인가), User-Agent(누가 보냈나), Cookie(신분증 쪽지) 등이 여기 들어갑니다.
  • 본문(body): POST처럼 데이터를 실어 보낼 때만 붙는 내용물입니다. GET은 보통 본문이 없습니다.

2-2. 응답의 해부학

서버의 대답도 같은 구조입니다.

HTTP/1.0 200 OK
Content-type: text/html
Content-Length: 270

<!DOCTYPE html>...
  • 첫 줄(상태 줄): 버전과 상태코드, 그리고 짧은 설명입니다.
  • 헤더들: Content-Type(내용물의 종류), Content-Length(길이) 등입니다.
  • 본문: 실제 웹페이지(HTML)나 데이터(JSON)입니다. 우리가 Step 71에서 만든 그 HTML이 바로 이 본문을 타고 오는 것입니다.

2-3. 상태코드 — 세 자리 숫자의 행간

상태코드는 서버의 한 마디 대답입니다. 백의 자리가 대강의 뜻을 정합니다.

코드 비유
200 성공 "여기 있습니다"
301/302 리다이렉트(이사) "그건 저쪽으로 이사갔어요"
403 금지 "들어올 수 없습니다"
404 없음 "그런 페이지는 없습니다"
500 서버 오류 "주방에서 사고가 났습니다"

보안 학습에서 이 숫자들은 정보원입니다. 403은 "뭔가 있기는 있는데 막았다"는 뜻이라 404와 구분되고, 숨겨진 페이지를 찾는 탐색의 단서가 됩니다. 500은 "서버가 내 입력 때문에 고장 났다"는 뜻이라 공격 실마리가 되기도 합니다.

2-4. GET과 POST — 엽서와 소포

두 메서드의 차이를 한 줄로 말하면 이렇습니다. GET은 데이터를 주소(URL)에 싣고, POST는 본문에 싣습니다.

  • GET: .../search?q=망치처럼 주소 뒤에 ?이름=값으로 붙습니다. 엽서처럼 지나가는 누구에게나 보이고, 브라우저 기록과 서버 기록 양쪽에 남습니다. 그래서 검색이나 조회에 씁니다.
  • POST: 데이터가 본문에 들어가 주소창에 보이지 않습니다. 소포처럼 포장되어 갑니다. 로그인, 글쓰기처럼 "서버에 변화를 일으키는" 요청에 씁니다.

오해 금지: POST가 암호화되는 것은 아닙니다. 주소창에 안 보일 뿐, 봉투를 뜯으면(가로채면) 내용이 그대로입니다. 진짜 보호는 HTTPS(암호화된 HTTP)가 담당합니다.


3. 따라 하기

3-1. 실습 서버 띄우기 — 내 컴퓨터가 서버가 된다

먼저 실험 상대를 만듭니다. 작업 폴더에 webroot라는 폴더를 만들고 그 안에 index.html을 저장합니다 (Step 71의 솜씨입니다).

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>실습 서버 홈</title>
</head>
<body>
  <h1>우리 집 연습 서버</h1>
  <p>이 페이지는 127.0.0.1에서만 살고 있습니다.</p>
</body>
</html>

그리고 터미널에서 그 폴더로 들어가 서버를 켭니다.

입력

cd webroot
python -m http.server 8001

출력 예시 (버전·환경에 따라 다를 수 있습니다):

Serving HTTP on :: port 8001 (http://[::]:8001/) ...

읽는 법: python -m http.server 8001은 "이 폴더를 8001번 출구로 내놓는 웹서버를 켜라"는 뜻입니다. 127.0.0.1은 "이 컴퓨터 자신"을 가리키는 특별 주소이고, 8001은 그 안의 출구 번호(포트)입니다. 이 창은 서버가 계속 일하느라 다른 명령을 받지 않습니다 — 새 터미널 창을 하나 더 열어 거기서 아래 실험을 하세요. 서버 끄기는 이 창에서 Ctrl+C입니다.

: 외부 사이트 상대로는 마음껏 실험할 수 없지만, 내 서버는 내 것입니다. 실패해도, 이상한 요청을 내도 전혀 문제없는 완벽한 연습장입니다.

3-2. curl -v — 대화의 날것 보기

이제 브라우저 없이 터미널에서 직접 요청을 보냅니다. curl은 "주소를 주면 대신 통신해 주는" 도구입니다.

입력 (새 터미널 창에서)

curl -v http://127.0.0.1:8001/index.html

출력 (2026-09-09 실측, 중간의 진행 표시 줄은 생략):

*   Trying 127.0.0.1:8001...
* Connected to 127.0.0.1 (127.0.0.1) port 8001
> GET /index.html HTTP/1.1
> Host: 127.0.0.1:8001
> User-Agent: curl/8.11.0
> Accept: */*
>
< HTTP/1.0 200 OK
< Server: SimpleHTTP/0.6 Python/3.12.14
< Date: Wed, 09 Sep 2026 04:34:10 GMT
< Content-type: text/html
< Content-Length: 270
<
<!DOCTYPE html>
<html>
... (이하 HTML 본문)

읽는 법: >로 시작하는 줄은 내가 보낸 것(요청), <로 시작하는 줄은 서버가 보낸 것(응답), *로 시작하는 줄은 접속 준비 과정(무시해도 됩니다)입니다. -v는 verbose(수다스럽게) 옵션으로, 이 봉투 내용을 전부 보여 달라는 뜻입니다. 응답의 Server: 헤더에 서버의 정체(SimpleHTTP/0.6 Python/3.12.14)가 스스로 적혀 있는 것도 보세요. 맨 아래에 헤더 없이 이어지는 것이 응답 본문, 즉 HTML 원문입니다.

: 브라우저가 화면에 그려 주지 않는 "날것의 대화"를 보는 훈련입니다. 화면이 아니라 이 텍스트가 웹의 진짜 모습입니다.

3-3. 상태코드 실험 — 있는 페이지와 없는 페이지

입력

curl -I http://127.0.0.1:8001/index.html
curl -I http://127.0.0.1:8001/no-such-page.html

출력 (2026-09-09 실측):

HTTP/1.0 200 OK
Server: SimpleHTTP/0.6 Python/3.12.14
Content-type: text/html
Content-Length: 270
HTTP/1.0 404 File not found
Server: SimpleHTTP/0.6 Python/3.12.14
Connection: close
Content-Type: text/html;charset=utf-8
Content-Length: 335

읽는 법: -I는 헤더만 받는(HEAD 요청) 옵션입니다. 본문 없이 봉투 겉면만 보고 싶을 때 씁니다. 있는 페이지에는 200, 없는 페이지에는 404가 돌아옵니다 — 이 서버의 404 설명 문구는 "File not found"입니다.

: 상태코드를 "화면의 에러 메시지"가 아니라 "기계가 읽는 신호"로 보는 훈련입니다. 숨은 경로를 찾는 도구(디렉터리 스캐너)가 일하는 원리가 바로 이 신호 읽기 — 후보 주소를 하나씩 찔러 보고 200과 404를 가려내는 것입니다.

3-4. 서버 측 로그 — 주소에 실린 것은 남는다

이번에는 GET으로 데이터를 실어 보내고, 서버 쪽에서 무엇이 보이는지 봅니다.

입력

curl "http://127.0.0.1:8001/index.html?name=admin&level=3"

그다음 서버가 돌고 있는 첫 번째 터미널 창을 보세요. 접속할 때마다 한 줄씩 기록이 쌓입니다 (2026-09-09 실측):

::ffff:127.0.0.1 - - [09/Sep/2026 13:34:23] "HEAD /no-such-page.html HTTP/1.1" 404 -
::ffff:127.0.0.1 - - [09/Sep/2026 13:38:38] "GET /index.html?name=admin&level=3 HTTP/1.1" 200 -

읽는 법: 각 줄은 "누가(IP) 언제 무슨 요청을 보냈고 상태코드가 뭐였나"입니다. 두 번째 줄을 보면, 주소에 실은 name=admin&level=3서버 기록에 통째로 남아 있습니다. 서버는 주소에 실린 데이터를 전부 읽고 기록할 수 있습니다.

: 그래서 비밀번호를 GET으로 내면 안 됩니다. 주소에 실린 데이터는 브라우저 방문 기록에도, 서버 로그에도, 중간 장비 기록에도 남습니다. "GET은 조회, POST는 변화"라는 관습 뒤에는 이런 보안적 이유가 있습니다.

3-5. POST를 보내 보기 — 이 서버는 모른다

입력

curl -X POST -d "id=admin&pw=1234" http://127.0.0.1:8001/echo

출력 (2026-09-09 실측, 본문 일부):

<h1>Error response</h1>
<p>Error code: 501</p>
<p>Message: Unsupported method ('POST').</p>

서버 로그에도 남습니다: code 501, message Unsupported method ('POST')

읽는 법: 501은 "그런 메서드는 모릅니다"라는 상태코드입니다. 이 단순 파일 서버는 GET과 HEAD만 이해하고, POST(데이터 받기)는 할 줄 모릅니다. 우리가 보낸 id=admin&pw=1234는 본문에 실려 가긴 했지만 읽어 주는 상대가 없었습니다.

: 메서드는 약속입니다. 클라이언트가 POST로 말을 걸어도 서버가 그 약속을 모르면 대화는 성립하지 않습니다. 로그인 폼이 실제로 작동하려면, POST 본문을 풀어서 처리해 주는 서버 프로그램이 필요합니다 — 그런 서버를 직접 만들어 대화하는 것은 requests를 배울 때의 첫 실습이 됩니다.

3-6. 헤더 변장 — 나는 누구인가

curl로 요청 헤더를 마음대로 바꿀 수 있습니다.

입력

curl -v -A "MyFirstBot/1.0" http://127.0.0.1:8001/index.html

출력 (2026-09-09 실측, 요청 부분만):

> GET /index.html HTTP/1.1
> Host: 127.0.0.1:8001
> User-Agent: MyFirstBot/1.0
> Accept: */*

읽는 법: -A 옵션으로 User-Agent를 바꿨더니, 요청 봉투의 "보낸 이" 칸이 그대로 바뀌었습니다. 서버는 우리가 누구인지 스스로 아는 것이 아니라, 우리가 헤더에 적어 보낸 말을 받아들일 뿐입니다.

: 헤더는 "클라이언트가 주장하는 정보"일 뿐 진실이 아닙니다 — 이것이 오늘의 핵심 교훈입니다. User-Agent를 보고 브라우저를 구분하는 서버, Referer를 보고 출처를 믿는 서버는 모두 속을 수 있습니다. 헤더를 검증 없이 믿지 않는 것이 보안 설계의 출발점입니다.

3-7. Network 탭 — 브라우저의 대화도 엿보기

마지막으로 브라우저의 대화를 봅니다.

입력: F12 → Network(네트워크) 탭을 연 채로 주소창에 http://127.0.0.1:8001/index.html 입력.

화면 예시: 탭 아래 목록에 index.html 한 줄이 찍힙니다. 그것을 클릭하면 Headers 세부 탭에 Request Headers(내가 보낸 헤더)와 Response Headers(서버가 보낸 헤더)가 나란히 보이고, Response 탭에는 돌아온 HTML 원문이 있습니다.

읽는 법: 목록의 한 줄이 요청-응답 한 쌍입니다. 브라우저가 보낸 User-Agent는 방금 우리가 curl로 흉내 낸 것과 같은 칸입니다 — 브라우저도 결국 같은 문법으로 말하는 하나의 클라이언트일 뿐입니다.

: "페이지가 보인다"는 현상이 요청-응답의 결과라는 것을 브라우저 안에서도 확인하는 마무리입니다. curl과 Network 탭, 이 두 개의 창이 앞으로의 모든 웹 분석에서 여러분의 눈이 됩니다.


4. 미션과 연습문제

미션 — HTTP 관찰 보고서

우리 집 실습 서버를 상대로 관찰 보고서를 작성하세요 (노트 파일 http_report.txt 권장).

  1. webroot에 두 번째 페이지 hello.html을 추가하고 서버를 켭니다
  2. curl -v로 index.html을 요청해, 요청의 > 줄 전부와 응답의 < 줄 전부를 베껴 적습니다
  3. curl -I로 있는 페이지(200)와 없는 페이지(404)를 한 번씩 유도해 상태 줄을 베껴 적습니다
  4. curl "http://127.0.0.1:8001/index.html?secret=abcd"를 보낸 뒤 서버 로그에서 그 줄을 찾아 베껴 적습니다
  5. -A 옵션으로 User-Agent를 바꿔 보내고, 바뀐 요청 줄을 베껴 적습니다
  6. 보고서 말미에 그림 하나: "브라우저 → [요청: 메서드+경로+헤더+본문] → 서버 → [응답: 상태코드+헤더+본문] → 브라우저"를 자기 말로 그립니다

연습문제

문제 1. 요청 메시지의 세 부분(첫 줄·헤더·본문)에 각각 무엇이 들어가는지 말해 보세요.

문제 2. GET과 POST의 차이를 "데이터가 실리는 위치"와 "기록에 남는 곳" 두 관점에서 설명해 보세요.

문제 3. 어떤 경로를 요청했더니 403이 돌아왔습니다. 404와 비교해 이 숫자가 주는 정보는 무엇이며, 왜 탐색의 단서가 되나요?

문제 4. POST로 내면 주소창에 데이터가 안 보이니 비밀번호가 안전하다 — 이 말의 어디가 틀렸는지 설명해 보세요.


5. 모범 답안과 완료 기준

미션 모범 답안

보고서에 담겨야 할 핵심 내용은 이렇습니다 (전부 2026-09-09 실측값과 같은 모양이어야 합니다).

  • 요청 > 줄: GET /index.html HTTP/1.1, Host: 127.0.0.1:8001, User-Agent: curl/..., Accept: */*
  • 응답 < 줄: HTTP/1.0 200 OK, Server: SimpleHTTP/0.6 Python/..., Content-type: text/html, Content-Length: ...
  • 404 실험의 상태 줄: HTTP/1.0 404 File not found
  • 서버 로그 줄: "GET /index.html?secret=abcd HTTP/1.1" 200 - — secret이 로그에 그대로 남은 것이 포인트
  • 변장 실험: 요청의 User-Agent 줄이 내가 정한 문자열로 바뀐 것
  • 그림: 요청과 응답의 세 부분(첫 줄/헤더/본문)이 화살표 위에 얹혀 있어야 합니다

검증하는 법: ① 베낀 기록 전부가 외부 사이트가 아니라 127.0.0.1을 향하고 있는가. ② secret=abcd가 서버 로그에 남은 것을 확인했는가. ③ 그림에 요청 4요소(메서드·경로·헤더·본문)와 응답 3요소(상태코드·헤더·본문)가 빠짐없이 있는가. 셋이 전부 ‘예’이면 완성입니다.

연습문제 해답

문제 1 해답. 첫 줄에는 메서드·경로·버전("무엇을 어디에 어떤 문법으로"), 헤더에는 이름: 값 형태의 부가 정보(Host, User-Agent, Cookie 등), 본문에는 POST 같은 요청이 실어 보내는 데이터가 들어갑니다. GET은 보통 본문이 비어 있습니다.

문제 2 해답. GET은 데이터를 주소(?이름=값)에 싣고 POST는 본문에 싣습니다. 그래서 GET 데이터는 브라우저 방문 기록과 서버 로그에 주소째로 남지만(3-4 실측), POST 데이터는 주소 기록에는 남지 않고 본문으로 이동합니다. 단, 둘 다 암호화와는 무관합니다.

문제 3 해답. 403은 "그 경로가 존재하지만 접근이 금지됐다"는 뜻이고, 404는 "존재하지 않는다"는 뜻입니다. 그래서 403은 "숨겨진 무언가가 있다"는 정보 자체가 되어, 보호된 자원의 존재를 알아내는 단서가 됩니다.

문제 4 해답. "안 보인다"와 "보호된다"를 혼동했습니다. POST 본문도 평문으로 전송되므로 중간에서 봉투를 뜯으면 내용이 그대로 읽힙니다. 안전은 전송 위치가 아니라 HTTPS(통신 구간 암호화)가 제공하는 것입니다.

완료 기준 체크리스트

  • [ ] python -m http.server로 실습 서버를 띄우고 끌 수 있다
  • [ ] 요청과 응답의 세 부분(첫 줄/헤더/본문)을 그릴 수 있다
  • [ ] curl -v 출력에서 요청(>)과 응답(<)을 구분해 읽을 수 있다
  • [ ] 상태코드 200/301/404/500의 뜻을 말할 수 있다
  • [ ] GET 데이터가 서버 로그에 남는 것을 확인했다
  • [ ] -A로 User-Agent를 바꿔 보낼 수 있다
  • [ ] 미션: HTTP 관찰 보고서를 완성했다

6. 흔한 실수와 해결

벽 1. 터미널이 명령을 안 받고 멍하니 있다

증상: python -m http.server 8001를 쳤더니 그 창이 다른 명령을 받지 않습니다.
원인: 고장이 아닙니다. 서버는 켜져 있는 동안 계속 일해야 해서 그 창을 점유합니다.
해결: 서버 창은 그대로 두고, 새 터미널 창을 열어 curl을 치세요. 서버 종료는 서버 창에서 Ctrl+C입니다.

벽 2. Address already in use가 뜬다

증상: 서버를 켤 때 OSError: [WinError 10048] ... 같은 메시지가 뜨며 죽습니다.
원인: 그 출구 번호(포트)를 이미 다른 프로그램(또는 꺼지지 않은 이전 서버)이 쓰고 있습니다.
해결: 포트 번호를 8002, 8010처럼 다른 번호로 바꾸세요. 포트는 대화방 번호일 뿐이라 아무 빈 번호나 쓰면 됩니다.

벽 3. curl -v 출력이 너무 길어서 무섭다

증상: 별표(*)와 꺾쇠가 잔뜩 떠서 읽기를 포기하고 싶습니다.
원인: -v는 접속 준비 과정까지 전부 보여 줍니다.
해결: ><로 시작하는 줄만 읽으면 됩니다. 별표 줄은 준비 과정이니 무시하세요. 이 구분이 오늘의 핵심 독해법입니다.

벽 4. POST를 보냈는데 501이 돌아온다

증상 (2026-09-09 실측): <p>Message: Unsupported method ('POST').</p>

원인: 상대 서버가 POST를 이해하지 못합니다. python -m http.server는 GET과 HEAD만 아는 단순 파일 서버입니다.
해결: 오타가 아니라 서버 능력의 문제입니다. POST를 받으려면 POST를 처리하도록 만든 서버가 필요합니다 — 그런 연습용 서버를 직접 만드는 실습이 곧 이어집니다.

벽 5. 301인데 아무 내용이 안 보인다

증상: curl로 요청했더니 본문 없이 Location: 헤더만 옵니다.
원인: 브라우저는 리다이렉트(이사 안내)를 자동으로 따라가지만, curl은 기본적으로 따라가지 않습니다.
해결: -L 옵션을 붙이면 안내를 따라갑니다. curl -L 주소처럼요. 몇 단계를 거쳐 도착했는지도 -v와 함께 볼 수 있습니다.


7. 정리

오늘의 개념

개념 한 줄 설명
HTTP 브라우저와 서버의 대화 문법 — 요청과 응답의 반복
요청 = 메서드+경로+헤더+본문 "무엇을(메서드) 어디에(경로)" + 부가 정보(헤더) + 내용물(본문)
응답 = 상태코드+헤더+본문 결과 신호(상태코드) + 설명(헤더) + 내용물(본문)
상태코드 서버의 한 마디 — 200 성공 / 301 이사 / 403 금지 / 404 없음 / 500 서버 사고
GET vs POST 주소에 싣기(조회) vs 본문에 싣기(변화) — 둘 다 암호화 아님
헤더 클라이언트가 주장하는 정보 — 서버는 검증 없이 믿으면 안 된다
127.0.0.1 내 컴퓨터 자신을 가리키는 특별 주소 — 안전한 연습장

오늘의 명령

명령 하는 일
python -m http.server 8001 현재 폴더를 내놓는 실습 서버 (종료: Ctrl+C)
curl -v 주소 요청·응답 전문 보기 (> 요청, < 응답)
curl -I 주소 헤더만 받기 (HEAD 요청)
curl -A "문자열" 주소 User-Agent 변장
curl -X POST -d "이름=값" 주소 POST 본문 실어 보내기
curl -L 주소 리다이렉트 따라가기

명령어보다 중요한 감각

오늘의 핵심 감각은 "화면 뒤에는 항상 텍스트 대화가 있다"는 것입니다. 예쁜 페이지도, 로그인도, 결국 메서드 경로 버전 한 줄로 시작하는 텍스트가 오간 결과입니다. 이 대화를 읽을 수 있게 되면 웹의 모든 현상이 분석 대상으로 바뀝니다. 보안과의 연결: 웹 공격의 거의 전부가 "요청을 변조하는 기술"입니다 — 헤더를 바꾸고, 경로를 바꾸고, 본문을 바꿉니다. 오늘 curl로 손수 해 본 그것이 이미 변조의 첫걸음이며, 헤더 중 Cookie(로그인 신분증 쪽지)가 왜 특별히 보호받아야 하는지도 이 대화 구조에서 나옵니다. 참고로 오늘 본 대화는 평문이었습니다. HTTPS는 이 대화 통째를 암호화한 것으로, 중간의 도청자는 내용 대신 암호문만 보게 됩니다.


전부 체크되면 Step 73 완료입니다. 사이드바의 체크박스를 눌러 진도를 저장하세요.