HTTP Overview

HTTPλŠ” μ‹ λ’°μ„± μžˆλŠ” 데이터 전솑 ν”„λ‘œν† μ½œ(TCP)λ₯Ό μ‚¬μš©ν•˜κΈ° λ•Œλ¬Έμ— 전솑 쀑 νŒŒκ΄΄λ˜κ±°λ‚˜ μ€‘λ³΅λ˜κ±°λ‚˜ μ™œκ³‘λ˜μ§€ μ•ŠλŠ”λ‹€. κ°œλ°œμžλŠ” 인터넷 κ²°ν•¨μ΄λ‚˜ 약점에 λŒ€ν•œ 걱정없이 κΈ°λŠ₯ κ΅¬ν˜„μ— 집쀑할 수 μžˆλ‹€.


μ›Ή ν΄λΌμ΄μ–ΈνŠΈμ™€ μ„œλ²„

μ›Ή μ½˜ν…μΈ λŠ” μ›Ή μ„œλ²„μ— μ‘΄μž¬ν•œλ‹€. μ›Ή ν΄λΌμ΄μ–ΈνŠΈλŠ” μ„œλ²„μ—κ²Œ HTTP μš”μ²­μ„ 보내고 μ„œλ²„λŠ” μš”μ²­λœ 데이터λ₯Ό HTTPμ‘λ‹΅μœΌλ‘œ λŒλ €μ€€λ‹€.

μ„œλ²„ ν΄λΌμ΄μ–ΈνŠΈ λͺ¨λΈ


HTTPλ₯Ό μ΄μš©ν•΄ μ›Ήμ„œλ²„μ˜ λ¦¬μ†ŒμŠ€λ₯Ό μš”μ²­ν•˜μ—¬ λΈŒλΌμš°μ €μ— λ³΄μ—¬μ£ΌλŠ” 과정을 λ‹¨μˆœν™”ν•˜λ©΄ λ‹€μŒκ³Ό 같은 μˆœμ„œλ‘œ 이루어진닀.

  • λΈŒλΌμš°μ €κ°€ URLμ—μ„œ 호슀트λͺ…κ³Ό 포트번호(μžˆλ‹€λ©΄)λ₯Ό μΆ”μΆœν•œλ‹€.
  • DNSλ₯Ό 톡해 URL을 IP둜 λ³€ν™˜ν•œλ‹€.
  • λΈŒλΌμš°μ €μ™€ μ›Ήμ„œλ²„ 사이에 TCP 컀λ„₯μ…˜μ„ λ§ΊλŠ”λ‹€.
  • λΈŒλΌμš°μ €κ°€ μ„œλ²„μ— HTTP μš”μ²­μ„ 보낸닀.
  • μ„œλ²„λŠ” λΈŒλΌμš°μ €μ— HTTP 응닡을 λŒλ €μ€€λ‹€.
  • TCP 컀λ„₯μ…˜μ΄ λ‹«νžˆλ©΄, λΈŒλΌμš°μ €κ°€ μ„œλ²„μ—μ„œ λ°›μ•„μ˜¨ λ¦¬μ†ŒμŠ€λ₯Ό 보여쀀닀.

λ©”μ‹œμ§€(Message)

