HTTP 상태 코드와 method

Lucid·2021년 12월 26일
3
post-thumbnail

오늘은 HTTP Status code에 대한 이야기를 해볼까 한다. 취업 전 보았던 HTTP 상태 코드는 거의 대부분이 404, 200, 500 이었다. 그리고 중요한 면접때에 HTTP Status code에 대해서 알고 있느냐는 질문을 받았고 어느정도 대답은 했지만 딱 취준생 수준의 대답을 했던 것으로 기억한다. 그 기억을 되짚어서 여태까지 몇개월간 개발자로 살면서 약간이나마 넓어진 시야를 통해 다시 한 번 상태코드에 대한 정리를 해볼까 한다.

HTTP Method

HTTP 상태 코드를 알아보기 전에 HTTP method부터 다시 한 번 짚고 넘어가보자. HTTP method에는 GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH 가 있다. 이러한 메소드들을 가지고 REST API를 잘 구성한다면 RESTful한 API를 작성하는데에 한발짝 더 가까워졌다고 이야기할 수 있다.

GET

가장 흔하게 쓰이는 GET 메소드는 주로 서버에게 리소스를 요청할 때 사용된다. GET 메소드는 리소스 요청시에만 사용해야 한다.

HEAD 메소드는 GET과 동일한 응답을 요청하지만 본문을 요청하지 않는 메소드이다. 서버는 응답으로 헤더만을 돌려준다.
이를 통해서 리소스를 가져오지 않고도 그에 대한 정보를 알아낼 수 있고, 응답의 상태 코드를 통해서 리소스가 존재하는지 확인할 수 있다. 또한 이를 통해서 리소스가 변경이 되었는지의 여부도 검사할 수 있다.
그렇다면 서버 개발자들은 HEAD에 대한 응답을 GET을 통해서 얻는 응답과 정확히 일치하도록 구현해야 한다.

POST

POST 메소드는 서버에 데이터를 전송하기 위해서 사용이 된다. 서버는 데이터를 받아서 이를 필요로 하는 곳에 보내어 처리한다. 보통은 입력한 데이터를 저장하기 위해서 사용한다.

PUT

PUT 메소드 또한 POST와 마찬가지로 서버에 문서를 저장하기 위해서 사용한다. 하지만 POST와의 차이점이 무엇이냐고 물어본다면 작성의 개념을 생각하면 이해가 편하다. POST가 문서를 추가하기 위함의 용도라면 PUT은 문서가 있다면 교체하고, 없다면 새로 생성하는 메소드이다.
예를 들어 POST /users ~~~ 로 두 번 요청하게 된다면 /users/1도 생기고, /users/2도 생기는 개념이다.
PUT /users/1 ~~~로 두 번 요청하게 된다면 /users/1을 통해 계속해서 작업을 진행하게 되는 것이다.

PATCH

PATCH는 PUT과 비슷하게 동작한다. 하지만 PUT은 전체 문서를 replace한다는 개념이라면 이와는 다르게 문서의 부분적인 수정의 개념을 가진다. PUT 요청 전송시에는 문서의 일부분만 보내게 된다면 이는 교체되고 나머지 값은 null(default value)로 대체되어야 한다. 하지만 PATCH는 일부 문서의 교체를 의미하기 때문에 보내지 않은 값에 대해서는 수정하지 않아야 한다.

DELETE

DELETE 메소드가 가장 직관적일 것 같다. 바로 그것. 삭제를 진행한다. 해당 위치에 있는 리소스를 삭제하는 역할만을 수행한다. 하지만 서버는 이를 판단하고 유효하다면 받아들이고 아니라면 무시할 수 있다.

CONNECT

CONNECT 메소드는 요청된 리소스와 양방향 통신을 시작하게 해주는 메소드이다. 이는 터널을 여는 데에 사용할 수 있다. 이러한 CONNECT 방법을 사용해서 SSL(HTTPS)을 사용하는 웹 사이트에 액세스할 수 있고, 클라이언트는 HTTP 프록시 서버에 TCP 연결을 원하는 대상으로 터널링하도록 요청한 후 서버는 클라이언트와의 연결을 계속한다. 서버에 의해서 연결되면 프록시 서버는 클라이언트에서 왔다갔다하는 TCP 스트림을 계속 프록시 한다.
(CONNECT 메소드와 여러가지 기법들은 더 공부하여 다시 블로그를 적어도 좋을 것 같다.)

OPTIONS

