kakasoo

[HTTP] 7. 상태코드 (Status Code) 본문

프로그래밍/HTTP

[HTTP] 7. 상태코드 (Status Code)

카카수(kakasoo) 2020. 10. 18. 14:22
반응형

3.4 상태 코드

상태코드는 5가지 범주로 나뉜다. 즉, 앞자리가 1부터 5까지 있다고 보면 된다. 상태 코드는 명확하다, 여기에 사유 구절이 들어가면 클라이언트가 트랙잭션을 이해하기 편해진다. (사유 구절은 공식적인 가이드가 없다.)

3.4.1 100-199: 정보성 상태 코드

HTTP/1.1 에서 도입된 것으로 비교적 최신의 것이며, 가치에 대해서는 아직 논란이다.

  • 상태코드 100 사유구절 Continue :

    요청의 일부가 받아들여졌고, 클라이언트는 나머지 요청을 보내야 한다는 의미이다. 이것을 보낸 후에는 서버는 반드시 요청을 기다려야 한다.

    만들어진 의도는, 클라이언트가 본문을 전송하기 전에 서버가 받아들일 것인지에 대한 확인을 최적화하기 위한 용도였으나, 프로그래머를 혼란스럽게 하는 경향이 있다.

    • 클라이언트 측면

      원래대로면, 클라이언트는 본문을 보낼 경우와 보내지 않을 경우를 나눠서 요청의 헤더를 다르게 해 보내야 한다. 본문을 보낼 거면 100-continue Expect 헤더를 추가해서 보내야 한다.

      만일 이것을 혼동한다면 서버는 클라이언트가 본문을 보낼 거라고 기다릴 수도 있고, 나중에 보낸 데이터를 클라이언트가 본문을 보내기 시작했다고 착각할 수도 있기 때문이다.

      다만 초창기의 100 Continue 상태에 대한 혼란 때문에, 당시 개발된 애플리케이션들은 위의 잘못된 사례들이 발생할 가능성이 높다. 따라서 클라이언트 개발자들은 예상하지 못한 응답에도 대비할 필요가 생겨 버렸다.

      이건 지금 글을 적고 있는 내 개인적인 생각인데, 마치 지구 주변에 돌고 있는 인공위성 파편들을 떠올리게 한다.

    • 서버 측면

      클라이언트가 본문을 보내기 전에 요청을 보냈다면, 즉 100-continue Expect 헤더를 보냈다면 서버는 100 Continue 응답 혹은 에러 코드로 답해야 한다.

      서버가 100 Continue 응답을 보낼 기회를 갖기 전에 이미 본문 내용 중 일부, 또는 전체를 받았다면 서버는 이 상태 코드를 보낼 필요도 없다. 이미 계속 보내기로 결정되었기 때문이다.

      그러나 서버가 요청을 다 읽은 후에는 그 응답을 보내 주어야 한다.

      마지막으로 주의할 점은, 서버가 본문을 읽기 전, 또는 읽던 도중에 요청을 닫기로 했다면 그냥 닫아서는 안된다! 자세한 내용은 추후 4장의 "TCP 끊기와 리셋 에러"에서 설명한다.

    • 프락시 측면

      클라이언트로부터 100-continue 응답을 의도한 요청을 받은 프락시는 아래와 같이 행동해야 한다.

    1. 만약 다음 홉 (next-hop) 서버가 HTTP/1.1을 따르거나, 어떤 버전인지 알 수 없다면 Expect 헤더를 보내야 한다.

    2. 만약 이전 버전을 따른다는 것을 이미 알고 있다면 417 Expectation Failed 에러로 응답해야 한다.

      정리하자면, 중간 역할인 프락시가 볼 때 다음 홉 서버가 최신 버전의 HTTP 명세를 따른다면 Expect 헤더를 보내 본문을 보낼 것임을 알리고, 그게 아니라면 에러로 응답하라는 뜻.

    3. 이 때, 만일 1번과 같이 Expect 헤더를 보내기로 했다면, 그 응답 결과는 클라이언트에게 보내지 않는다, 클라이언트는 이것을 어떻게 처리할지에 대한 로직이 없기 때문이다.

    4. 프락시가 다음 홉 서버에 대한 상태와 HTTP 버전을 기억해둔다면, 100-continue 응답을 기대한 요청을 더 잘 다룰 수 있게 되므로 프락시에게도 이득이 된다.

3.4.2 200-299: 성공 상태 코드

