백앤드(스프링)

HTTP 총 정리 1편

유승혁 2022. 2. 23. 23:54

 아휴 요새 알고 공부에 정신이 없다.. 오랜만에 개발 글 쓰기..

 알고 공부 틈틈이 시간이 좀 난다 싶으면 http 부분을 공부 했는데 인터넷에 자료도 많이 있어 간단하게 정리 해보고자 한다. 

  크게 6가지로 나뉠 것이여 URL(URI) / HTTP 성질 / HTTP 구조 / HTTP 메서드 / HTTP 상태 코드 / HTTP 헤더

이렇게 나뉘고 다룰 내용도 간단간단 쓸모 있는 것만 모아모아 이야기 해보겠다. 그럼에도 양이 많아 나누어 글을 올려야 겠다..ㅋㅋㅋ 

 

 1. URI

 URI와 URL 둘 다 흔히 들어 보았을 말인데 사실 상 같은 것이라 보아도 무방하다. 정확히는 URI라는 것이 URL과 URN을 포함하고 있는 것인데 URN 자체를 잘 안쓰게 되어 URI와 URL은 같게 되었다. 그래서 혼동하면서 쓰겠다. 

 아무쪼록 URI가 무엇이냐면 링크라고 생각 할 수 있는데 정확히는 각 파일(리소스)의 위치라고 생각하면 된다. 예를 들어 내 바탕화면에 프랑스 폴더에 얼음 왕자인 나의 초상화들이 있다고 하고 사람들에게 보여주고 싶다면 내 호스트 명과 이 위치 등등을 통해 만든 조합이 URI. 이 URI를 타고 들어오면 내 초상화들이 있다. 이 초상화들이 리소스들이다. 

 URL은 다음과 같이 나뉜다.

URL

 위 줄은 형식이고 아래 줄은 예시이다. 각각을 설명하자면~~

 1. scheme : 프로토콜을 칭함. 어떤 방식으로 자원에 접근 할 건데? http, ftp smtp 같은 것! 컴네 글에서 다루었당

 2. userinfo : URL에 사용자 정보를 포함해서 인증. 몰라도 돼

 3. host : 호스트 명. 즉 도메인 명이나 IP 주소 구글 처럼

 4. port : 443이 위의 예시. 포트도 컴네에서 이야기했으니 패스! 참고로 http(80) https(443)

 5. /path : 리소스 경로. 잘 아시다시피 계층적 구조를 띔

 6. query : key = value 형태로서 마치 함수의 인자 느낌이라 생각하면 될 듯! 즉 같은 리소스의 위치라 하더라도 다른 옵션을 주면 다른 결과를 내는 형식

 7. fragment : html 내부 북마크 같은 것으로 사용. 서버에 전송하는 정보가 아니다~

 

컴네 글에서 5계층을 거쳐 패킷으로 바뀌어 데이터가 전송 된다고 했다. HTTP 또한 마찬가지 이 HTTP가 패킷에 들어갈 때 형식이 존재하는데 이에 맞게 바뀐 것을 메시지라고 한다. HTTP 요청 메시지 - HTTP 응답 메시지 처럼. 당연히 이 부분을 다룰 것인데 이것은 잠시 후에~ ㅎㅎ

 

 

 

 2. HTTP의 성질

 HTTP는 여러 버전이 있는데 대채적으로 1.1 / 2 / 3 버전이 있다. 현재로서는 대게 1.1을 사용하는데 최근에는 2버전, 3버전도 늘어가는 추세이다. 재밌는 것은 컴네에서 다루었듯이 HTTP는 TCP 기반이라 했는데 3버전은 UDP 기반이다. TCP의 한계를 뛰어 넘어 상당한 속도 향상을 보이고자 하는 노력이... 너무 감사하다!

 특징으로는 크게 2가지 이다!

 

 2.1 클라이언트 서버 구조

  말 그대로 클라이언트는 요청 메시지를 서버에게 보내고 서버는 그것에 맞는 응답을 보내준다.

 