OPTIONS 메소드를 통해서 클라이언트는 서버에게 허용된 communication option들을 요청한다. (지원 범위에 대한 물음)
예를 들자면 OPTIONS * ~~ 와 같은 요청을 보냈다면 서버는 자신의 리소스에 대해 지원하는 메서드의 목록을 반환한다. 이를 통해 여러 리소스에 실제 접근하지 않더라도 어떻게 접근해야 하는지에 대한 수단을 확인할 수 있다.
사용의 예를 들어보자면 클라이언트가 DELETE 요청 전에 서버가 해당 요청을 허용해주는지를 브라우저가 자동적으로 preFlight request를 보낼 수 있다. (CORS) 그렇다면 브라우저는 OPTIONS /resource/foo와 같은 요청을 보내어 받은 응답에서 Access-Control-Allow-Origin의 출처를 비교해서 CORS를 처리할 수 있다.

TRACE

클라이언트가 어떤 요청을 보낼 때 요청은 방화벽, 프락시, 게이트웨이와 같은 애플리케이션들을 통과하여 서버로 전달될 수 있다. 이렇게 되면 이들은 원래의 HTTP 요청을 수정할 수 있게 된다. TRACE 메서드로 클라이언트는 루프백 진단을 통해 자신의 요청이 서버에 도달하게 된다면 어떻게 보이게 되는지 알 수 있게 된다. (요청 메시지의 복사본을 받아볼 수 있는 것) 서버는 자신이 받은 요청 메시지를 본문에 넣어서 TRACE 요청의 응답으로 돌려주게 되는 것이다.
TRACE 메소드는 해커가 XST(Cross Site Tracing)의 우회방법으로 사용되어 세션을 탈취할 수 있다는 취약점이 발견되었었다. 하지만 최신 브라우저에서는 우선 막혔다고 하지만 프로덕션에서는 사용하지 않는것을 추천한다.

HTTP 상태 코드란?


자 그러면 HTTP의 상태 코드란 도대체 무엇인가? 개발자라면 개발자 유머를 통해서 이런 짤들을 많이 접해보았을 것이다.
짤과 같이 상태코드(400) + 간단한 텍스트 구문의 조합으로 이루어져있다. 세 자릿수 중 맨 앞자리를 상태 분류를 위해 사용한다. 이는 클라이언트에게 서버가 어떠한 일이 일어났는지를 설명해주는 아주 중요한 코드이다.
하나하나 코드에 대해 알아볼 것인데 사실은 너무 많은 코드가 존재하기 때문에 너무 디테일한 코드는 타이틀만 적고 넘어가도록 하겠다.

1XX: Information response

100번대의 응답은 정보 상태 응답의 코드이다.

100 Continue

클라이언트가 서버로 보낸 요청에 문제가 없으니 다음 요청을 이어서 보내도 된다는 것을 의미한다. 만약 클라이언트의 작업이 완료되었다면 이 응답은 무시해도 된다.
클라이언트가 서버로 하여금 이를 검토하게 하려면 첫 번째 요청에서 Expect: 100-continue를 헤더로 보내야 한다. 이후, 클라이언트는 본문을 보내기 전에 서버가 100 Continue 상태 코드로 응답하기를 기다려야 한다.
서버가 100 Continue를 보냈다는 것은 클라이언트가 본문을 보내기 전에 보내도 되는지 물어보기 위해서 사용한다. 하지만 클라이언트는 마냥 서버를 기다릴 수는 없고(응답이든 에러든 오지 않는다면) 임의의 타임아웃이 지나면 그냥 요청 본문을 보내야 한다. 또한 서버는 해당 응답을 보내기 전에 클라이언트로부터 본문을 받았다면 100 Continue 응답을 보내서는 안된다. 사실 해당 응답은 아직은 받아본적도 없고 구성해본적도 없어서 와닿지 않는 것 같다..

101 Switching Protocol

103 Early Hints

2XX: Successful response

보통 클라이언트가 요청을 보내게 된다면 대부분의 요청은 성공한다. 서버는 성공의 종류에 대응하는 상태코드들을 가지고 있으며 이들을 2XX 코드들로 클라이언트에게 응답한다.

200 OK

아마 가장 많이 보았고, 앞으로도 가장 많이 보게 될 응답이라고 생각한다. 이를 통해 서버가 요청을 성공적으로 처리했다는 것을 알 수 있다.

201 Created

요청이 성공적으로 이루어졌으며 그 결과를 통해서 서버에 새로운 리소스가 생성되었다는 것을 의미한다. 해당 응답은 POST 요청이나 일부 PUT 요청 이후에 응답받는다.

202 Accepted

요청이 성공적으로 접수되었으나 아직 처리중이거나, 처리 시작을 하지 않은 상태를 의미한다. 요청이 처리중에 실패할 수도 있기 때문에 요청의 성공이 보장되지 않는다.

