3 minute read

??

Hypertext transfer protocal, 링크를 통해 연결된 하이퍼텍스트를 서버와 클라이언트간에 통신하는 프로토콜을 의미한다. 사실 HTML 뿐만아니라 다양한 형식의 데이터를 주고 받을수 있다.

HTTP는 서버 클라이언트 모델이다. 요청을 하는 클라이언트와 응답을 제공하는 서버로 분리하는 분산 아키텍처이다. 서버는 응답에만 집중, 클라이언트는 요청에만 집중, 각각이 독립적으로 발전할수 있는 계기가 되었다.

버전별 특징

  • 0.9: GET만 지원
  • 1.0: Content-type을 통한 다른 형식의 데이터전달, Header 도입
  • 1.1: keepalive를 통한 맺은 연결을 계속 사용할수 있다.
    • nginx 최적화 문제
  • 2.0: 성능향상을 위한 확장팩

HTTP의 비연결성(Connectionless)과 비상태성(Stateless)

비연결성이란, 클라이언트와 서버가 연결을 맺은후, 클라이언트 요청에 대하여 서버가 응답을 마치면 맺었던 연결을 끊어 버리는 성질을 의미한다. 따라서 클라이언트, 서버 입장에서 보았을때 새로운 연결 발생시, 이전에 서버와 연결했던 사실을 알수 없다. (항상 새로운 연결이 발생했다고 인지한다.)

비상태성이란, 연결이 종료된후, 연결 기간동안의 상태를 유지하지 않는 성질을 의미한다. 다음에 서버와 클라이언트가 연결되었을때 이루어지는 통신은 이전에 있었던 연결에 영향을 받지 않는다.

KEEPALIVE

http1.1 부터 추가된 기능으로, 커넥션을 제한시간동안 계속 쓸수 있는 스펙이다. 비연결성이라는 특징을 보완한다. 클라이언트와 서버간의 소켓을 통해 연결된다. 다만 keepalive를 통해 유지되는 연결(소켓)이 많고 서비스를 사용하는 유저층이 많고 불규칙적이라면, 사용하지 않는 메모리로 인한 누수가 있을수 있다.

쿠키

Cookie란 서버가 클라이언트의 웹브라우저에 보내는 작은 용량의 데이터이다. Cookie는 클라이언트에서 정보를 임시로 저장하는 기술이다. 웹브라우저는 전송된 쿠키를 저장했다가 다시 서버와 연결시, 필요한정보들과 request.header에 쿠키를 담아 전송한다. 쿠키를 통해 사용자 인증, 개인화, 트래킹 등을 할수 있어 stateless의 단점을 보완할수 있다. 다음과 같은 옵션이 있다.

  • HttpOnly: 웹 브라우저와 서버가 통신할 때에만 쿠키를 전달
  • Secure: HTTPS프로토콜을 사용할 때에만 전송
  • SameSite: 쿠키가 Cross-Site의 요청과 함께 전달되지 않음

하지만 장점만 있는것은 아니다. 쿠키는 공간 제약이 있다. 자바스크립트를 통해 쿠키에 접근할수있다면 XSS 공격(Cross site scripting)에 취약하다. httponly 옵션을 통해 자바스크립트로 쿠키에 접근하는것을 막을수 있다.

쿠키와 함께 CSRF(Cross-site request forgery) 서버 **요청을 통해 악의적인 행동을 할수 있다. 가짜 사이트로 위장하고, 폼은 원래사이트로 요청하게 되면 사용자의 정보를 판단하는 쿠키정보가 같이 전달되어 광고글 삽입등의 악의적인 행동을 할수 있는것이다. csrf token을 서버에서 발급받아서 사용하는 방법이 있다.

세션

세션은 서버에서 저장하여 관리하는 연결과 관련된 데이터이다. 쿠키와 다른점은 데이터를 클라이언트 뿐만아니라 서버에서도 관리한다.

HTTP 메시지

서버와 클라이언트간의 HTTP 프로토콜을 통해 주고 받는 메시지 (startline, header, body)를 의미한다. HTTP 메시지는 startline과 header, body로 구성되어있다. startline은 요청과 응답에 따라 들어가는 내용이 달라지는데, 요청의 경우 url과 http메소드, 버전, 응답은 응답코드, http메소드로 구성되어있다. 헤더의 경우 컨텐츠타입, 호스트정보, 쿠키설정, 캐시설정등의 http 통신에 필요한 메타데이터를 담고 있다. 바디의 경우 http 요청, 응답에 필요한 데이터를 담고 있다.

