HTTP 메세지 - 메서드

HTTP 메세지 - 메서드

목차

HTTP 메세지 중 요청 줄에 존재하는 메서드에 대해서 알아본다. 요청 메서드에 따라서 서버에서 처리되는 과정, 반환되는 메세지의 형태가 달라진다. HTTP/1.1에서 정의한 메서드에는 총 9가지가 존재하며, 서비스에 따라 커스텀한 확장 메서드를 만들 수 있다.


  • 모든 서버가 모든 메서드를 구현하지 않는다.
  • 모든 메서드를 구현하지 않았다 하더라도 메서드는 대부분 제한적으로 사용될 것이다.
  • 일반적으로 서버 설정에 의해 메서드의 제한이 정해지며, 따라서 사이트마다 또 서버마다 다를 수 있다.

안전성 Safe

  • HTTP는 안전한 메서드라 불리는 메서드의 집합이다.
  • 안전한 메서드의 목적은,
    서버에 어떤 영향을 줄 수 있는 안전하지 않은 메서드가 사용될 때
    사용자들에게 그 사실을 알려줄 수 있도록 하는 것에 있다.
  • 읽기 전용인 경우 안전한 메서드로 간주한다.
  • GET, HEAD, OPTIONS 메서드는 안전한 메서드로 정의되어있다.
  • 디버깅용 메서드 TRACE로 클라이언트 쪽에 공격을 시도하여 credentials을 훔칠 수도 있기 때문에 안전한 메서드에 속하지 않는다.
RFC 7231 설명

번역에 오역이 있을 수 있습니다..

정의된 의미들이 본질적으로 읽기 전용인 경우, 요청 메소드는 “안전한” 것으로 간주됩니다. 즉, 클라이언트는 해당 리소스에 안전성있는 메서드를 적용한 결과로, origin 서버에 상태변화를 요청하지도 않고, 상태변화를 예상하지도 않는다. 마찬가지로, 안전성 있는 메서드를 합리적으로 사용한다면 origin 서버에서는 어떤 해를 야기하거나 리소스 손실 또는 비정상적인 부담을 예상하지 않는다.

안전한 메소드의 정의로

  1. 잠재적으로 유해하거나,
  2. 완전히 읽기 전용이 아니거나,
  3. 안전한 메소드를 호출하는 동안 사이드 이팩트를 일으키는 행동

을 포함시키지 않았다.
중요한 것은 client가 추가젹인 행동을 요구하지 않았고, 그것에 대해 책임을 질 수 없다는 것이다.

예를 들어 대부분의 서버는 메소드에 관계없이 모든 응답이 완료될 때 로그 파일에 액세스하기 위해 요청 정보를 추가하며, 로그 저장소가 가득 차서 서버가 손상될 수 있음에도 불구하고 안전한 것으로 간주된다. 마찬가지로, 웹 상에서 광고를 선택함으로써 시작된 안전한 요청은 종종 광고 계정을 청구하는 부작용을 낳을 것이다.

이 사양에서 정의한 요청 메서드 중 GET, HEAD, OPTIONS 및 TRACE 메서드는 안전하도록 정의되어 있습니다.

안전한 메서드과 안전하지 않은 메서드을 구분하는 목적은 자동 검색 프로세스(스파이더)와 캐시 성능 최적화(프리페치)가 해를 일으킬 염려 없이 작동할 수 있도록 하는 것이다.
또한, 사용자 에이전트는 신뢰할 수 없는 콘텐츠를 처리할 때 안전하지 않은 메서드의 자동 사용에 적절한 제약을 가할 수 있다.
사용자 에이전트는 사용자에게 잠재적 조치를 제시할 때 안전과 안전하지 않은 메서드을 구분하여 사용자가 요청하기 전에 안전하지 않은 조치를 인지할 수 있도록 해야 한다.

