센로그

6. HTTP/1.1 본문

CS/풀스택서비스네트워킹

6. HTTP/1.1

seeyoun 2023. 10. 16. 18:25

◆ HTTP란?

서버-클라이언트 모델을 따라 데이터를 주고 받기 위한 프로토콜이다

클라가 서버에게 HTTP request 보냄그러면 서버가 이에 대한 HTTP response를 클라에게 주는 형태로 동작함.

 

그림을 보자.

웹 브라우저가 웹 서버에게 "HTTP라는 프로토콜로 root/index.html을 달라"고 요청하면,

서버는 "알겠어, 그거 여기 있고, 총 3150 length. 가져가."  하고 주는 것임. 굉장히 심플하다.

 

※ 어떻게 이렇게 심플할 수 있는 걸까?

→ 전제조건: 초기에 HTTP를 짤 때, "무조건 HTTP 밑에는 TCP가 돌아야 한다!" 라는 걸 생각하고 짰기 때문에 가능하다. 즉 어차피 TCP가 에러 검출 및 복구를 할 거기 때문에, HTTP는 그걸 신경쓰고 싶지 않고 간단하게 할 거야! 라는 초기 철학이 있었다.

 

 

이렇게 클라는 서버로부터 요청을 해서, 리소스들을 갖고 옴.

 

리소스는 정적 콘텐츠, 동적 콘텐츠로 나뉨

  • 정적 콘텐츠: Req가 오기 전에 이미 콘텐츠가 만들어져있고, req 받은 이후에도 바뀌지 않는 콘텐츠.
    기본적으로 오리지널 HTTP는 주어진 자료를 고정적인 형태로 보관하고, 요청하면 줄 뿐이었다.
    ex) 워드파일, 이미지, 비디오 등등에 해당함.
  • 동적 콘텐츠: 요청을 받으면 그 시점에 특정 로직을 돌려서 새롭게 만들어지는 콘텐츠.
    이때 요청한 사람의 추가적인 정보를 사용할 수 있다. ‘로직’이 존재하며, 관문 역할을 하는 서버가 있음.
    ex) 주주가 현재 본인의 주식 가격을 요청하는 경우

 

※ 헷갈리지 말 것: Request 오기 전에 다 만들어져있는 경우는 정적 콘텐츠다.
비디오의 경우, 컨텐츠 내부는 동적이지만 파일 자체는 정적이다. Request 받고나서야 배우들이 자 이제 찍어볼까? 하고 콘텐츠를 만들어내지는 않음. 이미 만들어진 걸 차근차근 보내줄 뿐.

 


◆ URI - URL

URI : 리소스를 식별하는 식별자

URI에는 URL과 URN이 있었는데, URN은 의미가 없어져서 사라짐

 

URL은 우리가 알다시피 요청한 파일이 어디에 있는지 식별하는 정보.

xxx.com/index.html 이라고 한다면, xxx.com 서버의 루트 디렉토리에 있는 index.html 파일을 의미함.

 


◆ HTTP 클라-서버간 통신 예시

<클라>

클라가 서버로 HTTP GET request를 보냄.

 

  • GET : 내놔! specials/saw-blade.gif 파일을 내놔.
  • 모든 통신 프로토콜은 버전이 중요함. 나는 HTTP이고 버전은 1.0이니까, 이거에 맞춰서 내놔!
  • Host : GET을 하는 상대방에 대한 정보를 달라고 함.
    → 엥? 이건 IP 계층이 하는 거 아니야..? IP에 그렇게 세팅이 되어있을텐데 왜 상위 레이어인 HTTP에다 저렇게 써놨을까..?
    → → 우리가 아는 웹 서버와 웹 브라우저는 실제로 그렇게 작동하지 않고, 둘 사이에 서버(프록시 서버) 하나가 떡하니 버티고있다. 회사에서 막어놓은 접속 불가 리스트 같은 게 있음. 그런걸 이 서버에서 처리하곤 함.

 

<서버>

  • HTTP 1.0 원했지? 알겠어. 리턴값은 200 (프로그램 입장의 OK라는 뜻. 니가 원하는 거 찾았고, 니가 말한 프로토콜로 줄 수 있어~ 라는거)
  • 콘텐츠 타입은 image, 그것도 gif야
  • 콘텐츠 length는 8572야!

 


◆ HTTP Request Methods 종류

