kakasoo

[Network] 웹 브라우저가 HTTP 메시지를 만든다 (1) 본문

프로그래밍/네트워크

[Network] 웹 브라우저가 HTTP 메시지를 만든다 (1)

카카수(kakasoo) 2021. 1. 31. 17:15
반응형

 

이 글은 성공과 실패를 결정하는 1%의 네트워크 원리를 읽고, 스터디한 결과를 토대로 작성했다.

 

 


1장의 내용은 브라우저에 URL을 검색하게 될 때 URL을 해독하는 것부터 시작된다. 이 책의 내용은 브라우저에 검색을 했을 때, 네트워크가 어떻게 동작하는지를 실제 순서대로 담고 있다.

나중에 이 순서에 대해 자세히 설명할 수 있는지 스스로 물어보자.

  1. HTTP 리퀘스트 메시지를 작성한다.
  2. 웹 서버의 IP 주소를 DNS 서버에 조회한다.
  3. 전 세계의 DNS 서버가 연대한다.
  4. 프로토콜 스택에 미시지 송신을 의뢰한다.

01. HTTP 리퀘스트 메시지를 작성한다

1. 탐험 여행은 URL 입력부터 시작한다.

  • 브라우저는 몇 개의 클라이언트 기능을 겸비한 복합적인 클라이언트 소프트웨어 ⇒ 어떤 기능을 사용하여 데이터에 접근하면 좋을 것인지 판단할 재료가 필요 ⇒ HTTP, FTP 등의 프로토콜이 마련됨.
    • HTTP, FTP 등의 프로토콜은 어떤 방법으로 접근할 것인가를 의미한다.

2. 브라우저는 먼저 URL을 해독한다

http: + // + [www.lab.cyber.co.kr](<http://www.lab.cyber.co.kr>) + / + dir1 + / + file1.html

3. 파일명을 생략한 경우

파일 명을 작성하지 않으면 그 폴더의 index.html로 접근한다. 이런 default 설정은 서버에서 미리 설정해둘 수도 있다. (과거에는 이걸 home page 라고 불렀지만, 지금은 보편적으로 쓰는 말이 되었다.)

주소 끝에 /를 생략하는 것도 이제는 정상적인 방법으로 인정되고 있다. 하지만 이렇게 되면 폴더인지 파일인지 구분할 수 없게 된다. 이 경우에는 웹 서버가 가진 리소스가 폴더인지 파일인지를 직접 찾게 한다.

( 동시에 같은 이름을 가진 파일, 폴더가 존재할 수 없기에 가능한 방법 )

4. HTTP의 기본 개념

HTTP 프로토콜은 클라이언트와 서버가 주고받는 메시지의 내용이나 순서를 정한 것

  1. 먼저 클라이언트에서 서버를 향해 리퀘스트 메시지를 보낸다. 리퀘스트 메시지에는 무엇을, 어떻게 하겠다는 내용이 쓰여 있다. 여기서 무엇에 해당하는 것이 URI이다. 어떻게 하겠다는 내용이 메서드이다.
  2. 리퀘스트 메시지가 웹 서버에 도착하면 웹 서버는 그 내용을 해독하여 결과 데이터를 응답 메시지에 저장한다. 응답 메시지에는 스테이터스 코드가 있다.
  • 메서드에는 GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE, CONNECT 등이 있다.
    • OPTIONS 는 통신 옵션을 통지하거나 조사할 때 사용
    • CONNECT 는 암호화된 메시지를 프록시로 전송할 때 이용
    • PUT는 멱등, PATCH는 비멱등.

5. HTTP 리퀘스트 메시지를 만든다

  1. 리퀘스트 메시지의 첫번째 행의 리퀘스트 라인을 작성한다. 이는 메서드 + 공백 + URI + 공백 + HTTP 버전으로 이루어져 있다.
  2. 두번째 행부터는 메시지 헤더가 들어간다. 메시지 헤더는 날짜, 클라이언트 측이 취급 가능한 데이터의 종류, 언어, 압축 형식, 클라이언트나 서버의 소프트웨어 명칭과 버전 등 세세한 내용이 담긴다.
  3. 메시지 본문이 끝나면 공백 라인을 하나 두고 메시지 본문을 작성한다. 메시지 본문은 메시지의 실제 내용으로, 메서드가 GET 인 경우에는 아무것도 없다.