클라이언트가 요청을 보내면 대개 성공한다. 서버는 성공을 의미하는 코드 배열을 가지고 있다.

  • 상태코드 200 사유구절 OK : 요청이 정상이고, 엔터티 본문에 요청된 리소스를 포함하고 있다.

  • 상태코드 201 사유 구절 Created :

    서버 개체를 생성하라는 요청 (예를 들어 PUT)을 위한 것. 생성된 리소스에 대한 구체적 참조가 담긴 Location 헤더와 함께, 그 리소스를 참조할 수 있는 여러 URL을 본문에 포함해야 한다.

    서버는 상태 코드를 보내기에 앞서 반드시 객체를 생성해야 한다.

  • 상태코드 202 사유 구절 Accepted :

    요청은 받았으나 서버는 아직 수행하지 않는다는 의미를 담고 있다. 따라서 요청이 적합해 보인다는 의미지, 처리에 대한 보장을 하지 않는다. 다만 서버는, 가급적 응답 본문에 예상 처리 시간을 포함해줘야 한다.

    또는 그에(예상 처리 시간) 대한 정보를 어디서 얻을 수 있는지를 포함해줘도 된다.

  • 상태코드 203 사유 구절 Non-Authoritative Information :

    원래대로면 성공했다는 의미로 200을 보내야 하지만, 해당 정보가 원래 서버가 아닌 리소스의 사본에서 왔을 경우, 즉 헤더를 검증하지 않은 경우에 발생한다. 원래 서버에서 온 것일 경우의 선택사항이다.

  • 상태코드 204 사유 구절 No Content : 엔터티 본문이 없는 경우를 의미한다. 주로 웹 브라우저를 새 문서로 옮기지 않고 갱신할 때, 즉 폼을 리프래시 할 때에 사용한다.

  • 상태코드 205 사유 구절 Reset Content : 주로 브라우저를 위해 사용하는 코드로, 브라우저에게 현재 html 폼에 채워진 모든 값을 비우라는 의미를 갖고 있다.

  • 상태코드 206 사유 구절 Partial Content : 부분 혹은 범위 요청이 성공했다는 의미.

3.4.3 300-399: 리다이렉션 상태 코드

리다이렉션 상태 코드는 클라이언트가 관심있어 하는 리소스에 대한 다른 위치를 사용하라고 말해주거나, 리소스 대신 다른 대안 응답을 제공한다.

리소스가 옮겨졌다면 어디서 찾을 수 있는지 알려주기 위해 리다이렉션 상태 코드와 Location 헤더를 보낼 수 있다. 이는 브라우저가 사용자를 귀찮게 하지 않고, 알아서 새 위치로 가게 해준다.

이런 특성으로, 리다이렉션 상태 코드 중 일부는 로컬의 복사본이 원래 서버와 비교했을 때 유효한지, 또는 최신의 파일이 맞는지 비교하는 데에 쓰인다.

이 때에는 If-Modified-Since 헤더에 특정 날짜를 보내 그 날짜를 기준으로 파일의 수정이 생겼는지 체크할 수 있다. 이 경우 304의 상태 코드가 돌아온다.

일반적으로, HEAD가 아닌 다른 메소드에 대해 리다이렉션 상태 코드를 포함한 응답을 해야 한다면, 링크와 그 링크에 대한 설명을 포함시키는 것은 좋은 습관이다.

  • 상태코드 300 사유 구절 Multiple Choices :

    클라이언트가 동시에 여러 리소스를 가리키는 요청을 하는 경우, 그 리소스의 목록과 함께 반환한다. 사용자는 목록에서 하나를 선택할 수 있다. 어떤 하나의 서버가 영어와 프랑스어로 되어 있는 경우 등에 사용한다.

    클라이언트가 어떤 것을 선택하는지 (협상)에 대해서는 추후 설명한다.

  • 상태코드 301 사유 구절 Moved Permanently : 요청한 URL이 옮겨 졌을 때 사용한다. Location 헤더에 URL을 담아서 보내줘야 한다.

  • 상태코드 302 사유 구절 Found : 301과 같으나, 임시로 가리키는 URL을 보내준다.

  • 상태코드 303 사유 구절 See Other : 사용자에게, 다른 URL에서 찾아야 한다고 암시해주는 상태 코드다.

  • 상태코드 304 사유 구절 Not Modified : 변동사항이 없음을 말한다. 200과 동일하게, 엔터티 본문을 전달하는 본분을 잊어서는 안 된다.

  • 상태코드 305 사유 구절 Use Proxy : 리소스가 프락시를 통해서 접근해야 함을 말한다.

  • 상태코드 306 사유 구절 (사용되지 않는다.)

  • 상태코드 307 사유 구절 Temporary Redirect : 301과 유사하나, 임시로 가리키기 위한 URL을 보내준다.

    302, 303, 307이 코드가 매우 유사한데, 이에 대한 내용은 버전에서 비롯되었다.

3.4.4 400-499: 클라이언트 에러 상태 코드

