Перенаправление Grails - почему оно всегда абсолютное? - PullRequest
4 голосов
/ 08 марта 2011

У меня есть два Jetty AppServer, работающие с веб-приложением Grails за обратными прокси-серверами Apache 2.2. Завершение SSL выполняется апачами, которые передают HTTP к серверам приложений Jetty.

Когда веб-приложение Grails выполняет перенаправление следующим образом

redirect(action:'index')

конечный пользователь получает запрос перенаправления HTTP 302 с полным URL-адресом, который использует протокол http://, а не https://:

HTTP/1.1 302 Found
Date: Tue, 08 Mar 2011 17:50:46 GMT
Server: Jetty(6.1.17)
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Location: http://hostname.domain/web/?lang=en

Это раздражает, поскольку все HTTP-запросы перехватываются прокси-сервером и перенаправляются на HTTPS-запросы. Так что это ненужный туда-обратно.

Я вижу два решения:

  1. Apache mod_proxy может переписать этот Location-заголовок в https: // перед передачей ответа пользователю. (Может ли это?)
  2. Grails может просто не использовать абсолютные URL при перенаправлении: Location: /web/?lang=en

Первый вариант немного глуп, я думаю, верно?

Есть ли у вас какие-либо идеи о том, как я могу получить grails для отправки не абсолютных заголовков перенаправления (в идеале, без необходимости переключать каждый редирект на использование uri:)?

РЕДАКТИРОВАТЬ: В настоящее время у меня есть обходной путь после первого подхода путем изменения заголовков ответа (a2enmod headers, затем добавьте Header edit Location ^http://(.*)$ https://$1 в <Location>). Вдохновение приходит от этого сообщения о неисправности сервера . Я все еще хотел бы знать, почему это необходимо в первую очередь.

1 Ответ

6 голосов
/ 09 марта 2011
Для HTTP 1.1 RFC требуется перенаправление

302, чтобы оно было абсолютным , а не относительным местоположением. Даже если это работает в некоторых браузерах, они выходят за рамки спецификации, и я уверен, что некоторые реализации не будут работать правильно, если вы сделаете относительный URL.

Причина, по которой вы видите эту проблему, заключается в том, что прекращение SSL происходит на apache, и apache делает ванильный HTTP-запрос к Jetty. Таким образом, Jetty получает ванильный, не HTTPS-запрос, поэтому она не знает, отправлять ли HTTPS-ответы вместо обычных HTTP-ответов. Если бы вы выполняли SSL-терминацию в Jetty, у вас не было бы этой проблемы (но Jetty не так уж хорош в терминации SSL).

Мы справились с этим в нашем приложении (apache / HA Proxy-> Tomcat), имея значение конфигурации для каждой среды, которое жестко кодирует протокол ответа (в любом случае нам нужно связываться с URL, потому что это мультитенантная система много потенциальных имен хостов, длинная история ... :), но ваше решение с apache тоже работает.

...