HTTP νŠΈλžœμž­μ…˜μ€ μš”μ²­λͺ…λ Ή(ν΄λΌμ΄μ–ΈνŠΈμ—μ„œ μ„œλ²„λ‘œ λ³΄λ‚΄λŠ”)κ³Ό 응닡 κ²°κ³Ό(μ„œλ²„κ°€ ν΄λΌμ΄μ–ΈνŠΈμ—κ²Œ λŒλ €μ£ΌλŠ”)둜 κ΅¬μ„±λ˜μ–΄μžˆλ‹€. 이 μƒν˜Έ μž‘μš©μ€ HTTP λ©”μ‹œμ§€λΌκ³  λΆˆλ¦¬λŠ” 데이터 덩어리λ₯Ό μ΄μš©ν•΄ 이루어진닀. HTTP λ©”μ‹œμ§€λŠ” λ‹¨μˆœν•œ 쀄 λ‹¨μœ„μ˜ λ¬Έμžμ—΄μ΄λ‹€. λ°”μ΄λ„ˆλ¦¬ ν˜•μ‹μ΄ μ•„λ‹Œ 일반 ν…μŠ€νŠΈμ΄κΈ° λ•Œλ¬Έμ— 읽고 μ“°κΈ° 쉽닀. HTTP λ©”μ‹œμ§€λŠ” λ‹€μŒ μ„Έ λΆ€λΆ„μœΌλ‘œ 이루어 진닀.

  • μ‹œμž‘μ€„(start-line) : λ©”μ‹œμ§€μ˜ 첫 쀄은 μ‹œμž‘μ€„λ‘œ μš”μ²­μ΄λΌλ©΄ 무엇을 ν•΄μ•Ό ν•˜λŠ”μ§€ 응닡이라면 무슨일이 μΌμ–΄λ‚¬λŠ”μ§€ λ‚˜νƒ€λ‚Έλ‹€.
  • 헀더(headers) : μ‹œμž‘μ€„ λ‹€μŒμ—λŠ” 0개 μ΄μƒμ˜ 헀더 ν•„λ“œκ°€ 이어진닀. 각 헀더 ν•„λ“œλŠ” μ‰¬μš΄ ꡬ문뢄석을 μœ„ν•΄ :둜 κ΅¬λΆ„λ˜μ–΄ 이름과 κ°’μœΌλ‘œ κ΅¬μ„±λœλ‹€. ν—€λ”λŠ” 빈 μ€„λ‘œ λλ‚œλ‹€.
  • λ³Έλ¬Έ(body) : 빈 쀄 λ‹€μŒμ—λŠ” μ–΄λ–€ μ’…λ₯˜μ˜ 데이터든 ν•„μš”μ— 따라 λ“€μ–΄κ°ˆ 수 μžˆλ‹€. μš”μ²­μ˜ 본문은 μ›Ήμ„œλ²„λ‘œ 데이터λ₯Ό μ‹€μ–΄ 보내며, μ‘λ‹΅μ˜ 본문은 ν΄λΌμ΄μ–ΈνŠΈλ‘œ 데이터λ₯Ό λ°˜ν™˜ν•œλ‹€. μ‹œμž‘μ€„μ΄λ‚˜ 헀더와 달리 본문은 이진데이터λ₯Ό 포함할 수 μžˆλ‹€.

λ¦¬μ†ŒμŠ€μ™€ λ―Έλ””μ–΄νƒ€μž…

λŒ€ν‘œμ μΈ μ›Ή λ¦¬μ†ŒμŠ€λŠ” ν…μŠ€νŠΈ, HTML, 이미지등 λͺ¨λ“  μ’…λ₯˜μ˜ 정적 νŒŒμΌμ΄λ‹€. HTTPλ₯Ό 톡해 μ˜€κ³ κ°€λŠ” 객체(λ¦¬μ†ŒμŠ€λ₯Ό ν¬ν•¨ν•˜λŠ”)μ—λŠ” MIME νƒ€μž…μ΄λΌλŠ” 데이터 포맷 라벨을 뢙인닀. μ›ΉλΈŒλΌμš°μ €λŠ” μ„œλ²„λ‘œλΆ€ν„° 받은 응닡 κ²°κ³Όμ—μ„œ MIMEνƒ€μž…μ„ 톡해 λ‹€λ£° 수 μžˆλŠ” 데이터 포맷인지 ν™•μΈν•œλ‹€. λΈŒλΌμš°μ €λŠ” μˆ˜λ°±κ°€μ§€μ˜ νƒ€μž…μ„ λ‹€λ£° 수 있으며 νŠΉλ³„ν•œ 포맷의 νŒŒμΌμ„ 닀루기 μœ„ν•΄ μ™ΈλΆ€ ν”ŒλŸ¬κ·ΈμΈ μ†Œν”„νŠΈμ›¨μ–΄λ₯Ό μ‹€ν–‰ν•œλ‹€.


MIMEνƒ€μž…μ€ /둜 κ΅¬λΆ„λœ μ£Ό νƒ€μž…(primary object type)κ³Ό λΆ€ νƒ€μž…(specific subtype)으둜 이루어진 λ¬Έμžμ—΄ 라벨이닀. HTTP λ©”μ‹œμ§€μ˜ 헀더에 Content-Type의 κ°’μœΌλ‘œ λͺ…μ‹œν•œλ‹€.

Content-Type: [MIME νƒ€μž…]

λŒ€ν‘œμ μΈ νƒ€μž…μ€ λ‹€μŒκ³Ό κ°™λ‹€.

  • text/html : HTML λ¬Έμ„œ
  • text/plain : plain ASCII ν…μŠ€νŠΈ λ¬Έμ„œ
  • application/json : json 파일
  • application/x-www-form-urlencoded : querystring으둜 μ„œλ²„μ— μ „μ†‘ν•˜λŠ” form 데이터
  • multipart/form-data : 각각의 νŒŒνŠΈλ§ˆλ‹€ Content-Type 이 μ‘΄μž¬ν•˜λŠ” form 데이터
  • image/jpeg : jpeg 이미지