대표적인 HTTP 리퀘스트 메소드로 네 가지가 있다.

  • GET: 리소스 파일을 내놔라.
  • PUT: 업로드. 서버에 리소스를 저장한다.
  • DELETE: 서버에 업로드한 파일을 삭제.
  • POST: 서버쪽으로 입력 파라미터(text)를 전달하는 용도. 그로 인해서 서버가 작업을 하기를 원한다.

 

이들에 대해 뒤에서 자세하게 다룰 것임.

 


◆ HTTP Status Codes

서버에 요청을 했다고 해서 무조건 다 성공하는 건 아님.

어떤 상태인지 나타내는 몇 가지 코드가 있다.

  • 404: 파일 요청헀는데 그 파일이 서버에 없는 것.
  • 302: 리다이렉트. 서버를 갈아타는 것.
    콘서트 대기창 같은 거.
  • 200: OK.성공
OK는 사람을 위한 정보, 200은 기계를 위한 리턴값 느낌

 


◆ Message 구조

HTTP 클라-서버간에 주고받는 메시지의 구조를 살펴보자.

기본적으로, 인간 이해하기 쉽도록 만들어졌다.

Start line

  • 클라: 요청, URL, 프로토콜 및 버전
  • 서버: 프로토콜 및 버전, 응답

 

Headers

Accept: 부가적인 옵션. Text의 형태는 모두 다 받을 수 있어~

Accept language: en, fr 언어만 읽을 수 있어~ 

 

 

Body

실제 메시지를 넣음

 


 TCP

HTTP/1.1은 TCP를 쓴다.

초기 HTTP는 req에 대한 resp만 바랐지, 오류 검출 같은 건 하고싶지 않았음

따라서 TCP/IP를 쓴다고 전제하고, 얘네가 알아서 에러 검출을 하도록 함

 

그러나 시대적 흐름이 변화하고 요구가 변화함에 따라, 최근에 나온 HTTP 3 같은 경우에는 TCP 안 쓰고 UDP 씀.

 


◆ HTTPS

암호화한 HTTP

HTTPSecurity. 

 

HTTP를 살짝 수정해서 SSL또는 TLS(보안 레이어)를 사용하도록 한 게 HTTPS임.

서버와 클라 사이에 어떤 정보도 까볼 수 없도록 한 .

 

대신 클라와 서버의 성능은 저하되며, 최초 연결시에 암호키를 주고받거나 하는 부분이 있는 만큼 최초 연결이 굉장히 느려진다

 

※ 최초 연결은 중요한데: TCP는 원래부터 최초 연결이 congestion window 1부터 시작하니까 느린데(slow start), 이런 보안 설정까지 하게되면 더 느려지는 것! ㅠㅠ

 


◆ HTTP 연결 과정

URL을 입력하면, 브라우저가 DNS 서버로 접속해서 IP 주소를 가져온 후, TCP 레이어가 소켓을 열어서 연결함.

그 위에서 HTTP GET이 날라가고, response를 받으며 정보를 전달함.

시간이 오래 지났음에도 뭔가를 안하면 연결이 끊어지는 구조.

 


◆ HTTP Networking - Proxy

HTTP클라와 서버 두 컴퓨터 사이에서만 동작한다? ㄴㄴ

클라와 서버 사이에는 눈에 보이지않는 프록시 서버있다.

 

프록시 서버는 클라와 서버 사이에서 여러가지 기능을 제공한다.

ex)

  • 특정 사이트 접속 차단(Web Security) 기능
  • 캐싱 기능(한국에서 미국 서버에 컨텐츠를 요청했는데, 프록시 서버가 보고는 '어, 이 컨텐츠 한국 서버에도 있는데?' 하고 한국 서버의 컨텐츠를 주는 것. 응답 속도도 빨라지고 트래픽 양도 줄음)을 한다.
  • 네트워크가 느린 국가에서 유튜브를 접속할 때, 무작정 하이 퀄리티를 보내면 오래 걸리고 보기 힘들 것이므로, 퀄리티를 낮추어서 보내는 기능

 

→ 쉽게 말해 프록시 서버는 (클라와 서버 사이에서) 클라 요청을 받고, 적합하면 요청한 서버로 보내고, 그렇지 않으면 본인이 처리하는 역할을 한다.

 


◆ 대표적인 HTTP Methods

나열, 각각 기능 설명

GET

리소스 파일 요청

응답: 요청한 리소스를 제공함. 성공하면 응답코드 200 OK. 못 찾으면 404 NOT FOUND

 

 

PUT

리소스 파일 업로드

응답: 성공적으로 저장하게 되면 응답코드 201.

 

DELETE

업로드한 파일 삭제

 

POST