클라이언트가 알 수 없는 요청을 보낸 경우를 다룬다.

  • 상태코드 400 사유 구절 Bad Request : 클라이언트가 잘못된 요청을 보냈다는 의미를 담고 있다.
  • 상태코드 401 사유 구절 Unauthorized : 리소스를 얻기 전에 인증이 필요하다는 의미이다.
  • 상태코드 402 사유 구절 Payement Required : 미래에 사용될 수 있는 코드.
  • 상태코드 403 사유 구절 Forbidden : 금지되어 있다는 의미. 본문에 이유를 설명할 수 있지만, 보통은 서버의 거절 사유를 숨기고 싶을 때 사용한다.
  • 상태코드 404 사유 구절 Not Found : 요청한 URL을 찾을 수 없다는 의미.
  • 상태코드 405 사유 구절 Method Not Allowed : 지원하지 않는 Method로 요청을 받았을 때에 사용한다. 요청에 Allow 헤더로 가능한 메서드를 알려주어야 한다.
  • 상태코드 406 사유 구절 Not Acceptable : 클라이언트가 받아들일 수 없는 정보일 경우를 의미한다. 자세한 내용은 추후 설명한다.
  • 상태코드 407 사유 구절 Proxy Authentication Required : 401과 같으나 대상이 프락시 서버인 경우를 위해 사용한다.
  • 상태코드 408 사유 구절 Request Timeout : 클라이언트의 요청을 받아들이기에 너무 오랜 시간이 걸리는 경우, 서버가 임의로 끊는 경우 반환한다. 이 타임아웃 설정은 적법한 요청을 받아들일 순 있을 만큼 충분히 길어야 한다.
  • 상태코드 409 사유 구절 Conflict : 요청이 리소스에 대해 일으킬 수 있는 충돌을 지칭하기 위해 사용한다. 응답은 그 설명도 본문에 담아야 한다.
  • 상태코드 410 사유 구절 Gone : 한 때 있었으나 지금은 없다는 의미.
  • 상태코드 411 사유 구절 length Required : 요청 메세지에 Content-Length가 필요하다는 의미다.
  • 상태코드 412 사유 구절 Precondition Failed : 클라이언트의 조건부 요청 중 하나를 실패했을 때 반환한다.
  • 상태코드 413 사유 구절 Request Entity Too Large : 서버가 처리할 수 있는 본문 크기를 초과했을 때 사용한다.
  • 상태코드 414 사유 구절 Request URI Too Long : 서버가 처리할 수 있는 한계를 초과한 URL을 받았을 때 사용한다.
  • 상태코드 415 사유 구절 Unsupported Media Type : 서버가 처리할 수 없는 타입인 경우 반환한다.
  • 상태코드 416 사유 구절 Requested Reange Not Satisfiable : 요청 메시지의 특정 범위가 잘못되었을 때 반환한다.
  • 상태코드 417 사유 구절 Expectation Failed : 요청의 Expect가 만족할 수 없는 것인 경우에 반환한다.

3.4.5 500-599: 서버 에러 상태 코드

클라이언트가 올바른 요청을 보냈음에도 에러가 발생한 경우, 즉 서버 측의 오류인 경우에 해당한다.

이 경우에는 클라이언트가 서버의 제한에 걸렸거나, 게이트웨이 리소스와 가은 서버 보조 구성 요소에서 발생한 에러일 수도 있다. 클라이언트를 대신하여 프락시가 서버와 소통하고자 할 때 자주 발생한다.

  • 상태코드 500 사유 구절 Internal Server Error : 서버가 요청을 처리할 수 없게 만드는 에러를 만났을 때 사용한다
  • 상태코드 501 Not Implemented : 클라이언트가 서버의 능력을 넘는 요청을 했을 때 사용한다.
  • 상태코드 502 Bad Gateway : 프락시나 게이트웨이처럼 행동하는 서버가 가짜 응답, 예컨대 자신의 부모 게이트웨이에 접속이 불가능해졌을 때 사용한다.
  • 상태코드 503 Service Unavailable : 현재는 서버가 요청을 처리해줄 수 없지만 나중에는 가능함을 의미하고자 할 때 사용한다.
  • 상태코드 504 Gateway Timeout : 상태코드 408과 비슷하지만 Timeout의 주체가 게이트웨이나 프락시라는 점에서 다르다.
  • 상태코드 505 HTTP Version Not Supported : 서버가 지원하지 않거나 지원하지 않으려고 하는 버전의 프로토콜로 된 요청을 받으면 사용한다. 몇몇 서버는 오래된 프로토콜을 지원하지 않으려고 한다.
반응형

'프로그래밍 > HTTP' 카테고리의 다른 글

[HTTP] 9. 커넥션 관리 (1)  (0) 2020.10.20
[HTTP] 8. 헤더 (Headers)  (0) 2020.10.18
[HTTP] 6. 메서드 (Method)  (0) 2020.10.17
[HTTP] 5. 메세지 (Message)  (0) 2020.10.17
[HTTP] 4. URL  (0) 2020.10.11