203 Non-Authoritative Information

사용해본적이 없는 것 같다.
이 응답 코드는 돌려받은 메타 정보 세트가 오리진 서버의 것과 일치하지 않지만 로컬이나 서드 파티 복사본에서 모아졌음을 하고, 이러한 조건에서는 이 응답이 아니라 200 OK 응답을 반드시 우선된다고 MDN에 나와있다.

204 No Content

해당 응답 코드는 요청이 성공했으나 클라이언트가 현재 페이지에서 벗어나지 않아도 된다는 것을 나타낸다. PUT 요청에 대한 응답으로 흔히 사용되며 사용자에게 보여지는 페이지를 바꾸지 않고 리소스를 업데이트할 때 사용한다.
말이 약간 헷갈리지만 간단히 이해해보자면 리소스 삭제 후 받는 응답으로 이해하면 더욱 나을 것 같다. 요청은 잘 받아들여져서 처리되었으며 돌려줄 컨텐츠는 없다는 뜻으로 이해하자.

205 Reset Content

206 Partial Content

3XX: Redirection message

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

300 Multiple Choice

클라이언트가 동시에 여러 리소스를 가리키는 URL을 요청한 경우, 그 리소스의 목록과 함께 반환한다. 사용자는 목록에서 원하는 하나를 선택할 수 있다. 예를 들어서 어떤 서버가 하나의 HTML 문서를 영어와 프랑스어 모두로 제공하는 경우와 같은 상황에 사용할 수 있을 것이다.
서버는 Location 헤더에 선호하는 선택사항을 포함시킬 수 있다.

301 Moved Permanently

요청한 URI이 옮겨졌을 때 사용한다. 응답은 Location 헤더에 현재 리소스가 존재하고 있는 URL을 포함해야 한다. 이 때 브라우저는 Location 필드가 존재한다면 해당 필드로 Redirect 한다.

302 Found

이 응답 코드는 요청한 리소스의 URI가 임시적으로 변경되었음을 의미한다. 브라우저는 이를 Location 헤더에 주어진 URL로 일시적으로 이동시키지만 검색엔진이 302를 만나게 될 때 SEO관점에서 해당 페이지의 정보를 갱신하지 않는다.

303 See Other

클라이언트가 요청한 리소스를 다른 URI에서 GET요청을 통해서 얻어야 할 때(확인 페이지 또는 업로드 진행 페이지), 서버가 클라이언트로 직접 보내는 응답이다. 일반적으로 PUT 또는 POST의 결과로 전송된다.

304 Not Modified

요청된 리소스가 이전의 응답과 달라진 점이 없을 경우 재전송할 필요가 없음을 나타낸다. 해당 응답을 받게 되면 클라이언트는 캐시된 자원으로 리소스를 사용하게 된다. 이는 캐시된 자원으로의 암묵적인 리다이렉션이다. 만약 이를 응답으로 받았는데 빈 화면이나 에러 화면이 노출되게 된다면 캐시된 리소스의 유무를 확인해보는것이 좋다.

305 Use Proxy

이전의 HTTP 기술 사양에서 정의되었으며 보안상의 걱정으로 인하여 사라져가고 있습니다.

306 unused

더이상 사용되지 않지만 나중의 사용을 위해서 예약되어있다.

307 Temporary Redirect

308 Permanent Redirect

4XX: Client error response

400번대의 상태 코드는 클라이언트측의 에러를 뜻하는 상태 코드이다. 사실 너무 많기도 하고 직관적인 코드들이 많으니 간단히 빠르게 짚어보겠다.

400 Bad Request

요청을 잘못보냈음을 의미한다. 잘못된 문법으로 전송시에 해당 상태를 볼 수 있다.

401 Unauthorized

비 인증 상태를 의미한다. 예를 들어서 누군지 모르는 사람이 인증이 필요한 어떠한 정보에 접근하려고 한다면 본인이 누구인지 인증해야 함을 의미한다.

402 Payment Required

나중에 사용될 것을 대비하여 예약되어있는 코드이다. 현재는 사용되고 있지 않는 코드이다.

403 Forbidden

클라이언트가 콘텐츠에 접근할 권리를 가지고 있지 않다는 것을 의미한다. 401과 다른 점은 403을 받게 된다면 사용자는 본인을 인증한 상태고 서버는 누구인지 알고 있는 상태라는 뜻이다. 전에 관리자 시스템 개발시에 일반 사용자가 접근하려했을 때 403 코드를 사용하여 에러 코드를 보여줬었다.

404 Not Found

