문제 발생
HTTP request 받는 서버를 변경하면서 에러가 발생했다.
정상적인 경우라면 response body 에 key 값만 있어야 하는데, key 값(123456) 뒤에 에러메세지가 append 되고 있었다. 에러메세지는 HTTP response 에 해당하는 모든 정보였다.
123456HTTP%2F1.1+408+Request+Time-out%0D%0AContent-length%3A+110%0D%0A
Cache-Control%3A+no-cache%0D%0AConnection%3A+close%0D%0AContent-Type%3A+text%2F
html%0D%0A%0D%0A%3Chtml%3E%3Cbody%3E%3Ch1%3E408+Request+Time-out%3C%2Fh1%3E%0D%0A
Your+browser+didn%27t+send+a+complete+request+in+time.%0D%0A%3C%2Fbody%3E%3C%2Fhtml%3E%0D%0A
원인
결론부터 말하면, request를 보내는 client 가 HTTP request spec 에 맞지 않게 보내고 있었다. HTTP request spec은 아래와 같다. header 와 body 를 구분하기 위해 CRLF 가 사용되지만, body 가 끝난후에는 CRLF 를 추가하지 않는다.
Request-Line
*(( general-header | request-header | entity-header ) CRLF)
CRLF
[ message-body ]
하지만 에러가 발생하는 request 에서는 body 마지막에 CRLF 두개를 추가해서 전달하고 있었다.
0d0a 가 \r\n 이고 CRLF다.

어떻게 기존 서버에서는 문제없다가 새로운 서버에서만 에러가 발생했을까?
keep-alive 설정 차이 때문이었다. keep-alive 는 HTTP/1.1 기본스펙이다. 그래서 새로운 서버에서는 추가 설정없이 그대로 사용하고 있어서 커넥션이 계속 맺어져 있는 상태였다. body 마지막에 CRLF 가 있어서 서버는 body 데이터가 아직 안끝났다고 판단하고 reqeust 가 또 들어오는것으로 인지했다. 그래서 첫번째 response 는 정상적으로 전달했고 두번째 request 를 기다리다가 timeout이 발생했다. 즉 client에서는 첫번째 response 를 받고 두번째 response 를 계속 기다리다 에러가 발생한 것이다.
기존 nginx 서버에서는 keep-alive 사용을 안하고 있어서 문제가 발생 하지 않았다. 디폴트 옵션인 keep-alive 를 왜 꺼놨는지 따로 기록해놓은게 없었기 때문에 미리 파악하기는 불가능했다.
해결방법
client 가 HTTP request spec 에 안맞는 요청을 보냈기 때문에 client 에서 수정 하는게 맞지만 그럴 수 없었다. API 연동 가이드 문서를 보니까 body 에 해당하는 $queryString 뒤에 CRLF 를 두개 추가하고 있었기 때문이었다.
...
fwrite($nc_sock, "Content-type: application/x-www-form-urlencoded; charset=utf-8\r\n");
fwrite($nc_sock, "Content-length: ".strlen($queryString)."\r\n");
fwrite($nc_sock, "\r\n");
fwrite($nc_sock, $queryString."\r\n");
fwrite($nc_sock, "\r\n");
잘못된 가이드로 이미 많은 client 들이 저렇게 request 를 보내고 있었고 지금까지 에러없이 동작했던 API 였기 때문에 서버쪽에서 keep-alive 설정을 끌 수밖에 없었다. 대신 성능상의 이슈가 있으니 문제가 되는 특정 path 만 keep-alive 를 끄기로 했다.
'Http' 카테고리의 다른 글
WebClient 프록시(CONNECT HTTP Method) (0) | 2022.11.27 |
---|---|
GET / POST 를 목적에 맞춰 사용하지 못한 케이스 (0) | 2021.06.18 |
Cookie SameSite Lax 모드 업데이트 정리 (0) | 2021.04.08 |
Cookie SameSite 기본편 (0) | 2021.02.05 |
https + id/pw rsa 암호화 (0) | 2021.01.31 |