이미 spring 프로젝트로 S3에 이미지를 저장하는 api를 만들어서 EC2에 배포한 상황에서 팀원이 2mb 크기의 이미지를 업로드하니 413 에러가 발생한다고 말해주었다.
기존에 크기가 작은 이미지들에 대해서는 테스트를 통과했고, application.yml을 통해 받을 수 있는 multipartFile 형식의 크기를 20mb로 잡아놓았기 때문에 문제가 발생하지 않을 거라고 생각했기 때문에 해당 소식을 들었을 때 당황했지만 금방 문제를 해결할 수 있었다.
현재 EC2 서버에서는 nginx 를 통해 리버스 프록시 및 ssh 인증을 해둔 상태였다. 이런 상황에서 413 에러에 대해 검색하고 nginx docs를 찾아보니 다음과 같은 결과를 얻을 수 있었다.
Sets the maximum allowed size of the client request body. If the size in a request exceeds the configured value, the 413 (Request Entity Too Large) error is returned to the client. Please be aware that browsers cannot correctly display this error. Setting size to 0 disables checking of client request body size.
즉, client request body에서의 최대 사이즈를 따로 정의하지 않아서 발생한 문제였다. 따로 client_max_body_size를 명시하지 않으면 Default 값으로 1mb가 설정되기 때문에 1mb를 초과하는 이미지는 413 에러를 발생하는 문제였다. 따라서 해당 client_max_body_size의 크기를 적절하게 명시해 주어서 문제를 해결할 수 있었다.
3. 추가적으로 마주한 에러
찾아보니 다음과 같은 형태들로 client_max_body_size를 설정했다.
http {
client_max_size 20M;
}
그래서 동일하게 기존의 /etc/nginx/sites-available/{설정파일} 위치에 있는 커스텀 설정 파일에 http로 감싼 뒤에 client_max_size를 추가했다. 그리고 nginx를 다시 실행했더니 다음과 같은 에러가 발생했다
"http" directive is not allowed here in /etc/nginx/sites-enabled/
즉, http 블록의 위치가 올바르지 않아서 발생한 문제였다. 분명 코드도 문제가 없는 거 같아서 추가적인 검색을 통해 다음의 stackoverflow에서 해답을 얻을 수 있었다.
여기서 말하는 것은 해당 http블록은 /etc/nginx/nginx.conf에 작성되어 있고 http 블록 하위에서 해당 /sites-enabled를 참조하고 있기 때문에 추가적인 http를 작성할 필요가 없다는 것이었다. 그래서 http를 빼고 client_max_size만 작성하니 1mb를 넘어가는 이미지에 대해서도 정상적으로 S3에 저장되는 것을 확인할 수 있었다
4. 너낀점
nginx에 대해서도 공부할게 많다고 느꼈다. docs를 읽어보는데 설정 api만 몇백 개는 되는 거 같았다. 재밌었다