웹을 지탱하는 기술 책을 읽고 정리한 내용입니다.
8. 스테이터스 코드
- 스테이터스 코드의 오용
예) Status Code가 200OK지만, Body에 정상적인 실행결과가 아닌, 에러코드를 반환하고 있는 예
--Request
GET/test HTTP/1.1
Host: api.example.com
--Response
HTTP/1.1 200 OK
Content-Type: application/xml
<error>
<code>1001</code>
<message>file not found</message>
</error>
에러를 200OK로 반환하게 된다면 클라이언트에서는 이 스테이터스 코드를 성공한것으로 믿고 정상 결과로서 바디를 표시하게 된다.
이는 에러를 웹 API측의 의도대로 처리하기 위해서는 전용 클라이언트를 구현해야 하기 때문에 다양한 클라이언트에서 이용할 수 있다는 웹 API의 특징을 훼손하게 된다.
웹 서비스의 경우도, 404 Not Found로 반환해야 할 정보를 200OK로 반환하면 검색 엔진의 로봇이 정식 리소스로 착각하고 인덱스 처리가 수행되어 비리는 등 문제가 발생할 가능성이 있다.
- 스테이터스 코드의 구현
Apache - 정적인 파일을 보내는 경우 보내는 파일의 조건에 따라 자동적으로 스테이터스 코드가 결정된다. 예를들어 요청한 파일이 존재하지 않으면 404 Not Found가 반환되고, 그 파일에 접근하는데 인증이 필요하면 401 Unauthorized가 반환됩니다.
또한 mod_rewrite 모듈을 사용하면 임의의 스테이터스 코드를 반환하도록 설정 할 수 있다.
Servlet - HttpServletResponse 클래스의 setStatus() 메서드와 setError() 메서드를 사용하여 스테이터스 코드를 설정 한다.
단, 수치를 하드코딩하게 되면 소스코드를 이해하기 힘들어진다. 각 스테이터스 코드는 HttpServletResponse의 상수 필드로서 SC_OK(200)나 SC_NOT_FOUND(404)와 같이 정의되어 있으므로 이것을 사용하는편이 좋다.
9-2 HTTP 헤더의 태생
HTTP 헤더는 전자메일 메시지 헤더형식을 빌려왔다
HTTP의 최초의 버전 0.9에는 헤더가 없습니다. HTTP의 스펙 책정이 진행됨에 따라 HTTP로 전소아는 문서의 메타 데이터를 표현하기 위해 전자멩리의 메시지 스펙(RFC 822)의 헤더 형식을 빌려오는 식으로 추가되었습니다.
이때문에 HTTP헤더에는 전자메일의 메시지 헤더와 공통되는 부분이 있습니다.
HTTP 헤더는 라틴 알파벳을 위한 문자 인코딩인 ISO 8859-1이외의 문자가 들어 갈 수 없다.
RFC 822 메시지는 심플한 헤더, 바디 형식의 포맷으로 장점도 많지만, 역사적 경위에서 온 제약이나 부적절한 사용 예도 몇가지 존재한다.
그부분은 헤더에 7bit ASCII 코드 이외의 문자를 넣을 수 없다는 것에 기인한다.
HTTP 헤더에도 역시 문자 인코딩 제한이 있다. 라틴 알파벳을 위한 문자 인코딩인 ISO 8859-1이외의 문자가 들어 갈 수 없다.
캐시
캐시란 서버로부터 가져운 리소스를 로컬 스토리지(하드디스크 등)에 저장하여 재사용하는 방법을 말한다.
캐시용 헤더
클라이언트는 서버에서 가져온 리소스의 캐시 가능 여부를 조사하고 가능한경우는 로컬 스토리지에 저장한다.
또한 어떤 리소스가 캐시 가능한지는 그 리소스를 취득했을때의 헤더로 판단한다.
리소스가 캐시 가능한지, 그 유효기간이 언제까지인지는 pragma, Expire, Cache-Control 헤더를 이용해 서버가 지정한다.
지속적 접속
HTTP 1.1에서의 커다란 신기능이 지속적 접속 이다.
HTTP 1.0에서는 클라이언트가 TCP 커넥션을 확립해 요청을 송신하고 서버가 그에 대한 응답을 반환할 때마다 TCP 커넥션을 절단했다.
TCP 커넥션의 확립은 비용이 드는 처리이기 때문에 이미지나 외부 CSS파일에 많은 링크를 하고 있는 웹 페이지를 표시하려면 아무래도 동작이 느려질 수밖에 없었다.
(아주 작은 이미지 하나를 보내려고 TCP Connection하나를 맺고, 전송하고... 바로 연결 해제 한다고 생각해보자... 그 리소스가 수천 수백개라면....)
이 문제를 해결하기 위해서 HTTP 1.0에서는 Keep-Alive라는 헤더를 이용하여 서버와 클라이언트 사이의 매 요청과 응답시마다 커넥션을 절단하는 것이 아니라, 계속 접속을 유지하여 모아두는 방법이 개발되었다.
Keep-Alive 헤더가, HTTP 1.1에서는 Default가 되었다.
지속적 접속에서는 클라이언트가 응답을 기다리지 않고 같은 서버에 요청을 송신할 수 있습니다. 이것을 파이프라인화 라고 부른다. 파이프라인화에 의해 좀 더 효율적으로 메시지를 처리 할 수 있다.
커넥션을 끊고 싶을 때는 요청의 Connection 헤더에 Close라는 값을 지정하면, '이 요청의 응답이 반환된 후 접속을 끊는다' 라는 의도가 서버에게 전달된다.
GET /test HTTP/1.1
Host: example.com
Connection: close
+ 추가 : 여태까지 클라이언트와 서버가 상태를 지속적으로 주고받기 위해서는 웹소켓이나, Ajax를 이용 한 폴링 방식만 생각했었는데... Keep-Alive 헤더를 이용해서(마찬가지로 Polling이겠지만..) 도 구현 할 수 있을것 같다.
'Today I learned' 카테고리의 다른 글
SNI 개념과 차단 우회방법 (0) | 2019.08.04 |
---|---|
group by의 키로 지정된 컬럼 외에도 다른 컬럼을 출력해야 할때- (0) | 2019.07.21 |
HttpServletXxx 관련 메서드 Cheet Sheat (0) | 2019.07.16 |
자바로 배우는 리팩토링 입문 4 (0) | 2019.07.14 |
자바로 배우는 리팩토링 입문3 (0) | 2019.07.13 |
댓글