요청한 데이터 처리. 주로 등록에 사용

웹 브라우저에서 인풋 필드에 우편번호 집어넣고 우편번호 쓴 다음에 조회! 이런거 눌렀을 때 하는 처리.

 

응답: 성공적으로 처리를 완료하면 응답코드 201.

 

 

 

HEAD

파일의 헤더 정보 요청함.

GET하고 얼추 비슷하다. 응답도 거의 똑같다. 200 OK

그러나, 파일 통째로 줄 필요는 없고, 헤더 정보만 내놔! 라는 것

 

이런걸 가지고 뭘하느냐?

캐싱

If-modified-Since : 니가 나한테 무조건 파일을 줄 필요는 없어. 만약 파일이 언제 이후로 수정이 되어있다면 . 아니면 안줘도 돼.(이미 예전 거 갖고 있어)

 

 

 

 

TRACE

프록시의 정보를 확인해보고 싶을 때 사용. 주로 디버깅 용도로 이용

얘도 GET과 유사하게 동작한다.

만약 클라-서버 중간에 프록시 서버가 있으면,

프록시 서버를 거칠 때 "나는 proxy3.company.com이야. 지금 나를 경유해서 가고 있어" 라고 프록시 서버가 써준다.

이걸 서버가 받으면 그대로 본문에 적어서 클라에게 돌려준다.

 

이런 걸 보고 뭐가 문젠지, 뭐가 잘못된 건지, 뭘 조심해야 하는지 확인할 수 있다.

 

 

OPTIONS

서버가 어떤 메서드를 지원하는지 알려줌.

서버야 니가 뭘 지원하는지 다 보여줘~라고 하면,

서버가 "나는 GET POST PUT OPTIONS를 지원해!" 라고 알려줌

 

 


◆ 네트워크 프로그래밍의 변천사

클라투 서버, 서버투서버, 프로그램투서버로 넘어가는 이야기를 햇엇다.

11로 통신파이프를 열어놓고 바이트 단위로 주고받는 기법 에서 HTTP로 넘어옴.

 

Monolithic - 어떤 거대한 하나의 시스템이 있어서, 클라들이 그 시스템과 상호작용하는거.

- 컴퓨터 한 대가 굉장히 많은 기능들을 하는 것.

- 프로그램 하나를 짜기 위해서 수백~수천명이 기계적으로 일정 관리하면서 협업

 

초기에는, 보통 기업체에서 엄청 비싼 컴퓨터(서버)를 샀. 컴퓨터가 너무 비싸서, 비싼 거 하나 사서 여러 개를 네트워크로 연결하는 게 더 저렴했기 때문.

이때 여기에 연결하는 사용자들의 컴퓨터는 터미널이라 부름. 우리가 아는 터미널 처럼 생김.

이 터미널에다가 키보드 입력을 하면, 서버로 보내고, 서버가 처리한 후 다시 돌려주는 방식으로 작동했다. (클라-서버 구조).  

→ 한 컴퓨터와 상호 작용하기 때문에 데베 언어 통일, 개발 언어 통일해서 요청하고, 받고 하며 동작했다.

 

 

SOA – (서비스 중심으로) 쪼개짐. Service Oriented Architecture

- 컴퓨터 한 대에다가 모든 복잡한 기능을 다 때려박는 게 아니고, 네트워크를 통해 수많은 서버를 연결해서 쓰자

- 서버들을 쪼개서, 서비스 기능을 분할. 그들 간에는 통신을 통해 정보를 주고받도록 함.

- 처음 진행되었을 때에는 분할된 애들도 좀 덩치가 컸다.

 

이제는 HTTP나 통신 프로그램 등이 일반화되고, 컴퓨터가 저렴해졌다.

이제는 오히려 싸구려 인텔 씨피유 여러 개 합치니까 거대한 애 성능 나오네? 이렇게 된 것

(물론 돈이 있으면 강력한 거 하나가 성능적으로 나음. but 여러 개 합치는 방향이 더 가성비 굿)

 

Micoservices 

- 서비스 기능들을 더 잘게 쪼개서 수천수만대의 컴퓨터에 나누어서 넣음

- Serverless: 굉장히 작은 단위로 분할. 극단적으로, 함수 하나만 돌리는 컴퓨터의 느낌. 

- 수천-수만대 컴퓨터를 필요할 때 쓰고 필요없으면 없애는클라우드 컴퓨팅 개념도 등장

 

