이번 주는 응용 계층 챕터의 내용을 읽고, 문제를 풀어보았다.
1. DNS와 자원
1.1. 도메인 네임과 네임 서버
1.2. 네임 서버 관리 방법
1.3. DNS
1.3.1. 계층적 네임 서버
1.4. 도메인 네임 리졸빙 과정
1.5. 자원을 식별하는 URI
1.5.1. URL
1.5.2. URN
2. HTTP
2.1. HTTP의 특성
2.2. HTTP 메세지 구조
2.3. HTTP 메서드
2.4. HTTP 상태 코드
3. HTTP 헤더와 HTTP 기반 기술
3.1. HTTP 헤더
3.1.1. 요청 시 활용되는 HTTP 헤더
3.1.2. 응답 시 활용되는 HTTP 헤더
3.1.3. 요청, 응답 모두에서 활용되는 HTTP 헤더
3.2. 캐시
3.2.1. 캐시 신선도
3.2.2. 캐시 신선도를 재검사하는 방법
3.3. 쿠키
4. 후기
1. DNS와 자원
해당 소단원의 문제는 아래와 같다.
도메인 네임과 네임 서버에 대한 설명으로 옳지 않은 것을 골라 보세요.
1) 8.8.8.8은 대표적인 공개 DNS 서버로, 구글이 관리합니다.
2) 도메인 네임은 호스트를 특정할 수 있는 문자열 형태의 정보입니다.
3) DNS는 계층적이고 분산된 도메인 네임에 대한 관리 체계이자 이를 관리하는 프로토콜입니다.
4) www.example.com에서 루트 도메인은 com에 해당합니다.
여기서 정답은 4)로, 루트 도메인은 .으로 표현되고 com은 최상위 도메인이다.
해당 정답과 풀이를 이해하기 위해 내용을 정리해보자.
1.1 도메인 네임과 네임 서버
호스트를 특정하기 위해 IP 주소만 사용하는 것은 호스트의 IP 주소의 변경 가능성과 모든 호스트의 IP 주소 기억이 번거롭기 때문에 도메인 네임과 네임 서버도 사용한다.
* 도메인 네임
= 호스트의 IP 주소와 대응되는 문자열 형태의 호스트 특정 정보.
(www.example.com, git.kernel.org)
= IP 주소에 비해 기억하기 쉬움.
= IP 주소가 변경되어도 바뀐 주소에 도메인 네임을 다시 대응하면 되므로 IP 주소만으로 호스트를 특정하는 것보다 간편함.
* DNS 서버
= 도메인 네임을 관리하는 네임 서버.
= 도메인 네임을 해당 서버에 질의할 경우, 해당 도메인 네임의 IP 주소를 받을 수 있다.
1.2. 네임 서버 관리 방법
도메인 네임의 구조를 통해 네임 서버를 어떻게 관리하는지 알아보자.
* 도메인 네임 구조
ex) www.example.com
= 점을 기준으로 계층적으로 분류한다.
위 예시를 분류해보면 아래와 같다. (일반적으로 3~5단계 정도로 도메인 단계를 설정한다.)
www.example.com. : 전체 주소 도메인 네임(FQDN, Fully-Qualified Domain Name)
www : 3단계 도메인 / 호스트 네임(FQDM, 네트워크 장치 자체의 이름을 가리키기도 함)
example : 2단계 도메인
com : 최상위 도메인
. : 루트 도메인
(++ 여기서 루트 도메인은 도메인 네임 마지막에 .으로 표기되지만, 일반적으로 생략해서 표기되어서 최상위 도메인이 도메인 네임의 마지막 부분으로 간주된다.)
1.3. DNS
도메인 네임은 계층적인 형태를 띠고, 역시 도메인 네임 서버 또한 계층적인 형태를 이룬다.
* DNS(Domain Name System)
= 계층적이고 분산된 도메인 네임에 대한 관리 체계이자 이를 관리하는 프로토콜.
(++ 서브 도메인 : 다른 도메인이 포함된 도메인)
1.3.1. 계층적 네임 서버
네임 서버의 구조를 통해 리졸빙(resolving, IP 주소를 모르는 상태에서 도메인 네임에 대응되는 IP 주소를 알아내는 과정)되는 과정을 알아보자.
* 네임 서버의 종류
- 로컬 네임 서버(local name server)
= 클라이언트와 맞닿아 있는 네임 서버로, 클라이언트가 도메인 네임을 통해 IP 주소를 알아내고자 할 때 가장 먼저 찾게 되는 네임 서버.
= 주소는 일반적으로 ISP에서 할당해주지만, 공개 DNS 서버에서 할당받기도 함.
(공개 DNS 서버 : 8.8.8.8, 8.8.4.4, 1.1.1.1..etc)
- 루트 네임 서버(root name server)
= 루트 도메인을 관장하는 네임 서버로, 질의에 대해 TLD 네임 서버의 IP 주소를 반환할 수 있음.
- TLD 네임 서버
= TLD를 관리하는 네임 서버.
= 질의에 대해 TLD의 하위 도메인 네임을 관리하는 네임 서버 주소를 반환 가능함.
- 책임 네임 서버(authoritative name server)
= 특정 도메인 영역(zone)을 관리하는 네임 서버.
= 자신이 관리하는 도메인 영역의 질의에 대해 다른 네임 서버에게 넘기지 않고 곧바로 답할 수 있는 네임 서버.
(로컬 네임 서버가 마지막으로 질의하는 네임 서버.)
=> 전체적으로 계층적인 구조를 띠고 있음.
1.4. 도메인 네임 리졸빙 과정
도메인 네임을 리졸빙하는 과정들에 대해 알아보자.
* 재귀적 질의(recursive query)
= 클라이언트가 로컬 네임 서버에게 도메인 네임을 질의 -> 로컬 네임 서버가 루트 네임 서버에게 질의 -> 루트 네임 서버가 TLD 네임 서버에게 질의 -> TLD 네임 서버가 다음 단계에 질의하는 과정
= 위 과정을 반복하며 최종 응답 결과를 역순으로 전달받는 방식.
* 반복적 질의(iterative query)
= 클라이언트가 로컬 네임 서버에게 IP 주소를 알고 싶은 도메인 네임을 질의 -> 로컬 네임 서버는 루트 도메인 서버에게 질의하여 다음으로 질의할 네임 서버의 주소를 응답받음 -> TLD 네임 서버에게 질의해서 다음으로 질의할 네임 서버의 주소 응답받음
= 위 과정을 반복하다가 최종 응답 결과를 클라이언트에게 알려줌.
* 위 과정의 문제점
= 시간이 오래 걸림.
= 네트워크상 메세지 수가 지나치게 늘어남.
* 해결책
= DNS 캐시(네임 서버들이 기존에 응답받은 결과를 임시로 저장한 데이터. 추후 같은 질의에 이를 활용함.)를 이용.
(TTL(Time To Live)와 저장되어 해당 시간동안 캐시 가능하게 설정)
1.5. 자원을 식별하는 URI
송수신하고자 하는 정보를 식별하기 위한 방식에 대해 알아보자.
(++ 자원 : 네트워크상의 메세지를 주고받는 대상으로, 두 호스트가 네트워크를 통해 정보를 주고받을 때 송수신하는 대상이다.)
(++ 대부분의 통신은 HTTP 기반으로 이루어져서 HTTP 요청 메세지의 대상이라 불리기도 한다.)
* URI(Uniform Resource Identifier)
= 자원을 식별할 수 있는 정보.
= 위치를 이용해 자원을 식별하는 방법을 URL, 이름을 이용해 자원을 식별하는 방법을 URN이라 한다.
1.5.1. URL
일반적으로 인터넷 환경에서 자원 식별에 더 많이 사용되는 방법이다.
예시를 보면서, URL 표기 방법을 알아보자.
ex) foo://www.example.com:8042/over/there?name=ferret#nose
foo:// : scheme
www.example.com:8042 : authority
over/there : path
?name=ferret : query
nose : fragment
scheme : 일반적으로 사용할 프로토콜 명시.
authority : 호스트를 특정할 수 있는 정보(IP 주소 / 도메인 네임)
path : 자원이 위치한 경로.
query : ?로 시작되는 <키=값> 형태의 데이터로, 자원의 위치를 식별한 후 해당 자원을 유저 임의로 커스텀해서 확인하고 싶을 경우 사용.
fragment : 자원에서 특정 부분을 가리키기 위한 정보.
1.5.2. URN
자원에 고유한 이름을 붙이는 이름 기반 식별자로, 자원의 위치가 변하는 URL의 고질적 문제를 해결하기 위한 방법이다.
2. HTTP
해당 단원에 관련된 문제는 아래와 같다.
HTTP 상태 코드에 대한 설명으로 옳지 않은 것을 골라 보세요.
1) 300번대 상태 코드는 요청한 자원이 존재하지 않음을 의미합니다.
2) 400번대 상태 코드는 클라이언트에 의한 에러를 의미합니다.
3) 500번대 상태 코드는 서버에 의한 에러를 의미합니다.
4) 200번대 상태 코드는 요청이 성공했음을 의미합니다.
정답은 1번으로, 300번대는 리다이렉션 관련 코드이다.
해당 문제를 이해하기 위해 HTTP에 대해 알아보자.
2.1. HTTP의 특성
HTTP는 응용 계층에서 정보를 주고받기 위해 사용되는 프로토콜이다.
* 요청-응답 기반 프로토콜
= 클라이언트와 서버가 서로 HTTP 요청 메세지와 HTTP 응답 메세지를 주고받는 구조로 동작한다.
* 미디어 독립적 프로토콜
= 자원의 특성과 무관하게 자원을 주고받을 수단인 인터페이스의 역할만 수행한다.
(HTTP에서 메세지로 주고받는 자원의 종류 : 미디어 타입 / MIME 타입)
= 미디어 타입에 제한을 두지 않는 독립적 프로토콜.
(타입 종류는 text, image, video, audio, application, multipart 등이 존재한다.)
* 스테이트리스 프로토콜
= 상태를 유지하지 않는 프로토콜.
(서버가 HTTP 요청을 보낸 클라이언트와 관련된 상태를 기억하지 않는다는 의미.)
= HTTP 서버는 많은 클라이언트와 동시에 상호작용하기 때문에 클라이언트에 종속되지 않음.
= 확장성, 견고성의 설계 목표를 지향하기 위한 중요한 특성.
* 지속 연결 프로토콜
= 하나의 TCP 연결상에서 여러 개의 요청-응답을 주고받을 수 있음. (킵 얼라이브(keep-alive)
= 비지속 연결(매변 새롭게 연결을 수립하고 종료함)에 비해 빠르게 여러 HTTP 요청과 응답 처리 가능.
2.2. HTTP 메세지 구조
해당 메세지의 구조는 아래와 같다.
시작 라인(줄바꿈)
필드 라인(줄바꿈, 0개 이상)
(줄바꿈)
메세지 본문(선택적)
시작 라인 : HTTP 메세지의 종류를 알려주는 부분. 시작 라인(HTTP 요청 메세지), 상태 라인(HTTP 응답 메세지) 등으로 설정될 수 있다.
(++ 요청 라인 : 메서드 (공백) 요청 대상 (공백) HTTP 버전 (줄바꿈)
메서드 : 클라이언트가 서버의 자원(요청 대상)에 대해 수행할 작업의 종류. (GET, POST, PUT, DELETE..etc)
요청 대상 : HTTP가 요청을 보낼 서버의 자원으로, 쿼리가 포함된 URI의 경로 명시.
HTTP 버전 : 사용된 HTTP의 버전)
(++상태 라인 : HTTP 버전 (공백) 상태 코드 (공백) 이유 구문(선택적) (줄바꿈)
HTTP 버전 : 사용된 HTTP의 버전.
상태 코드 : 요청에 대한 결과를 나타내는 세 자리 정수.
이유 구문 : 상태 코드에 대한 문자열 형태의 설명.)
필드 라인 : 0개 이상의 HTTP 헤더가 명시되어 헤더 라인이라고도 불림.
(HTTP 헤더 : HTTP 통신에 필요한 부가 정보. 헤더 이름+하나 이상의 헤더값으로 구성.)
메세지 본문 : HTTP 요청 혹은 응답 메세지에서 본문이 필요할 경우 사용.
2.3. HTTP 메서드
자주 사용되는 메서드에 대해 알아보자.
GET
= 특정 자원을 조회할 때 사용되는 메서드.
= 자원을 습득하기 위해 사용됨.
= 해당 메서드에 요청 메세지 본문을 포함하기보다 쿼리 문자열을 사용하는 것이 더 일반적.
HEADER
= GET과 동일하지만, 응답 메시지에 대한 메시지 본문이 포함되지 않음.
= 요청에 대한 응답으로 응답 메세지의 헤더만을 반환함.
POST
= 서버에게 특정 작업을 처리하도록 요청하는 메서드.
= 처리할 대상은 메세지 본문으로 명시.
= 범용성이 넓은 메서드로, GET과 함께 가장 대중적으로 많이 쓰인다.
= 대부분 클라이언트가 서버에 새 자원을 생성하고자 할 때 사용되며, 성공적으로 처리되면 서버는 Location 헤더로 새로 생성된 자원의 위치를 알려줌.
PUT
= 덮어쓰기를 요청하는 메서드.
= 요청 자원이 없으면 메세지 본문으로 자원을 새롭게 생성하거나, 이미 자원이 존재한다면 메세지 본문으로 자원을 완전히 대체하는 메서드.
PATCH
= PUT과 다르게 부분적 수정에 가까운 메서드.
DELETE
= 특정 자원을 삭제하고 싶을 때 사용하는 메서드.
++ API 문서 : 어떤 URL로 어떤 요청을 받았을 때 서버가 어떻게 처리할 지 명시되어 있는 문서.
2.4. HTTP 상태 코드
상태 코드는 요청에 대한 결과를 나타내는 세 자리 정수로, 백의 자리수를 기준으로 유형을 구분한다.
200번대 : 성공 상태 코드
= 주로 사용되는 상태 코드는 200(요청 성공), 201(요청이 성공했으며, 새로운 자원 생성), 202(요청은 잘 받았으나, 이미 요청한 작업을 끝내지 않음), 204(요청이 성공했지만 메세지 본문으로 표시할 데이터가 없음) 등이다.
300번대 : 리다이렉션 코드
* 리다이렉션
= 클라이언트가 요청한 자원이 다른 곳에 있을 때, 클라이언트의 요청을 다른 곳으로 이동시키는 것.
= 영구적인 리다이렉션(permanent redirection) : 자원이 완전히 새로운 곳으로 이동하여 경로가 영구적으로 재지정되는 것. (기존 URL에 메세지를 보내면 항상 새 URL로 리다이렉트됨.)
= 관련된 상태 코드는 아래와 같다.
301 : 영구적 리다이렉션, 재요청 메서드 변경 가능.
308 : 영구적 리다이렉션, 재요청 메서드 변경되지 않음.
= 일시적인 리다이렉션(temporary redirection) : 자원의 위치가 임시로 변경되었거나 임시로 사용할 URL이 필요한 경우에 주로 사용. (요청을 보낸 URL을 기억해야 함.)
= 관련 상태 코드는 아래와 같다.
302 : 일시적 리다이렉션, 재요청 메서드 변경될 수 있음.
303 : 일시적 리다이렉션, 재요청 메서드 GET으로 변경.
307 : 일시적 리다이렉션, 재요청 메서드 변경되지 않음.
400번대 : 클라이언트 에러 상태 코드
= 클라이언트에 의한 에러가 있음을 알려 주는 상태
= 관련 상태 코드는 아래와 같다.
400 : 클라이언트의 요청이 잘못되었음.
401 : 요청한 자원에 대한 유효한 인증이 없음.
403 : 요청이 서버에 의해 거부됨.(접근 권한이 없는 경우)
404 : 요청받은 자원을 찾을 수 없음.
405 : 요청한 메서드를 지원하지 않음.
(++ 인증 : 자신이 누구인지 증명하는 것)
(++ 권한 부여 : 인증된 주체에게 작업을 허용하는 것)
500번대 : 서버 에러 코드
= 서버에 에러가 있음을 알려주는 상태.
= 관련 상태 코드는 아래와 같다.
500 : 요청을 처리할 수 없음.
502 : 중간 서버의 통신 오류
503 : 현재는 요청을 처리할 수 없으나 추후 가능할 수도 있음.
3. HTTP 헤더와 HTTP 기반 기술
3.1. HTTP 헤더
자주 사용되는 중요한 헤더 위주로 살펴보면 아래와 같다.
3.1.1. 요청 시 활용되는 HTTP 헤더
Host
= 요청을 보낼 호스트를 나타내는 헤더.
= 주로 도메인 네임으로 명시되며, 포트 번호가 포함될 수 있음.
User-Agent
= User-Agent : 웹 브라우저와 같이 HTTP 요청을 시작하는 클라이언트 측의 프로그램.
= 요청 메세지 생성에 관여한 클라이언트 프로그램과 관련된 다양한 정보 명시.
= 가장 흔히 볼 수 있는 헤더 중 하나.
Referer
= 클라이언트가 요청을 보낼 때 머무르고 있던 URL 명시.
= 개발 시 유용한 헤더.
Authorization
= 클라이언트의 인증 정보를 담는 헤더.
= 인증 타입과 인증을 위한 정보가 명시되며, 인증 타입에 따라 인증 정보에 명시될 값이 달라짐.
(++ 인증 타입 종류
Basic : 사용자 아이디와 비밀번호를 콜론을 이용해 합치고 Base64 인코딩한 값을 인증 정보로 삼는 방식.)
3.1.2. 응답 시 활용되는 HTTP 헤더
Server
= 요청을 처리한느 서버 측의 소프트웨어와 관련 정보를 명시.
Allow
= 클라이언트에게 허용된 HTTP 메서드 목록을 알려 주기 위해 사용.
Retry-After
= 자원을 사용할 수 있는 날짜 혹은 시각.
= 상태 코드 503과 같이 사용.
Location
= 클라이언트에게 자원의 위치를 알려 주기 위해 사용되는 헤더.
= 리다이렉션 발생, 새로운 자원 생성되었을 때 사용.
WWW-Authenticate
= 자원에 접근하기 위한 인증 방식을 설명하는 헤더.
= Basic 인증 외 다양한 정보를 알려주는 경우가 많음.
3.1.3. 요청, 응답 모두에서 활용되는 HTTP 헤더
Date
= 메세지가 생성된 날짜와 시각에 관련된 정보를 담은 헤더.
Connection
= 클라이언트의 요청과 응답 간의 연결 방식을 설정하는 헤더.
= 지속 연결이 명시되는 대표적 연결 방식.
Contect-Lencth
= 본문의 바이트 단위 크기(길이)
Content-Type, Content-Language, Content-Encoding
= 전송하려는 메세지 본문의 표현 방식을 설명하는 헤더.
= 표현 헤더의 일종.
Content Type : 메세지 본문에서 사용된 미디어 타입.
Content-Language : 메세지 본문에 사용된 자연어. 언어 코드와 국가 코드가 대표적으로 많이 사용.
Content-Encoding : 헤더에 메세지 본문을 압축하거나 변환한 방식 명시.
3.2. 캐시
캐시는 불필요한 대역폭 낭비와 응답 지연을 방지하기 위해 정보의 사본을 임시로 저장하는 기술이다.
* 특징
= 불필요한 대역폭 낭비를 줄일 수 있고, 빠르게 데이터에 접근할 수 있다.
= 웹 브라우저에 저장된 캐시는 개인 전용 캐시, 클라이언트와 서버 사이 중간 서버에 저장된 캐시를 공용 캐시라 부른다.
(여기서는 개인 전용 캐시 위주로 설명하겠다.)
3.2.1. 캐시 신선도
캐시 신선도는 캐시된 사본 데이터가 최신 원본 데이터와 유사한 정도이다.
* 신선도를 유지하는 가장 기본 방법
= 캐시된 데이터에 유효 기간을 설정하는 방법.
(응답 메세지의 Expires 헤더(날짜)와 Cache-Control 헤더의 Max-Age(초)를 사용한다.)
-> 캐시의 유효기간이 만료되었다면 클라이언트는 캐시된 자원이 여전히 최신 상태의 정보인지 재검사해야 한다.
3.2.2. 캐시 신선도를 재검사하는 방법
위에 설명한 데이터들을 기반으로 날짜와 엔티티 태그로 구별할 수 있다.
* 날짜 기반 재검사
= 클라이언트 : If-Modified-Since 헤더를 통해 서버에게 특정 시점 이후 원본 데이터에 변경이 있었는지 물어봄 -> If-Modified-Since 헤더 값으로 특정 시점(날짜와 시각) 명시 -> 이 시점 이후로 원본에 변경 존재하면 그 때만 새 자원으로 응답 가능.
= 서버 : 클라이언트에게서 If-Modified-Since 헤더 포함된 요청 메세지를 수신받을 경우 상태는 아래와 같다.
요청받은 자원 변경 : 상태 코드 200 + 새 자원 반환.
요청받은 자원 변경되지 않음 : 상태 코드 304 클라이언트에게 전송. (클라이언트는 캐시된 자원 이용)
요청받은 자원 삭제 : 상태 코드 404로 클라이언트에게 자원 존재하지 않다는 사실 전송.
(++ 상태 코드 304와 Last-Modified 헤더(특정 자원이 마지막으로 수정된 시점)을 통해 클라이언트에게 자원의 변경 여부+마지막 변경 시점을 알려줌)
* 엔티티 태그 기반 재검사
= 엔티티 태그(Etag) : 자원의 버전을 식별하기 위한 정보.
(++ 버전 : 유의미한 변경 사항)
= 자원이 변경될 때마다 자원의 버전을 식별하는 Etag 값 변경.
= Etag를 검사하기 위해 클라이언트는 If-None-Match 이용.
= 서버로 해당 태그가 전송되었을 때 서버의 자원 상황은 아래와 같다.
요청받은 자원 변경 : Etag값 변경. 상태 코드 200+변경 데이터+Etag값 응답 가능.
요청받은 자원 변경되지 않음 : 상태 코드 304 응답.
요청받은 자원 삭제 : 상태 코드 304 응답.
3.3. 쿠키
쿠키는 서버에서 생성되어 클라이언트 측에 저장되는 데이터이다.
* 특징
= HTTP가 스테이트리스 프로토콜이고, 클라이언트의 상태를 유지하지 않지만 클라이언트의 상태를 유지할 상황이 필요하기 때문.
= 서버가 클라이언트의 상태를 알 수 있게끔 하는 데이터.
= 기본적으로 <이름, 값> 쌍의 형태이고, 추가로 적용 범위, 만료 기간 등 다양한 속성 가짐.
= 서버는 쿠키를 생성해서 클라이언트에게 전송.
= 클라이언트는 전달받은 쿠키를 저장했다가 추후 동일 서버에 보내는 요청 메세지에 쿠키를 포함해서 전송.
(++ 세션 인증
= 쿠키를 통해 전달되는 세션 아이디로 클라이언트를 식별하는 방식.
= 같은 클라이언트가 서버에게 여러 번 요청을 보낼 때 인증을 여러 번 하는 과정을 거치지 않게 하기 위함.
= 과정은 아래와 같다.
1) 클라이언트는 서버에게 인증 정보 전송.
2) 인증 정보가 올바르다면 서버는 세션 아이디를 생성해 클라이언트에게 전송.
3) 서버는 생성한 세션 아이디를 데이터베이스 등에 저장.
4) 클라이언트는 추후 요청을 보낼 때 쿠키 내 세션 아이디 포함해서 전송.
5) 서버는 쿠키 속 세션 아이디와 저장도니 세션 아이디를 비교해 클라이언트 식별.)
=> 위와 같은 과정으로 쿠키는 서버의 클라이언트 인증 방식을 간편하게 만들 수 있다.
* 응답 메세지
= Set-Cookie 헤더를 통해 쿠키의 이름, 값, 세미콜론으로 구분되는 속성들을 전달할 수 있다.
= 같은 도메인이어도 경로별로 쿠키를 구별할 경우, path로 쿠키가 적용될 경로를 명시한다.
* 요청 메세지
= 쿠키는 브라우저에서 저장되고 관리됨.
= 쿠키가 사용 가능한 도메인은 Set-Cookie의 도메인으로 정해짐.
* 한계점
= 정보가 쉽게 노출되거나 조작될 수 있다.
(해결책 : Secure(HTTP 프로토콜 사용되는 경우만 쿠키 전송) / HttpOnly(HTTP 송수신을 통해저만 쿠키를 이용하도록 제한) 속성 이용.)
4. 후기
캐시랑 쿠키는 네트워크에서 중요하게 사용되어서 끝까지 다 읽고 정리했는데, 정리하길 잘했다는 생각이다. 이번 스터디를 성공적으로 마무리하길 바란다.