λ©”μ„œλ“œ(Method)

HTTPλŠ” HTTP λ©”μ„œλ“œλΌκ³  λΆˆλ¦¬λŠ” μ—¬λŸ¬ μ’…λ₯˜μ˜ μš”μ²­ λͺ…령을 μ§€μ›ν•œλ‹€. λͺ¨λ“  HTTP μš”μ²­ λ©”μ‹œμ§€λŠ” ν•œκ°œμ˜ λ©”μ„œλ“œλ₯Ό κ°–λŠ”λ‹€. λ©”μ„œλ“œλŠ” μ„œλ²„μ—κ²Œ μ–΄λ–€ λ™μž‘μ΄ μ·¨ν•΄μ Έμ•Ό ν•˜λŠ”μ§€ 말해쀀닀.

  • GET : μ›Ήμ„œλ²„μΈ‘μ— λ¦¬μ†ŒμŠ€ μš”μ²­ν•œλ‹€.

    • 쑰건뢀 μš”μ²­ : μΊμ‹œλ₯Ό 가지고 μžˆμ§€ μ•Šμ€ 경우 200 OK μƒνƒœλ‘œ 응닡을 νšŒμ‹ ν•œλ‹€. μΊμ‹œλœ λ¦¬μ†ŒμŠ€κ°€ μ‘΄μž¬ν•˜κ³  λ¦¬μ†ŒμŠ€κ°€ λ³€κ²½λ˜μ§€ μ•Šμ•˜λ‹€λ©΄ 304 Not Modified 응닡을 νšŒμ‹ ν•œλ‹€. λ¦¬μ†ŒμŠ€κ°€ λ³€κ²½λ˜μ—ˆλ‹€λ©΄ μƒˆλ‘œμš΄ λ¦¬μ†ŒμŠ€μ™€ ν•¨κ»˜ 200 OK 응닡을 νšŒμ‹ ν•œλ‹€.
  • POST : μ„œλ²„μΈ‘μ— 데이터λ₯Ό HTTP Body에 λ‹΄μ•„ μ›Ήμ„œλ²„λ‘œ μ „λ‹¬ν•œλ‹€.
  • PUT : λ¦¬μ†ŒμŠ€ 전체λ₯Ό κ°±μ‹ λ₯Ό μƒμ‹ ν•œλ‹€. λͺ¨λ“  ν•„λ“œ μ˜μ—­μ΄ ν•„μš”ν•˜λ‹€. μΌλΆ€λ§Œ 전달할 경우 μ΄ˆκΈ°κ°’ ν˜Ήμ€ null둜 μ²˜λ¦¬λœλ‹€.
  • PATCH : λ¦¬μ†ŒμŠ€μ˜ 일뢀뢄을 κ°±μ‹ ν•œλ‹€. κ°±μ‹ ν•˜λ €λŠ” 일뢀 ν•„λ“œ μ˜μ—­μ΄ ν•„μš”ν•˜λ‹€.
  • DELETE : λ¦¬μ†ŒμŠ€λ₯Ό μ‚­μ œ ν•œλ‹€.

μƒνƒœμ½”λ“œ

λͺ¨λ“  HTTP 응닡 λ©”μ‹œμ§€λŠ” μƒνƒœ μ½”λ“œμ™€ ν•¨κ»˜ λ°˜ν™˜λœλ‹€. μƒνƒœμ½”λ“œλŠ” ν΄λΌμ΄μ–ΈνŠΈμ—κ²Œ μš”μ²­μ΄ μ„±κ³΅ν–ˆλŠ”μ§€ μ•„λ‹ˆλ©΄ μΆ”κ°€ μ‘°μΉ˜κ°€ ν•„μš”ν•œμ§€ μ•Œλ €μ€€λ‹€. μƒνƒœμ½”λ“œλŠ” μ„Έμžλ¦¬ μˆ«μžμ΄λ‹€. 각 μƒνƒœ μ½”λ“œμ— ν…μŠ€νŠΈλ‘œλœ μ‚¬μœ (reason phrase)도 ν•¨κ»˜ λ³΄λ‚΄μ§€λŠ”λ°, 이 ꡬ문은 단지 μ„€λͺ…λ§Œμ„ μœ„ν•΄ ν¬ν•¨λœκ²ƒμΌλΏ μ‹€μ œ 응닡 μ²˜λ¦¬μ—λŠ” 숫자둜 된 μ½”λ“œκ°€ μ‚¬μš©λœλ‹€.

  • 200 : 성곡
  • 3xx : λ¦¬λ‹€μ΄λ ‰μ…˜

    • 304 Not modified : 둜컬 μΊμ‹œ 정보λ₯Ό μ΄μš©ν•¨
  • 4xx : ν΄λΌμ΄μ–ΈνŠΈμΈ‘ μ—λŸ¬

    • 401 Unauthorized : κΆŒν•œ μ—†μŒ
    • 404 Not Found : μš”μ²­ν•œ λ¦¬μ†ŒμŠ€κ°€ λ°œκ²¬λ˜μ§€ μ•ŠμŒ
  • 5xx : μ„œλ²„μΈ‘ μ—λŸ¬

    • 500 Internal Server Error : μ„œλ²„ λ‚΄λΆ€ 였λ₯˜
    • 502 Bad Gateway : 잘λͺ»λœ κ²Œμ΄νŠΈμ›¨μ΄(μ ‘μ†ν•œ ν”„λ‘μ‹œ μ„œλ²„μ—μ„œ λ‚΄λΆ€ 망에 μ›Ήμ„œλ²„λ‘œλΆ€ν„° 잘λͺ»λœ 응닡을 λ°›μ•˜μ„λ•Œ)
    • Service Unavailable : μ„œλΉ„μŠ€ λΆˆκ°€