그 유명한 404 Not Found이다. 그냥 "리소스가 없다" 를 표시한다. 또한 인증받지 않은 클라이언트로부터 해당 자원을 숨기기 위해서 사용하기도 한다. 회원 권한에 따라 볼 수 있는 리소스가 다를 경우에 404를 보여주어 리소스를 숨기는 목적으로 403 대신 사용한 적이 있었다. 아마 가장 핫한 상태코드가 아닐까 생각한다 :)

405 Method Not Allowed

해당 메소드는 서버가 알고있지만 사용할 수 없는 상태임을 나타낸다.

406 Not Acceptable

클라이언트가 요청한 Content-Type에 알맞는 리소스가 없을 경우 서버는 이 상태코드를 통해 해당 타입이 없다는것을 응답해준다.

407 Proxy Authentication Required

브라우저와 서버 사이에 있는 프록시 서버에 대한 유효한 인증 자격 증명이 없었기 때문에 요청이 적용되지 않음을 나타낸다.

408 Request Timeout

서버가 클라이언트와 연결되어있는 더이상 사용하지 않는 연결은 끊고 싶을 때 보낸다. 서버가 클라이언트의 본문을 계속해서 기다리기보다는 종료하기로 결정하였다는 것을 알 수 있는 코드이다.

409 Conflict

서버의 현재 상태와 요청이 충돌했음을 나타내는 코드이다. PUT 요청에 대한 응답으로 발생될 (에러?)가능성이 높다. 예를 들어서 서버에 이미 있는 파일보다 오래된 파일을 업로드할 때 409 응답이 발생하여 버전 제어 충돌이 발생할 수 있다.

410 Gone

있었는데, 없었습니다.
서버는 한때 요청한 리소스를 가지고 있었으나 웹 사이트를 유지보수하면서 클라이언트에게 리소스가 영구적으로 삭제되었다는 것을 알려주기 위해 사용한다.

411 Length Required

서버는 해당 요청 메시지로부터 Content-Length를 받고 싶을 때 사용한다.

412 Precondition Failed

413 Payload Too Large

414 URI Too Long

415 Unsupported Media Type

416 Requested Range Not Satisfiable

417 Expectation Failed

418 I'm a teapot

Easter Egg

426 Upgrade Required

428 Precondition Required

429 Too Many Requests

431 Request Header Fields Too Large

5XX: Server errors

400번대가 클라이언트와 관련된 상태 코드였다면 대망의 마지막 섹션인 500번대는 서버의 오류로 인한 상태 코드이다. (여기까지 읽어주셨다면 조금만 더 힘내요....!)

500 Internal Server Error

서버가 클라이언트의 요청을 처리하는 과정에서 예상하지 못하는 상황에 놓였다는 것을 나타낸다. 이는 클라이언트가 에러의 내용을 알 수 없는 구체적이지 못한 응답이다. (사실 서버의 에러를 그대로 알려주는 것 또한 문제일 수도 있다고 생각합니다.)

501 Not Implemented

이는 서버측에 문제가 있어서 서버가 요청할 수 있는 기능을 지원하지 않을 때의 상태 코드입니다. 405는 고의적으로 지원하지 않는 상황이라면 이와는 다르게 서버가 지원하지 못하고 있는 상황이라고 이해하면 쉽다.

502 Bad Gateway

흔히 "서버가 죽었다" 라고 말하는 상황이다.
서버가 게이트웨이나 프록시 서버 역할을 하면서 업스트림 서버로부터 유효하지 않은 응답을 받은 것을 가리킨다.

503 Service Unavailable

해당 코드는 서버가 요청을 처리할 준비가 되지 않았음을 의미한다. 흔하게는 서버가 점검을 위해 다운되거나 오버로드되어 발생한다.

504 Gateway Timeout

408과 마찬가지로 요청에 대한 타임아웃이지만, 게이트웨이 혹은 프록시의 역할을 하는 동안 업스트림서버로부터 요청을 마치기 위해 필요한 응답을 받지 못했음을 나타낸다.

505 HTTP Version Not Supported

506 Variant Also Negotiates

507 Insufficient Storage

510 Not Extended

511 Network Authentication Required

마치며

너무 많은 상태 코드가 있고 이번에는 이를 다 짚어보지는 못했지만, 시간이 지나며 계속해서 더욱 익숙해지는 상태 코드들이 있다면 다시 돌아와서 정리하며 더욱 넓혀가는 시간을 가져야겠다.. 사실 이번주 내내 작성한 게시글이어서 어쨌든 끝마무리를 짓고 싶었다 :)

혹시 잘못된 정보가 있다면 댓글 or 이메일로 저에게 알려주세요. 😉


References

profile
Find The Best Solution 😎

0개의 댓글