6. 리퀘스트 메시지를 보내면 응답이 돌아온다.

  • 응답도 리퀘스트 메시지와 유사한 형태로 작성된다.
  1. 리퀘스트의 실행 결과를 나타내는 스테이터스 코드와 응답 문구를 첫 번째 행에 써야 한다.
    • 스테이터스 코드는 백의 자리에 따라 용도가 다른데, 1인 경우에는 처리 및 경과 사항, 2인 경우에는 정상 종료, 3인 경우에는 무언가 다른 조치가 필요함, 4인 경우 클라이언트 측 오류, 5는 서버 측 오류를 뜻한다.
  2. 리퀘스트 메시지에 쓰는 URI는 한 개 뿐이므로 메시지 한 개에 파일 1개만을 읽을 수 있다. 따라서 문장 1개, 이미지 3개인 경우에는 총 4번의 트랜잭션이 필요하다.
  3. 이렇게 데이터를 받아서 표시하는 것이 클라이언트 (브라우저)의 역할이다. 서버에서는 달라는 대로 줄 뿐이지 그것이 어떻게 쓰이는지에 대해서는 신경쓰지 않는다.

의문점 및 추가 사항

  1. PUT과 PATCH의 차이
  2. OPTIONS, CONNECT
  3. 스테이터스 코드가 3인 경우 무언가 다른 조치가 필요하다는 의미 ⇒ 리다이렉션 코드
  4. 다른 프로토콜 (FTP, MAILTO...)은 왜 사용하지 않는가?
    • HTTP 완벽 가이드에 나온 내용을 아래와 같이 요약해두었다.
    • 2.1.1 URL이 있기 전 암흑의 시대
    • FTP는 사용자와 패스워드, 내용을 평문으로 저장하기 때문에 보안 상 매우 취약하다고 한다. ( 개인 용도로 사용하는 경우가 있는 걸로 보아, 현재 기준으로도 속도는 빠른 편인 것 같다. )
    • mailto의 경우는 스팸 메일 목적으로 이메일을 수집하는 크롤러들 때문에 기피하고 있다고 한다. ( 이것도 더 찾아봐야 할 듯 하다. )

02. 웹 서버의 IP 주소를 DNS 서버에 조회한다.

1. IP 주소의 기본

HTTP의 메시지가 완성되면 이것을 OS에 의뢰하여 액세스 대상의 웹 서버에게 송신한다. 브라우저는 URL을 해독하거나 HTTP 메시지를 만들 수는 있지만 네트워크에 송출하는 기능이 없기 때문이다.

~~이 때, HTTP 요청을 보낼 때는, OS는 도메인 명이 아니라 IP 주소로 상대를 '특정'하기 때문에 브라우저는 도메인 명에서 IP 주소를 특정해줄 필요가 있다.~~

→ 나중에 다시 정리할 것.

→ HTTP 요청을 보낼 때 어떤 것으로 도메인 명인가 IP 주소인가, 그러한 문제에 대해서는 모두 OS에 위임한다고 보는 게 타당하다. 이러한 기능이 오직 OS에만 있기 때문이다.

이를 설명하기 위해서는 TCP/IP에 대해서 이해할 필요가 있다.

1.1 TCP/IP

서브넷이라는 작은 네트워크를 라우터에 접속하여 전체 네트워크를 만든다.

여기서 서브넷이란 허브에 몇 대의 PC가 연결된 망을 의미한다. ⇒ 서브넷 = 허브 + 몇 개의 PC

이 서브넷들이 지닌 각각의 허브들을 라우터에서 연결해주면 네트워크 전체가 완성된다.

컴퓨터를 ㅇㅇ동 ㅇㅇ번지 라는 형태로 주소를 할당한다고 할 때 동에 해당하는 번호를 서브넷에 할당하고, 번지에 해당하는 것을 컴퓨터에 할당한다. 이렇게 네트워크의 주소를 만들 수 있다.

이 때, 동 번호를 네트워크 번호, 번지에 해당하는 것을 호스트 번호라 한다. 이 두 주소를 합치면 IP 주소가 된다.

액세스 대상의 서버까지 메시지를 운반할 때에는 이 IP 주소를 따라 액세스 대상의 위치를 판단하고 운반한다. 송신 측이 메시지를 보내면 허브가 운반하고 가장 가까운 라우터까지 도착한다.

