요즘은 거의 모든 웹 개발이 프레임워크로 이루어집니다. 레일, Sinatra 또는 Lotus를 사용하든 쿠키 및 기타 헤더가 nginx 또는 apache에서 애플리케이션 서버 및 앱으로 전달되는 방식에 대해 생각할 필요가 없습니다. 그들은 그저 그렇습니다.
우리는 이 여정을 좀 더 깊이 있게 조사할 것입니다. 헤더의 이야기에는 웹의 역사에 대한 흥미로운 정보가 많이 포함되어 있기 때문입니다.
HTTP 헤더란 무엇입니까?
웹 브라우저가 requesnginxt를 만들 때마다 HTTP 헤더라고 하는 이러한 것들을 함께 보냅니다. 여기에는 쿠키, 사용자 에이전트에 대한 정보, 캐싱 정보가 포함되어 있습니다. 정말 유용한 것들이 많이 있습니다.
브라우저의 개발 도구에서 요청을 보면 어떤 헤더가 전송되고 있는지 확인할 수 있습니다. 여기 예가 있습니다. 보시다시피 헤더는 마법 같은 것이 아닙니다. 특정 방식으로 서식이 지정된 텍스트일 뿐입니다.
헤더가 앱에 전달되지 않는 방법
랙 앱을 작성한 적이 있다면 env
앱의 환경 변수가 포함된 해시입니다. 내부를 살펴보면 일반적인 시스템 환경 변수 외에도 모든 요청 헤더가 포함되어 있음을 알 수 있습니다.
# config.ru
run lambda { |env| [200, {"Content-Type" => "text/plain"}, [env.inspect]] }
# Outputs:
# { "HTTP_HOST"=>"localhost:9000", "HTTP_CONNECTION"=>"keep-alive", "HTTP_PRAGMA"=>"no-cache", "HTTP_CACHE_CONTROL"=>"no-cache", "HTTP_ACCEPT"=>"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "HTTP_UPGRADE_INSECURE_REQUESTS"=>"1", "HTTP_USER_AGENT"=>"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36", ... }
이것은 아닙니다 nginx가 앱에 헤더를 전달하는 방법. :)
애플리케이션 서버
오늘날 대부분의 Ruby 웹 앱은 Unicorn과 같은 애플리케이션 서버에서 실행됩니다. 앱 서버는 nginx에 의해 생성되지 않으므로 nginx는 환경 변수를 설정할 수 없습니다.
헤더는 nginx에서 유니콘으로 어떻게 이동합니까? 단순한. nginx가 요청을 앱 서버로 전달할 때 헤더와 모두를 포함한 전체 요청을 보냅니다.
이를 보여주기 위해 nginx가 STDOUT으로 보내는 모든 것을 덤프하는 간단한 애플리케이션 서버를 구축했습니다.
require "socket"
# Create the socket and "save it" to the file system
server = UNIXServer.new('/tmp/socktest.sock')
# Wait until for a connection (by nginx)
socket = server.accept
# Read everything from the socket
while line = socket.readline
puts line.inspect
end
socket.close
Unicorn 대신 이 서버에 연결하도록 nginx를 구성하면 앱 서버에 어떤 정보가 전송되고 있는지 정확히 알 수 있습니다. 바로 일반적인 HTTP 요청입니다. 헤더 및 모든 것.
<블록 인용>
간단한 업스트림 앱 서버를 작성하는 방법에 대한 자세한 내용은 유닉스 소켓에 대한 내 게시물을 확인하십시오.
그러면 왜 환경 변수에 신경을 쓰나요?
1993년 NSCA는 "공통 게이트웨이 인터페이스" 또는 줄여서 CGI라고 하는 사양을 발표했습니다.
Apache와 같은 서버가 디스크에서 임의의 프로그램을 실행하여 동적 웹 페이지를 생성하는 방법이었습니다. 사용자가 페이지를 요청하면 Apache는 문자 그대로 결과를 생성하는 프로그램을 실행하고 실행합니다. Apache는 앱을 직접 생성하므로 환경 변수를 설정할 수 있습니다.
CGI 표준은 HTTP 헤더가 환경 변수로 전달되도록 지정합니다. 그리고 기존 환경 변수와의 이름 충돌을 피하기 위해 이름 앞에 "HTTP_"를 추가하도록 지정합니다.
따라서 다음과 같은 많은 환경 변수가 생깁니다.
HTTP_ACCEPT="text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
HTTP_ACCEPT_CHARSET="ISO-8859-1,utf-8;q=0.7,*;q=0.7"
HTTP_ACCEPT_ENCODING="gzip, deflate"
HTTP_ACCEPT_LANGUAGE="en-us,en;q=0.5"
HTTP_CONNECTION="keep-alive"
HTTP_HOST="example.com"
HTTP_USER_AGENT="Mozilla/5.0 (Windows NT 6.1; WOW64; rv:5.0) Gecko/20100101 Firefox/5.0"
요즘은 새로운 개발을 위해 CGI를 사용하는 사람이 거의 없지만 때로는 가짜 환경 변수인 경우에도 HTTP 헤더가 환경 변수로 저장된 것을 보는 것은 여전히 매우 일반적입니다.
앱 서버가 위조하는 방법
애플리케이션 서버는 원시 HTTP 요청에서 헤더를 구문 분석합니다. 그들은 어떻게 환경에 들어갈 수 있습니까? 음, 앱 서버가 그것들을 거기에 넣습니다.
웹브릭을 조금 뒤져 담배를 피우는 총을 찾을 수 있었습니다.
self.each{|key, val|
next if /^content-type$/i =~ key
next if /^content-length$/i =~ key
name = "HTTP_" + key
name.gsub!(/-/o, "_")
name.upcase!
meta[name] = val
}
결국 이러한 "가짜" 환경 변수는 다른 실제 환경 변수와 병합되어 랙 앱과 Rails로 전달되어 환경 해시에서 다시 가져옵니다. :)