프로그래밍

HTTP란 무엇인가

2kindsofcs 2020. 3. 24. 00:29

 

HTTP란 무엇인가? 

HTTP는 HyperText Transfer Protocol의 약자이다.

프로토콜은 컴퓨터와 컴퓨터가 통신을 할 때 지켜야 할 절차나 규약이다. 

HTTP는 월드 와이드 웹에서 정보를 주고받을 수 있는 규약이다.

 

클라이언트 PC의 웹 브라우저, 그리고 웹 서버는 HTTP 프로토콜을 사용하여 정보를 주고 받는다.

이때 이 주고받는 정보들을 HTTP 메시지라고 부른다.

HTTP 메시지는 요청(Request)과 응답(Response) 두 가지 형태가 있다. 

 

HTTP 메시지의 구성 요소

- 요청 정보 행(request line) / 응답 정보 행(status line)

: 메세지의 종류 또는 상태를 표시한다. 

Ex) GET /example/something.html HTTP/1.1

Ex2) HTTP/1.1 200 OK

 

- 헤더(header)

: 메세지에 대한 자세한 정보

Ex) Accept: text/html, application/xhtml+xml

Ex2) Content-Type: text/html; charset=UTF-8

 

- 빈 줄(blank line)

 

- 메세지 바디(message body)

 

메세지 예시는 터미널에서 curl 명령어를 통해 간편하게 확인할 수 있다.

아래는 네이버에 curl 명령어로 get 요청을 보낸 것이다. 

(참고로 GET 요청의 경우 메세지 바디가 없다.)