효과적인 요청 URI 내의 매개 변수가 action을 선택하는 효과를 가지도록 리소스를 구성하는 경우 action이 요청 메서드의 의미와 일치하는지 확인하는 것은 리소스 소유자의 책임이다.
예를 들어 웹 기반 콘텐츠 편집 소프트웨어는 “page?do=delete”와 같은 쿼리 매개 변수 내의 action을 사용하는 것이 일반적이다.
이러한 리소스의 목적이 안전하지 않은 action을 수행하는 것이라면(GET, HEAD, OPTIONS가 아닌) 리소스 소유자는 안전한 요청 방법을 사용하여 액세스할 때 해당 action을 실행 중지하거나 허용하지 않아야 한다.

그렇게 하지 않으면 자동화된 프로세스가 링크 유지보수, 프리 페치(사전 검색), 검색 색인 구축 등을 위해 모든 URI 참조에 GET를 수행할 때 사이드 이팩트가 발생할 수 있다.

원문 Request methods are considered "safe" if their defined semantics are essentially read-only; i.e., the client does not request, and does not expect, any state change on the origin server as a result of applying a safe method to a target resource. Likewise, reasonable use of a safe method is not expected to cause any harm, loss of property, or unusual burden on the origin server. This definition of safe methods does not prevent an implementation from including behavior that is potentially harmful, that is not entirely read-only, or that causes side effects while invoking a safe method. What is important, however, is that the client did not request that additional behavior and cannot be held accountable for it. For example, most servers append request information to access log files at the completion of every response, regardless of the method, and that is considered safe even though the log storage might become full and crash the server. Likewise, a safe request initiated by selecting an advertisement on the Web will often have the side effect of charging an advertising account. Of the request methods defined by this specification, the GET, HEAD, OPTIONS, and TRACE methods are defined to be safe. The purpose of distinguishing between safe and unsafe methods is to allow automated retrieval processes (spiders) and cache performance optimization (pre-fetching) to work without fear of causing harm. In addition, it allows a user agent to apply appropriate constraints on the automated use of unsafe methods when processing potentially untrusted content. A user agent SHOULD distinguish between safe and unsafe methods when presenting potential actions to a user, such that the user can be made aware of an unsafe action before it is requested. When a resource is constructed such that parameters within the effective request URI have the effect of selecting an action, it is the resource owner's responsibility to ensure that the action is consistent with the request method semantics. For example, it is common for Web-based content editing software to use actions within query parameters, such as "page?do=delete". If the purpose of such a resource is to perform an unsafe action, then the resource owner MUST disable or disallow that action when it is accessed using a safe request method. Failure to do so will result in unfortunate side effects when automated processes perform a GET on every URI reference for the sake of link maintenance, pre-fetching, building a search index, etc.

멱등성 Idempotent

  • 특정 메서드의 요청을 여러 번 했을 경우, 한번 요청했을 때와 결과가 같다면 멱등으로 간주한다.
  • PUT, DELETE, TRACE 및 안전한 요청 방법(GET, HEAD, OPTIONS)이 멱등성을 갖는다.
RFC 7231 설명

번역에 오역이 있을 수 있습니다..

요청 메서드로 해당 방법으로 동일한 요청을 여러번 했을 때, 한 번했을 때와 결과가 같다면 “멱등”으로 간주한다. 이 사양에서 정의한 요청 방법 중에서 PUT, DELETE 및 안전성 있는 메서드가 멱등성을 갖는다.

안전성과 마찬가지로 멱등성은 사용자가 요청한 내용에만 적용됩니다. 서버는 각 요청을 별도로 기록하거나, 수정 관리 기록을 유지하거나 혹은 멱등성을 갖는 요청마다 다른 비멱등성 사이드이팩트들를 구현할 수도 있다.

클라이언트가 서버의 응답을 읽기 전에 통신 장애가 발생할 경우 요청이 자동으로 반복될 수 있기 때문에 멱등성 메서드가 구별된다. 예를 들어 클라이언트가 PUT 요청을 보내고 응답이 수신되기 전에 기본 연결이 닫힌 경우 클라이언트는 새로운 연결을 설정하고 멱등(?) 요청을 다시 시도할 수 있다. 원래 요청이 성공하더라도, 응답은 다를 수 있지만, 요청을 반복하는 것은 의도된 것과 동일한 효과를 낼 것이라는 것을 알고 있다.

