-
Handshake failed due to invalid Upgrade header: null 알아보자Protocol/HTTP 2023. 12. 12. 14:57
들어기가전에
iOS 클라이언트와 Simple(or Streaming) Text Orientated Messaging Protocol(STOMP) 통신을 하는데 SPRING 서버에서 Handshake failed due to invalid Upgrade header: null 오류가 발생했고 해결과정을 작성해보려고 한다.
해결 포인트는 공식 레퍼런스에 있다
이전 포스팅에서(https://doit94.tistory.com/80) 확인한 것처럼 웹서버(ex. nginx)를 거쳐서 뒷단에 SPRING 이 동작할 때는 웹 서버단에서 프록시 설정을 할 확률이 높다는 안내가 떠올랐다!
다시 한번 오류 내용을 짚어보자면,
$ ERROR "Handshake failed due to invalid Upgrade header: null"
HTTP 요청으로 HTTP Upgrade 헤더를 만들고 Connection 헤더의 값을 Upgrade를 사용하게 만들지 못하는 상황이다!
위 내용이 원인이지만 근본 원인은 따로 있다.
왜? HTTP Upgrade 헤더를 만들지 못할까? 여기서 `포워드 프록시`, `리버스 프록시` 개념을 알아야 한다.
포워드 프록시와 리버스 프록시
먼저, 프록시 개념을 가볍게 알아보자. 프록시를 사용하는 다양한 사례가 존재하지만 부하 분산 장치를 사용하게 되었을 때 프록시를 주로 사용한다. 클라이언트에서 요청이 오면 부하 분산 장치가 listener 로 확인하고 도메인 네임, IP 주소 등을 통해 해당하는 웹 서버로 요청을 분배하는 것이다.
여기서 재밌는 정보는 프록시라는 구조는 원래 클라이언트 측에 두는 방법에서 시작되었다. 이 유형이 프록시의 원형으로 `포워드 프록시`라고 한다.
포워드 프록시가 처음 등장했을 때 캐시를 이용하는 것이 목적이었고 방화벽을 실현한다는 중요한 목적이 한 가지 더 있었다.
이 목적을 달성하기 위해 가장 현실적인 방법은 패킷 왕래를 전부 정지시키는 것이다. 그러나 패킷을 전부 정지시키면 인터넷에 대한 액세스도 정지된다. 이렇게 하여 필요한 것을 통과시키는 방법을 생각하기 위해 `프록시` 라는 구조를 고안한 것이다.포워드 프록시는 메시지를 전송하는 동작도 서버측에 두는 캐시 서버가 웹 서버를 판단하는 부분이 약간 다르다. 포워드 프록시를 사용할 때 URI 부분에 http://~~~ 라는 URL이 그대로 쓰여있어 웹 서버를 사전에 설정해둘 필요없고 모든 웹 서버에 전송할 수 있다.
포워드 프록시를 사용할 경우 브라우저에 대한 설정이 꼭 필요한데 설정이 번거롭고 잘못 설정한 경우에는 브라우저가 제대로 작동하지 않는다. 이에 따라 브라우저에 프록시를 설정하지 않아도 사용할 수 있도록 개량되었다. 리퀘스트 메시지의 URI에 쓰여있는 디렉토리 명과 전송 대상의 웹 서버를 대응시켜서 URI 부분에 http://~~~ 라고 쓰여있지 않은 보통의 리퀘스트 메시지를 전송할 수 있도록 했다. 이것이 서버 측 캐시 서버가 채택한 방식으로 `리버스 프록시`라고 부른다.
여기까지의 정보를 종합해서 내 상황과 연결해보면,
- iOS 클라이언트에서 요청이 왔다
- 해당 요청은 nginx 프록시 구조로 통한다
- nginx는 클라우드 서버측에 설치되어 있기 때문에 서버측 판단이 필요한 리버스 프록시이다
- 리버스 프록시로 동작하는 nginx 설정을 변경 해야한다
프록시 서버(nginx, 그림에서는 캐시), 프록시 뒷 단(spring, 그림에서는 웹), 클라이언트(iOS)
해결방안
# nginx 80 포트로 요청이 들어오면 아래 프록시 경로로 보내준다. location / { proxy_pass http://아이피주소; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } # 게이트웨이 역할을 하는 nginx 설정에서 아래 프록시 헤더 설정을 추가한다. location / { proxy_pass http://아이피주소; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_http_version 1.1; }
리버스 프록시 역할을 하는 nginx 설정을 추가하면 해결된다.
'Protocol > HTTP' 카테고리의 다른 글
HTTP 메서드 속성을 알아보자 (0) 2023.12.23