라우터는 그럼 다시, 다음 번 라우터를 탐색하여 거기에 메시지를 보내도록 지시한다. 이 과정을 반복하면 상대의 데이터가 도착하게 된다.

1.2 실제 IP 주소

실제 IP 주소는 32비트의 디지털 데이터이며, 이것을 8비트 씩 점으로 구분하여 10진수로 표기한다. 이렇게 되면 어디서부터 어디까지 네트워크 번호고 호스트 번호인지 알 수 없기 떄문에 넷마스크를 같이 준다.

넷마스크는 똑같이 32비트로 이루어진 수이며, 네트워크 주소인 지점까지는 전부 1, 호스트 번호인 지점까지는 전부 0으로 표기한 숫자이다.

이 때, 실제 IP 주소에서 호스트 번호를 전부 0으로 바꾸면 서브넷을 나타내는 번호가 되고, 전부 1로 바꾸면 서브넷 전체에 대한 브로드캐스트가 된다.

브로드캐스트란 서브넷에 있는 전체 기기에 데이터 패킷을 보내는 것을 의미한다.

2. 도메인 명과 IP 주소를 구분하여 사용하는 이유

일단 IP 주소를 외우는 것보다는 쉽다. ⇒ 그러면 전부 도메인명으로 통일하는 게 낫지 않을까? ⇒ IP주소는 32비트(4바이트)인데 도메인 명은 최대 255바이트까지 있어서 실행 효율이 낮다.

고성능 라우터를 쓰면 되지 않을까? ⇒ 라우터의 속도에는 한계가 있다, 라우터의 성능은 발전하고 있지만 데이터의 양 역시 빠르게 증가하고 있다.

도메인 명을 알면 IP 주소를 알 수 있고, IP 주소를 알면 도메인 명을 알 수 있으면 이 둘을 구분함으로써 생기는 문제를 해결할 수 있는데, 이 원리가 DNS이다.

3. Socket 라이브러리가 IP 주소를 찾는 기능을 제공한다

DNS Server에 특정 도메인 명의 IP 주소를 알려달라고 요청하면 DNS Server는 그 도메인의 IP 주소를 돌려준다. 그러면 브라우저에서 DNS 서버는 어떻게 조회할 수 있을까?

DNS 서버에 조회한다는 것은 DNS 서버의 클라이언트가 된다는 말과 같다. 이 때 DNS 클라이언트를 DNS 리졸버 또는 리졸버 라고 부른다. DNS 원리를 사용하는 것을 네임 리졸루션 또는 이름 확인 이라고 한다.

리졸버는 Sokcet 라이브러리 ( 라이브러리가 무엇인지에 대해서는 생략한다 ) 에 있는 부품화된 프로그램인데, Socket 라이브러리는 OS에 포함되어 있는 네트워크 기능을 애플리케이션에서 호출하기 위해 부품을 모아놓은 것이다.

4. 리졸버를 이용하여 DNS 서버를 조회한다

gethostbyname과 웹 서버의 이름을 사용하면 바로 리졸버를 호출할 수 있다. 브라우저가 OS에 의뢰하면 이렇게 하여 IP 주소를 알아내고, 그것을 브라우저가 지정한 메모리에 올려준다.

5. 리졸버 내부의 작동

리졸버를 호출하면 제어가 리졸부 내부로 넘어 간다. 리졸버는 의뢰받은 작업을 실행한다. 이는 DNS 서버에 문의하기 위한 메시지를 만들고 보내는 것을 의미한다.

송신 동작은 리졸버가 실행하는 것이 아니라, OS 내부에 포함되어 있는 프로토콜 스택을 호출하여 실행을 의뢰한다. 리졸버도 브라우저와 같이, 네트워크에 대해 데이터를 송수신하는 기능은 없기 때문이다.

OS 내부의 프로토콜 스택에서 UDP 메시지를 송신, DNS 서버를 거쳐 다시 수신받으면, 그것을 이제 Socket에게 돌려준다.

Socket은 응답 메시지에서 IP 주소를 추출하여 메모리에 저장하고, 애플리케이션으로 제어를 돌려준다.

이 과정이 전부이다.

여기서, DNS 서버에 메시지를 보낼 때도 DNS 서버의 IP 주소가 필요한데, 이 IP 주소는 컴퓨터에 기본적으로 미리 설정되어 있다.