원문 A request method is considered "idempotent" if the intended effect on the server of multiple identical requests with that method is the same as the effect for a single such request. Of the request methods defined by this specification, PUT, DELETE, and safe request methods are idempotent. Like the definition of safe, the idempotent property only applies to what has been requested by the user; a server is free to log each request separately, retain a revision control history, or implement other non-idempotent side effects for each idempotent request. Idempotent methods are distinguished because the request can be repeated automatically if a communication failure occurs before the client is able to read the server's response. For example, if a client sends a PUT request and the underlying connection is closed before any response is received, then the client can establish a new connection and retry the idempotent request. It knows that repeating the request will have the same intended effect, even if the original request succeeded, though the response might differ.

캐시 가능성 Cachable

  • 향후 재사용을 위해 이에 대한 응답을 저장할 수 있음을 나타낼 수 있다.
  • 일반적으로 현재 시점의 응답이나 권한 있는 응답에 의존하지 않는 안전한 메서드는 캐시 가능한 것으로 정의한다.
    • GET, HEAD, POST
RFC 7231 설명 요청 method는 "cacheable"로 정의되어 향후의 재사용을 위해 이에 대한 응답을 저장할 수 있음을 나타낼 수 있다. 구체적인 요건은 [RFC7234](https://tools.ietf.org/html/rfc7234)를 참조한다. 일반적으로 현재 또는 권한 있는 응답에 의존하지 않는 안전한 메서드를 캐시 가능한 것으로 정의된다. 이 규격은 압도적으로 많은 캐시 구현이 GET와 HEAD만 지원하지만 GET, HEAD 및 POST는 캐시 가능한 것으로 정의한다.

Request methods can be defined as “cacheable” to indicate that responses to them are allowed to be stored for future reuse; for specific requirements see RFC7234. In general, safe methods that do not depend on a current or authoritative response are defined as cacheable; this specification defines GET, HEAD, and POST as cacheable, although the overwhelming majority of cache implementations only support GET and HEAD.

메서드 종류 (HTTP/1.1 기준)

1. GET

서버에게 리소스를 달라고 요청하기 위해 쓰인다.

요청메세지에 바디 존재 X
성공 응답메세지에 바디 존재 O
안전성  O
멱등성  O
캐시 가능?  O
HTML form에서 사용 가능? O

요청

1
2
3
GET /index.html HTTP/1.1
Host: feel5ny.github.io
Accept: *

응답

1
2
3
4
5
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 617

<html>...</html>

cf__1 왜 안전성과 멱등이 중요할까?

안전성과 멱등은 신뢰할 수 없는 네트워크 상의 HTTP를 신뢰할 수 있게 만들어 준다. 만일 GET 요청을 보내고 응답을 못 받았을 경우 그냥 한 번 더 보내면 된다. 이 동작은 안전하다. 먼저 보낸 요청이 벌써 처리되었다 하더라도 서버에 다른 영향은 없다. 마찬가지로 PUT 요청을 보내고 응답을 못 받았다면 단지 한 번 더 동일한 요청을 보내면 된다.
그러나 POST는 안전하지도 않고 멱등도 아니다. 따라서 POST 메소드는 주의해서 사용해야 한다. 출처(행복한 아빠)


2. HEAD

GET처럼 행동하지만, 서버는 응답으로 헤더만을 돌려준다.
엔터티 본문은 반환되지 않는다.

이럴 때 사용한다.

  • 리소스를 가져오지 않고도, 그에 대해 무엇인가(타입이라거나)를 알아낼 수 있다.
  • 응답의 상태 코드를 통해, 개체가 존재하는지 확인할 수 있다.
  • 헤더만을 확인하여 리소스가 변경되었는지 검사할 수 있다.
  • 큰 용량의 리소스를 다운로드 받을지 말지 결정하기 위해서 사전 요청하는 용도로 사용할 수 있다.
요청메세지에 바디 존재 X
성공 응답메세지에 바디 존재 X
안전성  O
멱등성  O
캐시 가능?  O
HTML form에서 사용 가능? X

요청

1
2
3
HEAD /index.html HTTP/1.1
Host: feel5ny.github.io
Accept: *

응답

1
2
3
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 617

3. PUT

서버에 문서를 쓴다….(?)

  • 예시
    • 어떤 발행 시스템은 사용자가 PUT을 이용해 웹페이지를 만들고,
    • 웹서버에 직접 게시할 수 있도록 해준다.

PUT 메서드의 의미는

  • 서버가 요청의 본문을 가지고 요청 URL의 이름대로 새 자료를 만들거나,
  • 이미 URL이 존재한다면, 본문을 사용해서 교체하는 것이다.
  • 데이터를 변경할 수 있는 메서드이기 때문에 서버 입장에서는 위험할 수 있다.
  • PUT은 콘텐츠를 변경할 수 있게 해주기 때문에,
    많은 웹 서버가 PUT을 수행하기 전에 사용자에게
    비밀번호를 입력해서 로그인을 하도록 요구할 것이다.
요청메세지에 바디 존재 O
성공 응답메세지에 바디 존재 X
안전성  X
멱등성  O
캐시 가능?  X
HTML form에서 사용 가능? X

요청

1
2
3
4
PUT /joy.txt HTTP/1.1
Host: feel5ny.github.io
Content-Type: text/plain
Content-Length: 34

응답

1
2
3
4
5
HTTP/1.1 201 Created
Content-Type: text/html
Content-Length: 47

http://feel5ny.github.io/joy.txt
  • 새로운 생성 시에는 성공 응답코드로 201 Created을 내려줘야 한다.
  • 수정 작업 시에는 성공 응답코드로 200을 내려줘야 한다.

PUT과 POST의 차이점은 PUT은 멱등하다.

  • PUT은 한번 혹은 연속적으로 여러 번 하더라도 동일하지만 영향(부작용이 아님)을 미치지만,
  • POST는 연속적인 요청이 그대로 전달되어, 요청이 연속적으로 들어가는 것으로 인지하여 추가적인 영향이 있을 수 있습니다.
  • PUT으로 새 리소스를 생성하고
    또 동일한 내용으로 PUT을 리소스에 요청해도
    두 번째는 이미 존재하고 동일한 내용이므로 결과는 같다.
  • 이미 존재하는 리소스에 PUT을 보낼 경우
    동일한 내용으로 몇 번을 보내더라도
    동일한 내용으로 상태가 저장되므로
    리소스 상태는 변하지 않는다.

4. POST

  • 서버에 입력 데이터를 전송하기 위해 설계되었다.
  • request의 body 타입은 Content-Type 헤더(header)에 따라 결정된다.
  • POST는 비멱등성을 갖는다. 같은 POST를 연속적으로 보낸다면 명령을 여러 번 내린 것처럼 부가적인 효과를 가져올 것입니다.
요청메세지에 바디 존재 O
성공 응답메세지에 바디 존재 O
안전성  X
멱등성  X
캐시 가능?  새 정보가 포함되었을 때만
HTML form에서 사용 가능? X

요청

1
2
3
4
5
6
POST /inventory-check.cgi HTTP/1.1
Host: feel5ny.github.io
Content-Type: text/plain
Content-Length: 18

item=bandsaw 2647

응답

1
2
3
4
5
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 37

The bandsaw model 2647 is in stock!

5. TRACE

자신의 요청이 서버에 도달했을 때 어떻게 보이게 되는지 알려준다.

  • 클라이언트가 어떤 요청을 할 때,
    그 요청은 방화벽, 프락시, 게이트웨이 등의 어플리케이션을 통과할 수 있다.
  • 이들에게는 원래의 HTTP 요청을 수정할 수 있는 기회가 있다.
  • TRACE는 클라이언트에게 자신의 요청이 서버에 도달했을 때 어떻게 보이게 되는지 알려준다.

TRACE 요청은 목적지 서버에서 루프백 loopback 진단을 시작한다.

  • 요청 전송의 마지막 단계에 있는 서버는
    자신이 받은 요청 메세지를 본문에 넣어서
    TRACE 응답을 돌려준다.
  • 클라이언트는 자신과 목적지 서버 사이에 있는 모든 HTTP 어플리케이션의 요청/응답 연쇄를 따라가면서
    자신이 보낸 메세지가 망가졌거나 수정되었는지, 만약 그렇다면 어떻게 변경되었는지 확인할 수 있다.

TRACE는 주로 진단을 위해 사용된다. (디버깅용)

  • 요청이 의도한 요청/응답 연쇄를 거쳐가는지 검사할 수 있다.

  • 중간 어플리케이션이 여러 다른 종류의 요청들을 일관되게 다룬다고 가정하는 문제가 있다.

    • 프락시는
      POST 요청을 바로 서버로 통과시키는 반면,
      GET 요청은 웹 캐시와 같은 다른 HTTP 어플리케이션으로 전송한다.
    • TRACE는 메서드를 구별하는 메커니즘을 제공하지 않는다.
      • TRACE 요청을 어떻게 처리할 것인지에 대해서는 일반적으로 중간 어플리케이션이 결정을 내린다.
      • TRACE 요청은 어떠한 엔터티 본문도 보낼 수 없다.
        TRACE 응답의 엔터티 본문에는 서버가 받은 요청이 그대로 들어있다.
요청메세지에 바디 존재 X
성공 응답메세지에 바디 존재 X
안전성  X
멱등성  O
캐시 가능?  X
HTML form에서 사용 가능? X

클라 요청

1
2
3
TRACE /product-list.txt HTTP/1.1
Accept: *
Host: feel5ny.github.io

프록시 요청

1
2
3
4
TRACE /product-list.txt HTTP/1.1
Accept: *
Host: feel5ny.github.io
Via: 1.1 proxy3.company.com 👈

서버 응답

1
2
3
4
5
6
7
8
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 96

TRACE /product-list.txt HTTP/1.1
Accept: *
Host: feel5ny.github.io
Via: 1.1 proxy3.company.com 👈

프록시 응답

1
2
3
4
5
6
7
8
9
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 96
Via: 1.1 proxy3.company.com 👈

TRACE /product-list.txt HTTP/1.1
Accept: *
Host: feel5ny.github.io
Via: 1.1 proxy3.company.com 👈

6. OPTIONS

  • options 메서드는 웹 서버에게 여러 가지 종류의 지원 범위에 대해 물어본다.
  • 서버에게 특정 리소스에 대해 어떤 메서드가 지원되는지 물어볼 수 있다.
  • 응답메세지 헤더에 Allow 필드를 포함해서 돌려준다.
  • preflight 요청용으로 OPTIONS 메서드를 사용한다.

cf__2 Preflight

  • Preflight Request는 actual 요청 전에 인증 헤더를 전송하여 서버의 허용 여부를 미리 체크하는 테스트 요청이다.
  • CORS Preflight Request는 CORS 프로토콜이 이해하는지 확인하는 요청이다.
  • 메서드는 OPTIONS를 사용하며, 헤더를 함게 보낸다.
    • Access-Control-Request-Method
    • Access-Control-Request-Headers
    • Origin
  • Preflight Request 필요시 브라우저에서 자동으로 전송되므로, 일반적인 경우 프론트 개발자는 이러한 요청을 직접 만들 필요가 없다.
    참고
요청메세지에 바디 존재 X
성공 응답메세지에 바디 존재 O
안전성  O
멱등성  O
캐시 가능?  X
HTML form에서 사용 가능? X

요청

1
2
3
OPTIONS * HTTP/1.1
Host: feel5ny.github.io
Accept: *

응답

1
2
3
HTTP/1.1 200 OK
Allow: GET, POST, PUT, OPTIONS
Content-Length: 0

7. DELETE

  • 서버에게 요청 URL로 지정한 리소스를 삭제할 것을 요청한다.
  • 클라이언트는 삭제가 수행되는 것을 보장하지 못한다.
    • HTTP 명세는 서버가 클라이언트에게 알리지 않고 요청을 무시하는 것을 허용하기 때문이다.
요청메세지에 바디 존재
성공 응답메세지에 바디 존재
안전성  X
멱등성  O
캐시 가능?  X
HTML form에서 사용 가능? X

요청

1
2
DELETE /joy.txt HTTP/1.1
Host: feel5ny.github.io

응답

1
2
3
4
5
HTTP/1.1 201 Created
Content-Type: text/html
Content-Length: 47

I have your delete request, will take time to process.
  • 200 OK
  • 202 Accepted
  • 204 No content

8. PATCH

  • 리소스의 부분 수정 시 사용된다.
  • PUT과 달리 비멱등성을 가진다.
  • PATCH의 사용 여부는 Accept-Patch로도 가능하다.

PUT과의 차이점

  • PUT은 문서 자체의 교체만을 허용한다.
  • PUT으로 수정할 JSON 일부분을 보낼 때, 보낸 필드 이외의 필드는 null 혹은 초기화 처리가 된다.
  • PATCH로 수정할 JSON 일부분을 보낼 때, 해당 필드만 수정된다.
요청메세지에 바디 존재 O
성공 응답메세지에 바디 존재 O
안전성  X
멱등성  X
캐시 가능?  X
HTML form에서 사용 가능? X

요청전 데이터

1
2
3
4
{
"name": "joy",
"company": "goodoc"
}

PATCH 요청

1
2
3
4
5
PATCH /api/user/123 HTTP/1.1 
Host: www.example.com
Content-Type: application/json

{"company": "protopie"}

PATCH 결과

1
2
3
4
{
"name": "joy",
"company": "protopie"
}

PUT 요청

1
2
3
4
5
PUT /api/user/123 HTTP/1.1 
Host: www.example.com
Content-Type: application/json

{"company": "JOYI"}

PUT 결과

1
2
3
4
{
"name": null,
"company": "JOYI"
}

9. CONNECT

잘 모르겠다.

  • HTTP CONNECT 메소드는 요청된 리소스와 양방향 통신을 시작한다.
  • 터널을 여는 데 사용할 수 있다.
  • 예를 들어
    • CONNECT 메소드를 사용하여 SSL(HTTPS)을 사용하는 웹 사이트에 액세스 할 수 있다.
    • 클라이언트는 HTTP 프록시 서버에 TCP 연결을 원하는 대상으로 터널링하도록 요청한다.
    • 그런 다음 서버는 클라이언트 대신 연결을 진행한다.
    • 서버가 연결을 설정하면 프록시 서버는 클라이언트와의 TCP 스트림을 계속 프록시한다.
요청메세지에 바디 존재 X
성공 응답메세지에 바디 존재 O
안전성  X
멱등성  X
캐시 가능?  X
HTML form에서 사용 가능? X

요청

1
2
3
CONNECT server.example.com:80 HTTP/1.1 
Host: server.example.com:80
Proxy-Authorization: basic aGVsbG86d29ybGQ=

10. 확장 메서드

  • HTTP 명세에 정의되지 않은 메서드다.
  • HTTP는 필요에 따라 확장해도 문제가 없도록 설계되어 있으므로, 새로 기능을 추가해도 과거에 구현된 소프트웨어들의 오동작을 유발하지 않는다.
  • 아래는 웹 배포 확장메서드의 예시
    • LOCK - 사용자가 리소스를 잠글 수 있게 해준다.
    • MKCOL - 사용자가 문서를 생성할 수 있게 해준다.
    • COPY - 서버에 있는 리소스를 복사한다.
    • MOVE - 서버에 있는 리소스를 옮긴다.

확장메서드를 다룰 때는 ‘엄격하게 보내고 관대하게 받아들여라’라는 오랜 규칙에 다르는 것이 가장 좋다.


  • 책뽀개기 모임http 완벽가이드 1장 뽀개기 진행중입니다. (~8월말) (다음 모임은 2장)
  • HTTP 완벽가이드 책을 보고 이해한 내용을 저만의 순서로 정리 한 글입니다.

참고자료

  1. http 멱등성참고 1
  2. http 멱등성참고 2
  3. http method 참고
  4. preflight 참고 1
  5. preflight 참고 2
  6. http 응답 다이어그램
    • 도움이 많이 된 시각화 자료
  7. PUT과 PATCH의 차이 1
  8. PUT과 PATCH의 차이 2
  9. rfc7231
📚