2.2 stateless, 비연결성

 먼저 statefull 과 stateless를 비교하자면

                                statfull                                stateless
 A : 안녕 난 프랑스에서 왔어
 B : 넌 프랑스에서 왔구나

 A : 난 왕자야
 B : 넌 프랑스 왕자구나!
 
 A : 난 얼음 마법을 써
 B : 넌 프랑스 얼음 왕자구나!
 A : 안녕 난 프랑스에서 왔어
 B : 넌 프랑스에서 왔구나

 A : 난 왕자야
 B : 넌 왕자구나!
 
 A : 난 얼음 마법을 써
 B : 넌 얼음 마법사구나!

  즉, B가 A의 정보를 기억해서 앞으로의 대화에 써먹는 것이 statefull 이고 기억하지 못하면 stateless 처럼 되는 것이다. 

 어? statefull이 훨씬 낫네 그럼 http는 statefull? Hmm Jun Hyu Ani Ya!

 만약 statefull을 가져가게 되면 하나의 서버는 하나의 클라이언트와 1대1로 계속 대응 해야만 한다. 그렇다면 접속자가 많아지면 그에 맞게 1대 1로 만들어야 하는데 만약 못된 100만명의 사람이 접속만 하고 아무것도 안하면,,, 자원이 너무 아까워 진다. 그래서 무상태를 추구한다. 그럼 어떻게 대화를 하느냐?

 

 A : 안녕 난 프랑스에서 왔어
 B : 넌 프랑스에서 왔구나

 A : 난 프랑스에서 온 왕자야
 B : 넌 프랑스 왕자구나!
 
 A : 난 프랑스에서 온 왕자인데 얼음 마법을 써
 B : 넌 프랑스 얼음 왕자구나!

 

 짠! 즉 클라이언트가 이전 정보를 포함해서 함께 요청 메시지를 보내는 방식이다. 이렇게 하면 응답 서버를 계속 바꾸어도 서버 간에 인수인계 할 필요가 없어진다. 상당히 이득! 중간에 서버 하나가 장애가 나거나 요청자가 몰려도 요청 메시지를 응답해야 하는 순간 순간에만 맞게 서버를 할당해 응답해 주면 된다. 이렇게 되면 확장 가능 성이 무궁무진하다. 아무 서버로 교체가능하니 말이다. 구현은 어렵겠지만,,, 말야... 세상에 쉬운건 없어(절레절레)

 하지만 한계가 있다. 모든 것을 무상태로는 할 수 없어. 왜냐면 로그인 정보 같은 것은 계속 유지를 해야만 한다. 사실 이 부분은 서버 세션이나 브라우저 쿠키를 이용하여 최소한의 상태 유지를 노린다.

 

 비연결성은 위에서 예시와 함께 눈치로 알 수 있을 것인데 클라이언트와 서버간에 연결을 유지 하지 않는데 그 말인 즉슨, stateless 는 이전 정보를 기억 하지 않는 다는 것이고 비연결성은 응답 메시지를 보내면 연결을 끊어 버린다. 마치 대답만 하고 뒤를 돌아버리는 그대의 모습처럼.....★

 이렇게 하는 이유는 클라이언트 3개가 있고 하나의 서버에게 요청이 오고 각각의 클라이언트는 10개의 요청을 보낼 것인데 만약 연결성을 취한다면 첫 번째 클라이언트의 10개 요청 처리하고 두번째.. 세번째.. 이러면 세번째는 얼마나 기다리는 겨!

 그래서 각각 총 30개의 요청을 올 때마다 처리하고 바로 연결을 끊어 버려서 억울한 클라이언트를 최소한으로  줄여버린다!

 이것이 얼마나 대단한 것이냐면 실무에서 1시간 동안 수천명이 서비스를 이용해도 실제 필요한 서버의 수는 수십개의 단위라고 한다. 물론 TCP를 이용하다보니 3-way 악수 때문에 요청 시간이 오래 걸릴 것이지만,, 이를 최적화 하기 위해 많은 노력을 해주고 있다. 예로 HTTP 지속 연결이 있는데 컴네 글에서 다루었고 인터넷에도 널려있드아..

 

 

 

 

 3. HTTP 구조

 HTTP 프로토콜은 정말 훌륭하도다! 모든 파일들을 다 보낼 수 있기 때문이지! 그래서 우리도 정말 많이 쓰잖아~! HTML, TEXT, Img, 음성, 영상, 파일, JSON, XML 등등 아주 든든하고 유용한 도구이다!

 위에서도 잠깐 언급한 이 메시지는 크게 두 가지가 있다고 했다. HTTP 요청 메시지와 HTTP 응답 메시지. 그 중 응답 메시지로 어떠한 구조를 띄고 있는 지 설명하겠다. 각 구조에 대해 형식(문법)들은 다루겠으나 각 형식에 무엇을 넣는지(단어)들은 아마 다음 글에..? ㅎ

HTTP 메시지 형태

  3.1 시작라인

 HTTP 요청 메시지 : / 를 기준으로 request-line과 status-line으로 나뉜다. request-line 은 method를 가리킨다. 위의 사진에서는 GET메서드. (메서드는 다음 글에서) request-line은 리소스의 절대 경로와 파라미터를 넘겨준다. 마지막에는 HTTP 버전이 들어간다. 메서드와 경로 사이에 space, 경로와 http 버전 사이의 space 마지막 버전 뒤에는 CRLF(엔터) 가 굉장히 중요하다! 필기 하도록 ㅎㅎ

 

 HTTP 응답 메시지 : 예시 사진에도 보이듯이 간단하게 http 버전과 상태 코드가 있다 2xx~5xx까지 있고 그 옆에는 그 상태 코드에 대한 짧막한 설명이다..  OK 너무 짧막해 ㅋㅋㅋ

 

 3.2 header

  구조는 다음과 같다 header-field = field-name ":" (OWS) field-value (OWS) 로 이루어 져있고 OWS 는 공백 생략 가능 하다는 의미이다. 또한 field-name은 대소문자 구분이 없어 위의 예시에서 HOST: www.google.com  처럼 할 수 있다. 단 정말 중요한 것은 field-name 뒤 ':' 사이에 공백이 절대 있어서는 안된다. 

 이 헤더는 전송에 필요한 부가 정보이다. 상대방이 해석할 때 도움을 줄만한 요소들이라 볼 수 있다. html인지 file인지 총 용량은 얼마인지, 어떤 방식으로 message body 를 읽으면 되는 지 등등

 게다가 사용자 간의 약속된 헤더를 추가 할 수도 있다. http3의 UDP 기반에서 상당히 유용하게 쓰일 것 같다.

 

 3.3 HTTP 메시지 바디

 실제 전송할 데이터. 당연!

 

 

 마무리

 첫번째 정리글은 여기까지!  HTTP의 전반적인 컨셉과 구조를 다루어 보았다. 아마 다음 글은 상태 코드와 메시지들 처럼 각 구조를 자세히 다루어 보겠다. 내일 ,, 아님 , 내일 모레..?

 암튼 여기까지 느낀 것은 HTTP는 상당히 쓸모있는 포멧이라는 거~ 확장 가능성도 무궁무진하고~~

게다가 UDP 기반인 HTTP 3버전은 정말 어떠한 모습일지 기대가 된다. 훗날 나오겠지만 말야. 정말 세상엔 똑똑한 사람들이 많다. 너무나도 고맙다. 인류애가 넘쳐난다!!