HTTP METHOD

  • GET
    • 데이터를 조회할때 사용
    • queryString을 통해 파라미터 전달
    • 멱등하다. (같은 요청을 몇번을 실행해도 리소스의 상태가 변하지 않는다)
  • HEAD
    • Header를 조회할때 사용한다.
    • [Content-Length](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Length)를 통해 파일을 다운로드 하지 않고도 사이즈를 알수 있다.
    • 멱등하다.
  • POST
    • 자원의 생성, 업데이트, body데이터기반으로 한 비즈니스 처리에 사용된다.
    • body를 사용하기도 한다.
  • PUT
    • 덮어쓰기! 멱등하다.
  • PATCH
    • 자원의 일부를 변경할때 사용
  • DELETE
    • 자원을 삭제할때 사용
    • 멱등하다.
  • OPTIONS
    • 어떤 메소드를 지원하는지 여부를 알려준다.

HTTP 응답코드

  • 100 (서버의 현재 상태, 정보)
    • 100 (information)
      • 계속해서 요청을 보내도 된다!
      • 요청을 보내기전에 미리 Content-length 헤더를 보내고 서버가 가용할수 있으면 판단한다.
    • 101 (switching protocol)
      • 프로토콜이 변경되었음을 클라이언트에 통지
      • http → websocket
  • 200 (정상응답)
  • 300
    • 301 (permenent): 웹 크롤러가 인식해 검색엔진 최적화에 활용할수 있다
    • 302 (temporary): X
  • 400
    • 400: bad request
    • 401:
    • 404
    • 405
  • 500
    • 500: 어플리케이션 에러
    • 503: 서버가 일시적으로 요청을 처리할수 없음
    • 504: 타임아웃

HTTP CACHE

동일한 요청에 대해서 캐시를 써서 트래픽비용과 응답속도를 향상시킨다. 캐시는 오리진과 최종 클라이언트(웹브라우저)사이에 있는 프록시부터, 웹브라우저에서 사용된다. 웹브라우저에서 정적데이터를 가져오는 HTTP 요청을 할때 먼저 캐시에 응답이 있는지 확인하고, 만료여부를 확인하여 데이터를 재사용한다. 또한 요청이 오리진 전의 프록시에 도달하면, 프록시에서 오리진에 요청하기전에 파일이 있는지 확인한후 만료여부를 확인하여 재사용한다.

  • max-age
    • 캐시가 유효한 시간을 서버에서 설정해줌
    • 클라이언트는 max-age만큼 저장
  • cache-control
    • no-cache (항상 캐시를 검증하고 사용, proxy 서버는 캐싱이 금지됨)
    • no-store (항상 요청)
    • must-revalidate
      • 캐시 만료시 반드시 확인요청을 한다.
      • origin 서버의 검증을 반드시 거쳐야 한다.
      • proxy서버에서 origin서버를 건드릴수 없다면 오류를 발생시킨다.
    • public
    • private
      • 중간에 proxy에 캐싱이 되면 안된다.
    • s-maxage
      • proxy에서 캐시 maxage

캐시는 응답을 줄때 max-age, cache-control 헤더를 통해 설정옵션을 부여한후, 클라이언트(프록시, 웹브라우저)에서 헤더를 통해 캐시를 설정한다. 어떨때 요청을 cache 할수 있을까? 우선 cache에 적합한 요청은 멱등한 요청이 될것이다. 그렇다면 http method 가 get, put, delete 중에 하나가 되어야 하고, 이중 자원의 재사용에 적합한 요청은 get을 통한 정적컨텐츠 요청이 될것이다.

웹브라우저, 서버(프록시, 오리진)에서 요청을 검증할때 last modifed, etag 등의 헤더값을 사용한다.

  • last modified
    • max-age가 지나더라도 캐시를 쓸수 있는 방법이 있다.
    • 서버에서 파일을 보내줄때 last modified 헤더로 수정된 시각을 같이 보내준다
    • 클라이언트에서 캐시만료후 if modified since 헤더로 최종적으로 수정된 시각을 body없이 같이 보내준다.
    • 만약 서버에서 최종 수정 시각이 같다면 304 not modified을 전송한다!
    • 만약 다르다면 새로운 파일과 함께 200 ok을 전송한다!
    • 그러면 클라이언트에서 cache를 재사용할수 있다.
  • etag (hash)
    • 파일에 hash 값 부여
    • hash값이 같으면 캐시 사용!
    • 서버와 클라이언트

프록시

클라이언트 대신 요청해주는 서버다. HTTP 캐시를 통해 멀리 요청을 안 보내도 되기때문에 응답시간이 줄어들고 트래픽비용도 감소하는 장점이 있다.

Leave a comment