HTTP에서 헤더는 클라이언트와 서버가 요청/응답 본문과 함께 추가 정보를 전달하기 위한 요소다. 요청과 응답에서 모두 사용하는 개념이며, 대소문자를 구분하지 않는 key와 value를 콜론(:)으로 구분하여 헤더를 구성한다. 아래는 HTTP 요청과 응답 메시지의 예인데, 잘 보면 HTTP의 헤더가 많은 부분을 차지하고 있다. 언어, 브라우저 정보, 본문의 길이, 본문의 포맷, 인코딩 정보, 서버 정보 등 주고받을만 한 메타데이터들이 많기 때문이다.

헤더는 그 context에 따라 그룹을 나눌 수 있는데, 다음과 같다.

  • 일반 헤더(General header) : 요청 및 응답에는 적용되지만, 전송되는 데이터와는 관련이 없는 헤더
  • 요청 헤더(Request header) : 가져오고자 하는 리소스, 또는 클라이언트 자체에 대한 자세한 정보가 포함된 헤더
  • 응답 헤더(Response header) : 응답에 대한 추가 정보가 포함된 헤더
  • 엔티티 헤더(Entity header) : 요청이나 응답의 본문에 대한 더 많은 정보가 포함된 헤더

이제 헤더들을 살펴보자. '이런것도 있네' 싶은 헤더들이 종종 있다. 글의 길이가 너무 길어질 것 같아 여러 편에 나누어 구성한다.

Authorization: Basic cGxhbmI6c2VjcmV0

Authorization: <type> <credentials>

Request header로, 사용자의 자격을 증명하기 위해 사용한다. 게시글을 삭제하는 작업을 처리하는 API에서 요청의 Authorization 헤더를 복호화한 뒤 요청자가 리소스에 대한 삭제 권한이 있는지를 확인하는 등의 구현이 있을 수 있다.

type과 credentials를 공백으로 구분하여 value를 구성하며, type은 인증 타입을 나타낸다. BearerBasic, Digest, OAuth 등을 값의 맨 앞에 두는 것을 자주 봤을 것이다. type에 따라 credentials를 구성하는 방식이 달라지므로 서버가 credentials를 복호화하는 방식을 결정할 수 있게 하기 위해서 함께 사용한다. 따라서 credentials는 type에 따라 만들어내는 방식이 달라진다. 예를 들어 Basic 타입은 사용자명과 비밀번호를 콜론을 통해 합친 후(planb:secret), 그 문자열을 base64로 인코딩(cGxhbmI6c2VjcmV0)하여 credentials를 생성한다.

일반적으로, Authorization 헤더가 필요한 곳에 해당 헤더 없이 접근했거나, type이 유효하지 않거나, 복호화가 불가능한 경우 401을, 복호화에 성공했으나 자격 증명에 실패한 경우 403을 상태 코드로 응답한다.

Cache-Control: no-cache

Cache-Control

X- 헤더

'배경지식' 카테고리의 다른 글

ProxySQL  (1) 2019.02.12
직렬화와 JSON  (0) 2019.02.12
ORM  (0) 2019.02.12
HTTP 메소드  (0) 2019.02.12
StatsD  (0) 2019.02.11

Context(문맥)이라는 단어가 참 많은 곳에서 사용되기 때문에 조금 애매하지만, 아무튼 Python의 특정 객체들은 context를 가집니다. 예를 들어, file 객체는 open-close의 2가지 context를 가지는 식입니다.

file 객체의 open과 close처럼, context가 명확한 객체의 경우 Python에서는 원하는 타이밍에 정확하게 리소스를 할당하고 제거할 수 있도록 context manager 프로토콜을 갖도록 하는 것을 권고하고 있습니다. 'context manager 프로토콜을 가지고 있다'의 조건은 생각보다 간단합니다.

  • 매직 메소드 __enter__()를 구현하고 있어야 한다.
  • 매직 메소드 __exit__()을 구현하고 있어야 한다.

이 두 매직 메소드들은 가장 일반적인 context manager인 with-as 문에서 사용됩니다.

with 문에 의해 감싸진 객체는, 블럭이 시작되기 이전에 as 뒤의 객체에 __enter__()의 반환값을 할당하며, 블럭을 탈출하는 시점에 해당 객체의 __exit__()을 호출합니다. file의 경우, __enter__()에서 파일 객체를 열어 반환하고, __exit__()에서 파일 객체를 닫는(close) 역할을 하므로 context manageable하다고 말할 수 있습니다.

Context manageable한 클래스 만들기

__enter__()와 __exit__()이 정의된, context manageable한 클래스를 만들고 with-as 문에 사용해 보겠습니다.

역시, Python은 생각보다 훨씬 깊습니다.

'Python 계열 > Python 레거시 글' 카테고리의 다른 글

pip  (0) 2018.11.05
__slots__  (0) 2018.11.03
Argument Unpacking  (0) 2018.10.30
[Python] zip  (0) 2018.07.28
[Python] Coroutines  (0) 2018.07.27

Python에서 언더스코어처럼, asterisk(*)도 꽤 특별하게 사용할 수 있었습니다. 가장 일반적인 사용 사례는 수 사이의 곱셈과 거듭제곱 연산, Sequence 객체의 반복 확장, 그리고 아래의 가변 인자 표현식이었습니다.

Argument unpacking

Iterable 객체는 unpacking이 가능합니다. 이를 함수 인자에도 적용할 수 있는데, 여기에서 asterisk(*) 기호를 사용합니다.

이를 Argument unpacking이라 부르며, 위치 인자의 argument unpacking에는 List와 Tuple, String과 같은 sequence 객체를 사용할 수 있습니다. 아래는 키워드 인자에 대한 argument unpacking입니다.

여기에는 Dictionary와 같은 mapping 객체를 사용할 수 있습니다.

응용

Argument unpacking은 설정 데이터를 외부에서 다룰 때 유용하게 사용할 수 있는데, 아래와 같습니다. 데이터베이스에 연결하는 스크립트를 작성한다고 가정해 보겠습니다.

위처럼 argument unpacking으로 설정 데이터를 관리하는 경우, 대표적으로 아래 2가지의 강점을 가집니다.

  1. 코드가 간결해집니다. config에서 관리하는 데이터가 많아질수록, 간결함은 더 강해집니다.
  2. 추상화 레벨을 높여 유지 보수에 조금이나마 편의성을 제공합니다. 설정이 추가되거나 제거되는 경우, argument unpacking을 사용하는 코드에서는 원본 해당 객체만 수정함으로써 해결 가능하게 됩니다.


'Python 계열 > Python 레거시 글' 카테고리의 다른 글

__slots__  (0) 2018.11.03
Context Manager  (0) 2018.11.01
[Python] zip  (0) 2018.07.28
[Python] Coroutines  (0) 2018.07.27
[Python] memoize  (0) 2018.07.26

+ Recent posts