iOS개발 시 주의해야 할 http status code (feat. 301, 205)

iOS앱을 개발하면서 서버와 통신을 통해 데이터를 가져오는 작업을 하게 됩니다. API 명세에서 response body도 중요하지만 status code도 주의 깊게 살펴봐야 합니다.
status code를 잘못 사용하면, 앱 삭제후 재설치 등 사용자 경험에 치명적인 이슈가 발생할 수 있습니다.

iOS개발에서의 HTTP

http에 대한 설명은 위키백과를 참고해주세요. HTTP에 대한 이해 link
http프로토콜은 위 백과의 내용을 보시면 굉장히 양이 많고 복잡함을 알 수 있습니다. 그렇기 때문에 대부분 Obj-C의 경우 AFNetworking, Swift의 경우 Alamofire 라이브러리를 이용해 쉽게 response를 가져오고 사용할 수 있도록 개발하고 있습니다.
위 라이브러리 덕분에 http에 대한 이해도가 부족하더라도 iOS에서 http를 쉽게 사용하여 개발할 수 있지만, 조금 더 나은 iOS개발자가 되기 위해서 주의해야 하는 http status code 정도는 알아둬야 하지 않나 생각합니다.

iOS앱을 망칠 수 있는 status code

필자가 iOS앱을 개발하면서 잘못된 http status code로 인해 앱 삭제 후 재설치, API 응답 지연 등 사용성에 크리티컬한 이슈를 때려 맞았던 status code와 대응방안을 공유합니다.
http status code 스펙을 볼 수 있는 사이트 https://httpstatuses.com/

301 (Moved Permanently) 영구적 리다이렉트

301 spec link

이슈가 발생되는 상황
301로 잘못된 url을 내려 받는 경우. 서버 복잡도가 높은 경우 gateway를 두고 여러 서버로 redirect를 해주는 구조를 갖게 되는데요. 이 때 gateway의 잘못된 배포로 http 301 code와 함께 잘못된 url이 내려온다면? 앞으로 잘못된 url로 매번 request를 보내며, 매번 실패합니다.

특이사항
301의 의미, Moved Permanently 말 그대로 301 code로 내려받은 url의 생존주기는 앱의 생존주기와 동일합니다. 앱이 삭제 후 재설치 되지 않는 이상 절대 변경되지 않습니다. (Andorid의 경우 불행중 다행인지 표준을 지키지 않아, 몇시간, 몇일 뒤 잘못된 url이 휘발됩니다.)

디버깅이 굉장히 어렵습니다. 코드상에서는 없는 url, 잘못된 url로 계속 request를 보내고 있는데, 왜 보내는지 알 방법이 없고 프록시로 요청을 뜯어보지 않는이상 잘못된 url조차도 알 수 없습니다. ~Charles 만세~

API 응답이 정상적으로 오지 않고, 프록시 확인 결과 잘못된 URL, 클라이언트 코드 상에 없는 잘못된 URL로 계속 요청을 보내고 있다면 301로 잘못된 response를 받은 적이 있는지 확인보세요.

올바른 사용법
301를 대체할만한 status code로 302, 307가 있습니다. 302 spec link, 307 spec link
302는 일회용 리다이렉트라고 생각하면 됩니다. 클라이언트 내부적으로 url을 저장하지 않으므로 잘못된 요청이 오더라도 수정이 가능합니다.
307도 302와 기본적인 동작은 동일합니다. 다른점은, redirect될 때 http method 변경은 불가합니다.

205 (Reset Content) 새 문서 없음. 하지만 브라우저는 문서 창을 리셋해야 함.

205 spec link

이슈가 발생되는 상황
205 status code는 직접적으로 영향을 주는 것은 아니지만 iOS의 속성과 합쳐져 이슈를 발생시킬 수 있습니다.

1. 205의 잘못된 사용

status code 205 를 사용하는 response의 header의 content-length가 0이 아닌 경우.
iOS는 response header의 content-length가 0이 아닌 경우, body를 읽습니다. body가 content-length 값보다 작은 경우 iOS는 body 데이터를 기다립니다… 기다리다가 timeout 시간(default 60sec)이 지나면 timeout으로 connection이 닫히게 됩니다.

위 상황에서 발생하는 현상은, 205 status code를 주는 API를 호출 할 때마다 60sec 짜리 connection이 생성됩니다. 각각의 connection은 timeout 시간(default 60sec) 에 도달할 때까지 유지됩니다. (Hang이 걸린다고 표현하죠)

2. iOS의 기본 속성

Swift httpMaximumConnectionsPerHost 프로퍼티 link
iOS에는 httpMaximumConnectionsPerHost라는 프로퍼티가 있습니다. host별로 가질 수 있는 동시 connection 수 입니다. iOS의 경우 4를 기본값으로 가집니다.
각 host에 동일한 connection이 5개가 생성되면 5번째 request는 무시됩니다. (아예 요청조차 하지 않음)

1 + 2 = Bomb

위에서 설명한 1, 2를 더하면..? 폭탄이 됩니다.
60sec 짜리 connection 4개가 생성된 이후에 클라이언트는 어떠한 API도 호출하지 않습니다. 보통 response를 보고 UI를 그리거나, 에러페이지를 그리지만,, request조차 하지 않는 API에서는 답이 없습니다.

특이사항
205로 response를 내려받은 상황이기 때문에, 클라이언트앱은 정상적으로 response를 완료했다고 판단합니다. (200 번대 status code).
Android의 경우, 동시 connection 제한이 없는지 위의 이슈가 발생하지 않았습니다.

올바른 사용법
205의 스펙을 지키면 됩니다. 205 spec link
위 링크에 잘 정리되어 있지만 여기에도 적어보자면

  1. Header의 Content-Length 값은 0 이어야 합니다.
  2. 그에 맞춰 실제 Body의 데이터는 없어야 합니다.

HTTP를 잘 쓰는 iOS 개발자

이번에 소개한 205, 301외에도 주의해야 하는 status code가 더 있을 수 있습니다. (아직 제가 모든 status code를 사용해보지 못했습니다).
새로운 API를 연동할 때, 명세에 status code가 새로운 것이 있다면 꼭! https://httpstatuses.com 에서 스펙을 확인 하신 후 표준에 맞춰 개발하시기 바랍니다.

0%