κ°„λ‹¨ν•œ μ‹€μŠ΅

ν„°λ―Έλ„μ—μ„œ curl 을 μ‚¬μš©ν•˜μ—¬ μ„œλ²„μ— μš”μ²­μ„ 보내면 μ „μ†‘λ˜λŠ” μš”μ²­ λ©”μ‹œμ§€μ™€ μ„œλ²„μ—μ„œ λŒμ•„μ˜€λŠ” μ‘λ‹΅λ©”μ‹œμ§€λ₯Ό ν„°λ―Έλ„μ—μ„œ 확인할 수 μžˆλ‹€. μ΄λ•Œ ν΄λΌμ΄μ–ΈνŠΈλŠ” 터미널이 λœλ‹€.

$ curl -v localhost:3000

μ„œλ²„λŠ” Node.jsλ₯Ό μ‚¬μš©ν•΄ κ°„λ‹¨ν•˜κ²Œ κ΅¬ν˜„ν•΄λ³΄μ•˜λ‹€.

const http = require('http');
const server = http.createServer((req, res) => {
  res.writeHead(200, {
    'content-type': 'text/html'
  });

  res.write('<div>λ³Έλ¬Έ</div>');
  res.end('<div>끝</div>',() => {
    console.log('μ „μ†‘μ™„λ£Œ');
  });
});

server.listen(3000);

μš”μ²­(Request) λ©”μ‹œμ§€

μ‹œμž‘μ€„μ—μ„œ GET μš”μ²­μž„μ„ 보여쀀닀. κ·Έ λ‹€μŒ 쀄뢀터 3μ€„μ˜ 헀더가 :λ₯Ό κΈ°μ€€μœΌλ‘œ κ°’κ³Ό 이름 쌍으둜 λͺ…μ‹œλ˜μ–΄μžˆκ³  ν—€λ”μ˜ 끝을 λ‚˜νƒ€λ‚΄λŠ” λΉˆμ€„μ΄ μžˆλ‹€. 본문은 μ „λ‹¬ν•˜μ§€ μ•Šμ•˜λ‹€.

> GET / HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.54.0
> Accept: */*
>

응닡(response) λ©”μ‹œμ§€

μ‹œμž‘μ€„μ—λŠ” HTTP λ²„μ „λ²ˆν˜Έ(HTTP/1.1) μƒνƒœμ½”λ“œμ™€ μ‚¬μœ (200 OK)κ°€ μ ν˜€μžˆλ‹€. res.writeHead둜 μƒνƒœμ½”λ“œ 200을 λͺ…μ‹œν–ˆκΈ° λ•Œλ¬Έμ΄λ‹€. κ°™μ€μ΄μœ λ‘œ 헀더 ν•„λ“œ μ˜μ—­μ—λŠ” content-type: text/html κ°€ μ ν˜€μžˆλ‹€. ν—€λ”μ˜ 끝을 λœ»ν•˜λŠ” λΉˆμ€„ 이후 본문에 μ„œλ²„μ—μ„œ μ „μ†‘ν•œ 데이터가 λ“€μ–΄μžˆλ‹€.

< HTTP/1.1 200 OK
< content-type: text/html
< Date: Thu, 03 Oct 2019 09:48:11 GMT
< Connection: keep-alive
< Transfer-Encoding: chunked
<
<div>λ³Έλ¬Έ</div>
<div>끝</div>

μ°Έκ³