[PHP] HTTP/3으로 통신할 때 값이 비는 $_SERVER['HTTP_HOST'] 변수

  다른 경우에는 어떤지 모르겠지만, nginx와 HTTP/3으로 통신하는 웹 서버에서는 PHP의 서버 환경 변수 가운데 $_SERVER['HTTP_HOST']의 값이 비어 있을 수 있다. HTTP/2 이하로 통신할 때에는 $_SERVER['HTTP_HOST'] 변수가 값이 비지 않는다.

  $_SERVER['HTTP_HOST'] 값이 비는 것에 대비하지 않고 이 변수를 인증 정보나 주소 정보에 값을 쓰는  PHP 프로그램은 HTTP 3.0으로 통신할 때에 인증이 되지 않거나 잘못된 주소에서 정보를 부를 수 있다. 속을 모르면 HTTP/3 통신에 잘못이 없어도 HTTP/3이 아직 불안정해서 그렇다고 여길 만 하다.

HTTP/1.1, HTTP/2, HTTP/3의 전송 규약 스택 (HTTP, TLS, SSL, TCP, UDP, QUIC)
HTTP/1.1, HTTP/2, HTTP/3의 전송 규약 스택 (HTTP, TLS, SSL, TCP, UDP, QUIC)
TLS 1.2을 쓰는 TCP와 견준 QUIC의 주고받기(handshake)
TLS 1.2을 쓰는 TCP와 견준 QUIC의 주고받기(handshake)

  값이 비어 나오는 $_SERVER['HTTP_HOST']를 갈음하기 좋은 변수는 $_SERVER['SERVER_NAME']이다. $_SERVER['HTTP_HOST']에는 이용자가 접속한 주소가 담기고, $_SERVER['SERVER_NAME']에는 서버에서 지정한 주소가 담긴다.

  두 변수에 관한 설명은 아래 글에 자세하게 나와 있다.

  $_SERVER['HTTP_HOST']와 $_SERVER['SERVER_NAME']이 모두 값이 빌 수는 있지만, $_SERVER['HTTP_HOST'] 값이 있으면 $_SERVER['SERVER_NAME']은 값이 비지 않는다고 한다.

  HTTP/3은 이용자가 접속하는 주소가 달라지더라도 끊김이 적고 빠르게 통신하는 것을 목적으로 내세우고 있다. $_SERVER['HTTP_HOST']는 웹 정보를 요청하는 쪽의 형편에 따라 달라질 수 있고 조작될 수도 있다. 그래서 이용자 쪽에서 알려 주는 $_SERVER['HTTP_HOST']를 HTTP/3 통신에서는 챙기지 않는지도 모른다.

  이런 경우에 대비하여 덩치가 큰 웹 프로그램은 자주 쓰이는 서버 환경 변수의 값을 맞추는 곳이 따로 있기도 한다. $_SERVER['SERVER_NAME']을 써서 $_SERVER['HTTP_HOST']에 값을 따로 넣는다면, HTTP/3을 쓰는 때에도 웹 프로그램에서 $_SERVER['HTTP_HOST'] 변수를 쓸 수 있다.

  많은 경우에는 아래처럼 넣어도 잘 작동할 것이다.

if(!isset($_SERVER['HTTP_HOST'])) {
$_SERVER['HTTP_HOST'] = $_SERVER['SERVER_NAME'];
}
  하지만 두 변수의 값은 때에 따라 다를 수 있다. $_SERVER['HTTP_HOST']에는 '123.123.123.123:8080'이나 'domain.com:4321' 같은 꼴로 포트 번호가 함께 들어갈 수 있다. $_SERVER['SERVER_NAME']에는 '123.123.123.123'이나 'domain.com' 같은 IP 주소 또는 도메인 주소만 들어가고, 포트 번호는 $_SERVER['SERVER_PORT']에 따로 들어간다.

  포트 번호가 80 또는 443일 때에는 웹 주소에 굳이 포트 번호를 넣지 않으므로 $_SERVER['HTTP_HOST']와 $_SERVER['SERVER_NAME']의 값이 같다. 하지만 다른 포트 번호가 쓰이면 두 변수의 값이 다를 수 있다.

  포트 번호까지 들어가는 주소는 아래처럼 넣을 수 있다.

if(!isset($_SERVER['HTTP_HOST'])) {
$_SERVER['HTTP_HOST'] = $_SERVER['SERVER_NAME'].($_SERVER['SERVER_PORT']==80 || $_SERVER['SERVER_PORT']==443 ? '' : ':'.$_SERVER['SERVER_PORT']);
}

  웹 프로그램에 따라 서버에서 접속 주소를 강요할 수도 있고 이용자가 접속한 주소를 존중(?)하는 때도 있다. $_SERVER['HTTP_HOST']를 단순하게 $_SERVER['SERVER_NAME']과 $_SERVER['SERVER_PORT']로 갈음할 수도 있지만, 웹 프로그램의 성격과 형편에 따라 $_SERVER['HTTP_HOST']를 살려 쓰는 방안도 저울질해 봄직 하다.

  HTTP/3으로 통신한 뒤에 로그인 인증이 되지 않았다면, 웹 프로그램을 잘 고친 뒤에도 $_SERVER['HTTP_HOST']가 빈 채로 잘못 들어간 인증 정보가 남아서 인증되지 않을 수 있다. 그런 때에는 서버에 있는 웹 프로그램의 세션 정보나 이용자의 컴퓨터에 있는 웹 누비개(브라우저)의 쿠키 정보를 지워야 할 수 있다.

글 걸기 주소 : 이 글에는 글을 걸 수 없습니다.

덧글을 달아 주세요