한번 쪼개지기 시작했더니 급속도로 쪼개지기 시작했다! 왜냐면.. 가지고 있는 컴퓨터의 개수가 엄청 많았기 때문. 구글같은 경우 200~300만개의 컴퓨터가 있음. 그래서 엄~~~~청나게 쪼개질 수 있는 거.

결국, 한 컴퓨터에서 함수 하나만 돌아가도 되는 지경에 이르렀다. 아이콘 내놓는 서버, 사진 내놓는 서버 .
API
주면, API를 주는 정도로 req-resp가 오가는 상황이 된 것.   Serverless. 굉장히 작아진 서버. 등장

 

굉장히 작게 쪼개짐. 그러다보니, 거대한 누군가를 접속하기 위해 가로질러야 했던 과거에서부터, 이제 옆에있는 Microservices 끼리 대화해야 되니까, 통신의 목적이 달라진 것. 옆에 애 하고 대화하고자 하는 쪽으로 바뀜.

 

DB언어나 개발 언어는, 옛날엔 통일했는데, 이제는 걍 서비스별로 다 다름. 팀별로 독자적으로 언어를 선택할 수 있고, 팀안에서도 언어를 나눠서 짜고 돌릴 수도 있고. 각각 속성에 최적화된 쪽으로 하면 되는 것.

그리고 작은 단위로 개발하고 돌아가다보니, 개발 시간도 단축되고, 업데이트도 엄청 빨라짐. 개발한 것도 우리팀꺼에만 합치면 되니까, 거대한거랑 합칠 필요는 없는것. → continuous하게 integration하고 delivery(출시).

 

마이크로서비스화되어있는데 서로쪼개져있는프로그램들 굳이 프로그래밍 언어를 통일할 필요가 없다!!!


◆ JSON 파일

 

JSON 등장 배경

처음에는 바이트 단위로 TCP통신을 했다.

그러다가, HTTP위에 XML을 주고받기 시작. HTML은 웹페이지 위에 문서를 보내는거고, XML은 좀더 확장한 느낌.  웬만한 문서들 다 표현 가능. 이걸통해서 서버야 니가 이런걸 수행해줬으면 좋겠어를 표현.

 

그런데 XML은 그림처럼 엄청 많은 태그들, 표현 방식, … 같은게 필요했다. (< 배꼽)

그래서 등장한 JSON: int, float, set, dict, string,…등을 표현할 수 있는 방식.

 

■ TCP때와 다른점?!

  • TCP: 바이트 단위로 보내.
  • SOA, RESTful : JSON으로 보내.  Int, float, set, dict, string등을 보내.
    → 주고받는 데이터의 형태를 지정해야 할 때 TCP에 비해 굉장히 쉬워짐.
    쉽게 얘기하면 소스코드 형식의 데이터를 보내도록 한 것.

 

< JavaScript로 개발하지 않은 앱과 서버들에서 JSON 형태의 데이터를 주고 받는 이유 >

기본적으로 웹 서버 개발 시 다루는 포멧이 JSON이다.

(클래스가 컴퓨터 메모리를 점유할 때 오브젝트인 것처럼, 자바스크립트가 객체를 표현하는 양식인 JSON을 사용해서 클라 투 서버, 서버 투 서버 통신을 하는 것)

 

그럼 자바 스크립트를 쓰는거임? ㄴㄴ. 자바스크립트에서 데이터를 표현한 그 방식 JSON만 쓰는 것임.

인터넷 발달하면서 JS언어가 확산되었고, 웹 브라우저는 보통 JS 번역기를 내장하기에 웹 서비스에서 유리함.

그러면서도 기본적인 프로그래밍 언어의 데이터 형태들(float, int, 등)을 지원하기 때문에 쓰기 편함.

따라서, JS로 개발하지 않은 앱과 서버들에서도  자바스크립트 객체로 변환할 수 있는 텍스트 형태를 주고 받으며 통신한다.

 

, 데이터만 실어나르는 것임. 메서드는 없음.

 

 

JSON 대표 함수

  • json.dump() : dict 데이타를 json 포맷 화일로 저장함  
  • json.load() : json 화일을 읽어서 dict 데이타로 변환홤
  • json.dumps() : dict 데이타를 json 포맷 문자열로 변화함  
  • json.loads() : json 포맷 문자열을 dict 데이타로 변환함

 


◆ REST 구조란?

HTTP를 기반으로 상대방의 기능을 호출하거나 데이터를 주고받는 철학.
(JSON보다는 좀 더 생산성을 높이고 개발이 용이하도록 하는 방향을 추구함) 

 

  • RESTful : REST를 좀 더 구체적인 형태로 세분화 한 것

