Work hard, have fun and make history.

개발/HTTP 완벽가이드

[HTTP 완벽가이드] 8장 통합점: 게이트웨이, 터널, 릴레이 > 8.6 릴레이

bluecandle37 2022. 10. 4. 19:50
728x90

[HTTP 완벽가이드] 8장 통합점: 게이트웨이, 터널, 릴레이 > 8.6 릴레이

 

8.6 릴레이

HTTP 릴레이는 HTTP 명세를 완전히 준수하지는 않는 간단한 HTTP 프록시.

릴레이는 커넥션을 맺기 위한 HTTP 통신을 한 다음, 바이트를 맹목적으로 전달함.

맹목적으로 전달한다는게 무슨말이지?? 커넥션 상태에 상관없이 무조건 전달한다는 의미인가??

이후 내용 살펴보니, 무지성 전달이 더 맞는 표현인듯! 무슨 뜻인지 모르지만 일단 그냥 다 전달 ㄱㄱㄱ 이런 느낌.

 

어쨌든 이렇게 모든 헤더와 메소드 로직을 수행하지 않고 맹목적으로 트래픽을 전달하는 간단한 프록시 방식이 유용할 때가 있음.

단순 필터링이나 진단 혹은 컨텐츠 변환을 하는데 사용되기도 함. 근데, 잠재적으로 심각한 운용 문제를 가지고 있기 때문에 주의해서 배포.

 

단순 맹목적 릴레이 구현 관련하여 더 일반적인(악명 높은) 문제 중 하나는 맹목성 릴레이가 Connection 헤더를 제대로 처리하지 못해서 keep-alive 커넥션이 행(hang)에 걸리는 것.

 

HTTP 완벽가이드, 인사이트, p. 244. 단순 맹목성 릴레이가 행(hang)에 걸리는 경우.

그림 설명

  • [a] 클라는 Connection : Keep-Alive 헤더를 보내서, 릴레이에 keep-alive 커넥션 맺고 싶다고 알리고 응답 기다림.

 

  • [b] 릴레이가 HTTP 요청 받지만 Connection 헤더를 이해하지 못하므로 (맹목적 전달), 그냥 단순하게 서버로 요청 넘김. 근데 Connection 헤더는 홉과 홉 사이(hop-by-hop)에만 사용하는 헤더임. 단일 전송 링크만을 지원하고 체인을 따라 전달 할 수 없음.

 

  • [b] 릴레이 된 요청이 웹 서버에 도착. 웹 서버는 릴레이가 keep-alive 하길 바란다고 판단. 보통 클라한테는 그렇게 하니까 ㅇㅇ 웹 서버는 할 일을 했을 뿐임.

 

  • [c] 그래서, 웹 서버는 keep-alive 통신에 동의하고 Connection : Keep-Alive 헤더와 함께 응답. 이제 웹 서버는 릴레이와 함께 keep-alive 통신을 하고, keep-alive 규칙에 맞게 동작할 것임. 근데 문제는... 릴레이는 무지성이라서 keep-alive 에 대해 모른다!

 

  • [d] 릴레이는 웹 서버로부터 받은 Connection : Keep-Alive 헤더를 포함한 응답 메시지를 클라에게 전달. 클라는 릴레이가 keep-alive 통신에 동의했다고 추측함. 클라 잘못이 아님! 근데, 실제로 통신을 이어주는 릴레이가 아무것도 모르는 상태.

 

  • 릴레이는 keep-alive 에 대해 모르기 때문에, 원 서버가 커넥션을 끊기를 기다리며 받은 데이터 전부를 그대로 클라에게 전달. 하지만 원 서버는 릴레이가 자신에게 커넥션을 계속 맺고 있기를 요청했다고 믿기 때문에 커넥션을 끊지 않음! 그래서, 릴레이는 커넥션이 끊길 때를 기다리며 계속 커넥션을 맺고 기다리는(hang) 상태가 된다.

 

  • [e] 클라는 [d] 에서처럼 응답을 받으면, 바로 다음 요청을 보냄. 근데, 릴레이는 같은 커넥션으로 또 다른 요청이 오는 것을 예측하지 못함. 왜?? keep-alive 의 규칙이 뭔지 모르니까! 결국, 브라우저는 계속 돌고 있지만, 아무런 작업도 진행되지 않는 상태가 만들어짐.

 

위와 같은 상황을 방지하기 위해 릴레이를 조금 더 똑똑하게 만드는 방법이 있지만, 애초에 단순하게 만들어 놓으면 상호 운용과 관련한 문제가 발생할 위험이있음. 특정 목적을 위해 단순 HTTP 릴레이를 구축하려고 한다면, 어떻게 사용할지 신중하게 고민해야 하는 이유!

근데, 그냥 HTTP를 제대로 준수하는 프록시 사용이 더 좋아 보인다.

728x90