$ curl -v www.naver.com
*   Trying 125.209.222.142...
* TCP_NODELAY set
* Connected to www.naver.com (125.209.222.142) port 80 (#0)
> GET / HTTP/1.1
> Host: www.naver.com
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 302 Moved Temporarily
< Server: NWS
< Date: Mon, 23 Mar 2020 12:25:42 GMT
< Content-Type: text/html
< Transfer-Encoding: chunked
< Connection: keep-alive
< Location: https://www.naver.com/
< Vary: Accept-Encoding,User-Agent
<
<html>
<head><title>302 Found</title></head>
<body>
<center><h1>302 Found</h1></center>
<hr><center> NWS </center>
</body>
</html>
* Connection #0 to host www.naver.com left intact
* Closing connection 0

 

헤더에는 HTTP 메세지에 대한 자세한 정보가 들어간다고 했다. 

예를 들어 리퀘스트의 Accept는 클라이언트가 이해 가능한 컨텐츠 타입을 알려준다.

위에 있는 */*의 경우 모든 MIME 타입을 받을 수 있다는 뜻이다. 

(참고: https://developer.mozilla.org/ko/docs/Web/HTTP/Headers/Accept)

 

리스폰스를 보자. 

응답 정보 행, 헤더가 순서대로 나오고 빈 줄이 하나 있다.

빈 줄 밑에 있는 것이 메세지 바디이다. html 파일의 내용이 있다. 

 

HTTP 메소드

- GET: 특정 리소스 표시 요청

- HEAD:  특정 리소스를 GET 메서드로 요청했을 때 돌아올 헤더를 요청

- POST: 서버로 데이터를 전송 

- PUT: 요청 페이로드를 사용해 새로운 리소스를 생성하거나, 대상 리소스의 데이터를 대체 

- DELETE: 특정 리소스를 삭제

- CONNECT: 요청한 리소스에 대해 양방향 연결을 시작

- OPTIONS: 목표 리소스와의 통신 옵션을 알기 위해 사용

- TRACE: 디버깅에 용이한 메소드. loop-back으로 메세지를 반환한다. 

- PATCH: 리소스를 부분적으로 수정

 

위키피디아의 http 항목에 잘 정리되어 있다.

 

멱등성

PUT과 POST는 비슷해보이는데,  PUT은 멱등성이 있다.

동일한 요청을 한 번 보내는 것과 여러 번 연속으로 보내는 것이 같은 효과를 지니고, 서버의 상태도 동일하게 남을 때, 해당 HTTP 메서드가 멱등성을 가졌다고 말합니다.

- MDN 멱등성 https://developer.mozilla.org/ko/docs/Glossary/Idempotent

PUT 메소드로 요청을 딱 한 번 보내든, 여러 번 연속으로 보내든 결과가 동일하다. side effect가 없다. 

GET 메소드 역시 멱등성 있는 메소드이다. 몇 번이고 클라이언트가 서버에 GET 요청을 보내도 돌아오는 응답은 동일하다. 

 

 

안전

어떤 http 메소드가 안전하다는 것은 무엇을 의미하는가?

해당 메소드가 서버의 상태를 변경시키지 않는다는 뜻이다. 즉 read-only 동작만 시키는 것이다. 

GET, HEAD, OPTIONS는 안전하다. 안전한 http 메소드는 모두 멱등성을 가진다. 

(역은 항상 성립한다고 할 수 없다. 모든 멱등성을 가진 메소드가 안전한 메소드는 아니다. )

 

중요한 것은 클라이언트가 안전한 메소드를 호출할 때 서버 측에 어떤 변화도 요구하지 않는다는 것이다. 

서버가 GET 요청을 받고, 요청된 리소스를 돌려주는 것 외에 로깅이라든가 이것저것 일을 수행할 수는 있어도

그건 GET 요청에 의한 것들이 아니다. 

 

캐시

캐싱은 어떤 리소스의 복사본을 저장해 두었다가 필요할 때 접근해서 사용할 수 있게 하는 것이다. 

웹 캐시의 경우, 만약 자신의 저장소에 요청된 리소스의 복사본을 가지고 있으면,

서버에 리소스를 또 요청해서 받아오는 것이 아니라 갖고 있는 복사본을 사용한다.

클라이언트 입장에서는 요청을 하나 절약하고 리소스에 빠르게 접근할 수 있으며, 

서버 입장에서는 로드가 줄어드므로 이득이다. 

 

Cache-Control과 Etag 

 

https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching?hl=ko

 

서버가 리스폰스를 보낼 때, 헤더에 캐싱 지시문과 유효성 검사 토큰을 제공하여 http 캐시를 구현할 수 있다.

 

Cache-Control 지시문은 응답을 캐시할 수 있는 사용자, 캐시 조건, 캐시 기간을 제어한다.

 

 

캐시하지 않음

Cache-Control: no-store

서버 응답을 저장할 수 없다. 응답은 항상 다운로드 된다.

 

캐시를 하되 재검증

Cache-Control: no-cache

캐시된 리소스를 사용자에게 보여주기 전에, 서버에 요청을 보내서 확인해야 한다.

유효성 검사 토큰(ETag)가 있을 경우, 캐시된 응답이 유효한지 서버에 요청을 하고 응답을 받는다. 

한 번의 왕복이 발생하지만 리소스가 변경되지 않았을 경우 새로 다운로드를 받지 않는다. 

 

공유 캐시

Cache-Contorl: public

어떤 캐시에 의해서든 캐시된다는 뜻이다. 

 

사설 캐시

Cache-Control: private

응답이 단일 사용자를 위한 것이며, 공유 캐시에 의해 저장되서는 안 된다는 뜻이다. 

예를 들어, 비공개 사용자 정보가 포함된 HTML 페이지는 사용자의 브라우저가 캐시할 수 있지만, CDN은 이 페이지를 캐시할 수 없다. 

 

만료

Cache-Control: max-age=120

요청 시간부터 가져온 응답을 활용할 수 있는 최대 시간을 지정한다. 단위는 초다.

max-age=120은 응답이 120초 동안 캐시되어 재활용될 수 있다는 뜻이다. 

 

 

ETag

ETag HTTP 응답 헤더는 특정 버전의 리소스를 식별하는 식별자다. 

https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching?hl=ko

예를 들어 max-age가 120초인 리소스를 다운로드 받고 나서, 120초가 지나면 클라이언트는 다시 서버에게 리소스를 요청할 것이다.

그런데 120초가 지났는데 정작 해당 리소스에 변경사항이 없다면, 또 다운로드 하는 일은 낭비이다. 

ETag는 이러한 낭비를 막기 위해 나온 장치다. 

 

클라이언트로부터 리퀘스트가 왔을 때, 서버가 리스폰스에 ETag를 포함해서 보내도록 하면,

max-age가 초과되었을 때 클라이언트는 받았던 'If-None-Match' 요청 헤드에 ETag를 넣어 리퀘스트를 보낸다. 

서버는 해당 ETag를 확인하여, 변경사항이 없다면 304 Not Modified로 응답을 보낸다.  

이는 캐시에 저장된 리소스가 변경되지 않았고, 추가로 120초 동안 유효하다는 뜻이다. 

그러면 클라이언트는 새로 다운로드 받지 않고 기존에 있던 리소스를 사용한다.  

 

 

상태 코드

응답 상태를 나타내는 코드이다. 

우리의 친구 위키피디아에 잘 정리되어 있다. 

  • 1xx (정보): 요청을 받았으며 프로세스를 계속한다
    • 100 Continue - 클라이언트로부터 일부 요청을 받음, 나머지 요청 정보를 계속 보내주길 바람
  • 2xx (성공): 요청을 성공적으로 받았으며 인식했고 수용하였다
    • 200 OK - 오류 없이 전송 성공
    • 201, 204 도 알면 좋음 
  • 3xx (리다이렉션): 요청 완료를 위해 추가 작업 조치가 필요하다
    • 301 Moved Permanently - 요구한 데이터를 변경된 URL에서 찾았음
    • 302 Moved Temporarily - 301과 유사하나 임시 저장 장소로 해석됨
  • 4xx (클라이언트 오류): 요청의 문법이 잘못되었거나 요청을 처리할 수 없다
    • 400 Bad Request - 요청 실패. 서버가 요청사항을 이해하지 못함
    • 401 Unauthorized - 해당 리소스에 유효한 인증 자격이 없어서 응답할 수 없음. "인증이 안 됨"
      • 요청이 왔는데 사용자가 누구인지 식별할 수 없음. 로그인하지 않은 유저가 뭔가를 하려고 할 때.
    • 403.x Forbidden - 금지. "인가가 안 됨"
      • 누군지는 알겠는데 (식별은 되었는데) 넌 뭘 할 자격이 없다.
    • 404 Not Found - 문서를 찾을 수 없음. 요청한 파일이나 스크립트를 찾지 못함.
    • 405 Method Not Allowed
    • 406 Not Acceptable 
    • 409 Conflict - 요청을 처리하는 데 문제가 있음. 보통 다른 버전의 파일을 업로드할 때 발생.
    • 413 Request Entitiy Too Large - 요청된 문서가 서버가 다룰 수 있는 크기보다 더 큼
    • 415 Unsupported Media Type 
    • 431 Request Header Fields Too Large - http 헤더가 너무 김. 
  • 5xx (서버 오류): 서버가 명백히 유효한 요청에 대해 충족을 실패했다
    • 500 Inernal Server Error - 서버 내부 오류
    • 502 Bad gateway - 게이트웨이 상태 나쁨
    • 503 Service Unavailable - 서비스가 멈춘 상태거나 이용할 수 없는 서비스

 

반응형