REST 구조에 대한 제한 조건

  • 인터페이스 일관성)
    HTTP1.1은 온갖 메서드들을 자유자재로 사용해서 프로그래밍하는 건데, REST는 그래도 좀 더 일관적 형태를 갖춰야 하지 않겠어? 라는 권장사항.
  • 무상태)
    서버는 오직 현재 도착한 리퀘스트 정보만을 가지고 처리하며, 이를 저장해두지 않는다.
  • 캐시 처리 가능)
    클라이언트는 응답을 캐싱할 수 있어야 함. modified가 되었는지 아닌지 확인하여, 이미 이전에 그 결과를 가지고 있는 경우 캐싱해둔걸로 사용하는 방안.
  • 계층화)
    클라와 서버 사이에 중간 서버(ex: 프록시)들이 존재해도 잘 동작하도록 해야 함.
    중간에서 수많은 서버들에게 작업을 잘 분배할 수 있어야 함. (클라-프록시-서버라든지, 클라-프록시-프록시-서버 라든지 하는 계층 구조)
  • [옵션] Code on demand)
    전달하는 것이 프로그램일 수 있어야 함. (수업에선 안다룸)
  • 클라/서버구조)
    클라-서버 각 파트가 독립적으로 개선될 수 있도록 함.

 


◆ CRUD 원칙!?

HTTP 리퀘들을 Create, Read, Updae, Delete와 1:1 매핑하여 쓰는 것.

 

누군가(클라 또는 서버) 서버에게 HTTP 리퀘스트를 보낼 때, 해당 리퀘스트를 썼다면 다른 액션을 취하도록.

 

예를들어 다음과 같이 쓸 수 있음

  • POST: 새로운 데이터베이스 레코드인 것처럼 creation을 해줘라.
  • GET: (파일을 가져오는 게 아니라) 정보를 가지고 옴. Read.
  • PUT: 정보를 업데이트한다. (Write)
  • DELETE: Delete

 

이런것들이 쓰인 Url이나 body를 통해서, 추출하고자 하는 identifier같은걸 추출한다.

 

※ 예를 들어: http://localhost/ 서버를 다음처럼 개발할 수 있음

http://localhost/my_api/로 해서,
서버가 “my_api”에 대응해서 제공하는 기능을 호출함
더 이상 “my_api”는 원래 의미의 directory 개념이 아님  

http://localhost/my_api/{문자열} 처럼 HTTP Req를 Server에  보내면, 
서버는 {문자열}과 HTTP Req의 Body로 전달한 값을 입력  파라메타로 하여, 
GET/POST/PUT/DELETE에 상응하는 기능을 수  행하고, 결과를 Client에 리턴 하도록 할 수 있음

ex)
GET을 Read로 간주하여, {문자열}을 Key 값으로 하여, 서버의  record들을 찾아 대응하는 Value를 리턴
POST을 Create로 간주하여, {문자열}을 Key 값으로 하고, HTTP  Req의 Body에 해당하는 값을 Value로 하는 record를 생성

 


◆ RESTful API에서, CRUD란 무엇인가?

HTTP/1.1을 사용한다(광의).

JSON파일을 사용한다(협의).

CRUD원칙을 따른다

+) 여기서 추가로,

"우리 회사는 키값을 url로 받고, 세부정보를 body로 받고, body는 이렇게 처리하겠다!" 까지 갔을 때, RESTful.

REST 정신을 만족시키는 API인 것.

 

즉, CRUD 원칙을 회사가 구현할 수 있는 형태로 조금 더 구체화 한 것이 RESTful API.
(각각의 회사들이 이걸 어떻게 정의하는지에 대한 문서가 나와있다.)

 

 

※ RESTful API를 구현하는 간단한 예시: url을 건드리는 것.

예를들어 클라-서버 간 다음과 같은 약속을 하는 것이다.
Url 에 해당하는 주소가 있으면 파일이지만, 없으면 함수로 넘기도록 하자  → RESTful API
: 파일을 주고받는 게 아니라 대화를 하는 것임(정보를 주고받는 것). Url에다가 원하는 데이터를 집어넣음ㅇㅇ

 

'CS > 풀스택서비스네트워킹' 카테고리의 다른 글

8. HTTP/2  (0) 2023.12.08
7. gRPC  (0) 2023.12.08
5. ZeroMQ  (1) 2023.10.15
4. Socket  (0) 2023.09.30
3. OSI Arghitecture L4  (0) 2023.09.30
Comments