의문점 및 추가 사항

  1. 허브랑 라우터의 구분 (57P를 보면 허브 위레 라우터가 있기도 하고, 라우터 위에 허브가 있기도 하다.)

  2. socket.io 와 websocket의 차이

    • 아래는 NAVER D2에서 둘의 차이를 간단히 서술한 글이다.
    • socketio 홈페이지를 참고하면, websocket은 전체 브라우저의 97% (2020년 기준)에서 사용이 가능하다고 한다, 다만 그것과 별개로 아직까지는 잘 쓰이지 않는 미래의 기술인 것 같다.

    NAVER D2

최종 정리

웹 브라우저에 URI ( 보통은 URL ) 을 입력하면, 브라우저는 OS에게 이 URI에 해당하는 서버 IP를 찾아서 자신의 메시지를 보내달라고 의뢰한다.

이를 위해서는 일단 URI가 무엇인지, 메시지는 어떻게 만들어지며 어떤 내용을 담고 있는지, 그리고 OS는 어떻게 URI에 해당하는 IP를 찾을 수 있는 것인지를 알아야겠다.

URI는 일단 URL과 URN으로 이루어져 있다. 이는 Uniform Resource Identifier의 약자인데, 이 안에 URL (Uniform Resource Location) 과 URN (Uniform Resource Name)이 들어 있다.

URL은 서버가 가지고 있는 리소스들 중 그 위치에 따라 지칭이 달라지는 것을 의미하며, URN은 위치와 상관없이 이름이 일정한 경우를 의미하는데, 아직까지는 URL이 대부분을 차지하기에 URL를 URL로 통칭하는 경우가 많다.

따라서 URL은 서버가 클라이언트에게 제공하는 리소스라고 할 수 있겠다.

URL은 프로토콜 이름과 호스트의 이름, 리소스의 위치를 지니고 있으며, 사용자나 패스워드 등의 내용을 선택적으로 추가할 수 있다.

URL이 무엇인지 알았다면 다음으로는 HTTP 메시지에 대해서 알아보자.

HTTP 메시지의 첫줄에는 리퀘스트 라인, 그 다음 줄에는 헤더, 그리고 공백라인을 두고 본문을 가지고 있다. 리퀘스트 라인은 프로토콜과 호스트명, 프로토콜 버전을 가지고 있다.

리퀘스트는 서버로부터 어떠한 행동을 해줄 것을 요청하는 것을 말하며, 서버는 요청을 받을 시 응답 메시지를 보내준다.

응답 메시지도 리퀘스트와 유사한 구조로 되어 있다.

마지막으로 OS가 어떻게 URL를 찾을 수 있는지를 보자,

OS는 다른 소프트웨어와 달리 데이터를 송수신할 수 있는 기능을 가지고 있기 때문에 모든 어플리케이션으로부터 데이터를 보내고 받는 것을 의뢰받는다, 이 때 의뢰를 받게 되면 OS는 브라우저로부터 URL을 전달받는다.

Q1. URL만을 사용하지 않는 이유는?

Q2. IP만을 사용하지 않는 이유는?

OS는 알아낸 HOST의 IP를 가지고, DNS 서버의 클라이언트, 즉 리졸버의 역할을 하게 된다. 이 경우도 역시 DNS 서버의 IP 주소를 알아야 하겠지만, DNS 서버의 IP는 모든 컴퓨터에 기본적으로 내장되어 있다.

리졸버가 된다는 것은 OS는 그러면 socket 라이브러리를 사용하는 것을 의미하는데, 이 라이브러리에서 gethostnameby() 함수와 URL을 가지고서 HOST의 IP를 알아낼 수 있다.

즉 동작 순서는 아래와 같다.

  1. 브라우저가 OS에 요청
  2. OS는 DNS 서버의 클라이언트 (또는 리졸버)로써, 서버 측의 IP 주소를 요청.
  3. OS가 알아낸 IP 값을 브라우저가 지정한 메모리에 할당.
    • 브라우저가 아닌 다른 애플리케이션도 동일한 방식으로 동작한다.

스터디를 통해 알게 된 것

  1. 브라우저 자체는 싱글 스레드가 아니다.
  2. DNS 자체도 프로토콜이다.
반응형