[HTTP] 2. URI와 웹 브라우저 요청 흐름
김영한님의 모든 개발자를 위한 HTTP 웹 기본 지식 강의를 듣고 정리했습니다.
(1) URI
URL
- Uniform Resource Identifier
- 리소스를 식별하는 통합된 방법
- URI는 로케이터(locator), 이름(name) 또는 둘 다 추가로 분류될 수 있다.
- URI, URL, URN
- URN은 대상의 이름 그 자체를 말하고, URL은 위치를 의미한다 URN과 URL을 합하여 URI라 한다.

- 우리가 일반적으로 웹 브라우저에서 사용하는 웹 사이트의 주소는 URL이다. URL을 이용하여 특정 이름을 부여할 수 있는데, 이를 URN이라 한다. 다만, URN과 URL이 매핑되어 있는 무언가가 없기 때문에 URN만을 가지고는 특정 웹사이트를 찾기 어렵다. 실생활에서는 거의 URL을 주로 사용하고 있다.

URL, URL, URN
URL
- Uniform : 리소스를 식별하는 통일된 방식
- Resource : 자원, URI로 식별할 수 있는 모든 것(제한 없음)
- 자원이란, 구분할 수 있는 모든 것을 의미한다
- 예) 웹 브라우저의 정적 파일, 실시간 교통 정보
- Identifier : 다른 항목과 구분하는데 필요한 정보
URL, URN
- URL - Locator : 리소스가 있는 위치를 지정한다.
- URL - Name : 리소스에 이름을 부여한다.
- 예) urn:isbn:9788966261208 (어떤 책의 isbn URN)
- 위치는 변할 수 있지만 이름은 변하지 않는다. 다만 URN 이름만으로 실제 리소스를 찾을 수 있는 방법이 보편화되지 않았다. 따라서 URL을 주로 사용한다.
URL
전체 문법
- scheme://[userinfo@]host[:port][/path][?query][#fragment]
- https://www.google.com:443/search?q=hello&hl=ko
- 프로토콜(https)
- 호스트명(www.google.com)
- 포트 번호(443)
- 패스(/search)
- 쿼리 파라미터(q=hello&hl=ko)
schema
- scheme://[userinfo@]host[:port][/path][?query][#fragment]
- 주로 프로토콜을 사용한다.
- 프로토콜 : 어떤 방식으로 자원에 접근할 것인지에 대한 클라이언트와 서버간의 약속 규칙
- 예) http, https, ftp 등
- https는 80 포트, https는 443 포트를 주로 사용하고, 포트는 생략 가능하다.
- https는 https secure를 의미하고, http에 강력한 보안을 추가한 것이다. 요즘에는 보통 https를 사용할 것을 권장한다.
userinfo
- scheme://[userinfo@]host[:port][/path][?query][#fragment]
- URL에 사용자 정보를 포함해서 인증해야할 때 사용한다. 요즘에는 거의 사용하지 않는다.
host
- scheme://[userinfo@]host[:port][/path][?query][#fragment]
- https://www.google.com:443/search?q=hello&hl=ko
- 호스트명에는 도메인명 또는 IP 주소를 직접 사용할 수 있다.
PORT
- scheme://[userinfo@]host[:port][/path][?query][#fragment]
- https://www.google.com:443/search?q=hello&hl=ko
- 포트 정보는 일반적으로 생략한다. 생략시 http는 80, https는 443이다.
- 특정 서버에 따로 접근하려고 한다면 포트 정보를 입력하기도 한다.
path
- scheme://[userinfo@]host[:port][/path][?query][#fragment]
- https://www.google.com:443/search?q=hello&hl=ko
- 리소스가 있는 경로이다.
- 계층적 구조로 되어있다. 디렉토리 경로처럼 되어있기도 하고, 컬렉션-하위 정보처럼 되어있기도 하다.
- 예)
/home/file.png,/members/100
query
- scheme://[userinfo@]host[:port][/path][?query][#fragment]
- https://www.google.com:443/search?q=hello&hl=ko
key=value형태로 되어있다.- query는 ?로 시작하고, &로 추가할 수 있다.
- ?keyA=valueA&keyB=valueB
- 웹서버에 제공하는 파라미터, 문자 형태이기 때문에 query parameter, query string 등으로 불린다.
fragment
- scheme://[userinfo@]host[:port][/path][?query][#fragment]
- https://docs.spring.io/spring-boot/docs/current/reference/html/getting-started.html#getting-started-introducing-spring-boot
- html 북마크 등에 사용하고, 서버에 전송되는 정보는 아니다.
- 사용 빈도가 높지는 않다.
(2) 웹 브라우저 요청 흐름
- 웹 브라우저에서 구글 서버로 요청을 보낸다.
- 먼저 DNS를 조회하여 IP 주소와 PORT 번호를 알아낸다. 그리고 HTTP 요청 메세지를 생성한다.

- HTTP 요청 메시지
GET /search?q=hello&hl=ko HTTP/1.1
Host: www.google.com
HTTP 메시지 전송
- 웹 브라우저가 HTTP 메시지를 생성한다.
- SOCKET 라이브러리를 통해 OS의 TCP/IP 계층으로 전달한다.
- TCP/IP 패킷이 생성되는데, HTTP 메시지를 포함한다.


- 웹브라우저에서 패킷을 인터넷 망에 던진다. 서버에 요청 패킷이 도착하면 서버는 TCP/IP 패킷을 제거하고 HTTP 메시지를 꺼내어 해석한다. 쿼리의 의미를 파악하고 그에 맞는 데이터를 찾는다.

HTTP 응답
- 클라이언트에서 요청한 데이터를 서버가 찾으면, 응답 패킷을 전달한다. 이때 HTTP 응답 패킷에는 HTTP 응답 메시지가 들어있다.

- HTTP 응답 메시지
HTTP/1.1 200 OK
Content-Type: text/html;charset=UTF-8
Content-Length: 3423
<html>
<body>...</body>
</html>
- 응답 패킷이 도착하면 웹 브라우저는 TCP/IP 패킷을 제거하고 HTTP 메시지를 읽는다. HTTP 메시지의 html을 읽어 렌더링을 하고, 사용자는 html 결과를 볼 수 있다.