Недавно мы изменили хостинг на initialized.com и столкнулись с тем, что стало очень распространенной задачей на протяжении многих лет, а именно с настройкой перенаправления на наш канонический домен и порт, в частности, обеспечение перенаправления запросов на субдомен www и HTTP-запросов на https://initialized.com при сохранении пути запроса. Это довольно простая задача, когда вы запускаете свой собственный веб-сервер, но со статически сгенерированным сайтом, таким как наш, нам пришлось искать где-нибудь еще, чтобы разместить логику перенаправления.

Сразу же меня осенило, что это отличный вариант использования нового Edge Apps нашей портфельной компании Fly. С помощью небольшого количества кода мы можем настроить всю необходимую нам логику перенаправления, а затем развернуть наше пограничное приложение на всех пограничных узлах Fly по всему миру, обеспечивая перенаправление с малой задержкой из любого места.

Приложения Fly Edge реализованы как простые приложения Javascript. На высоком уровне главное требование - вызвать fly.http.respondWith с функцией, которая принимает объект Request и возвращает объект Response. Вот как это выглядит для пограничного приложения, которое перенаправляет все HTTP-запросы на HTTPS:

fly.http.respondWith((req) => {
  const url =  new URL(req.url)
  let redirectNeeded = false
  if (url.protocol !== 'https:') {
    redirectNeeded = true
    url.protocol = 'https'
    url.port = '443'
  }
  if (redirectNeeded) {
    return new Response(
      'Redirecting',
      {
        status: 301,
        headers: { 'Location': url.toString() }
      }
    )
  } 
  
  return new Response('No redirect needed!', { status: 200 })
})

Выше мы использовали объект URL для анализа URL-адреса входящего запроса, что упрощает последующую проверку протокола запроса. Если он не совпадает с https:, мы можем обновить только протокол и порт URL-адреса и вернуть объект Response со статусом перенаправления и заголовком Location. В противном случае мы можем дать успешный ответ. Если бы весь наш сайт обслуживался приложением Fly edge (хорошая идея по другим причинам), мы бы сделали что-нибудь еще для последней строки функции, например, получили бы запрос из бэкэнда Fly и проксировали его.

Чтобы развернуть это, нам сначала нужно создать учетную запись Fly на fly.io. Затем, если у нас установлен Node, мы можем использовать терминал для установки двоичного файла Fly и войти в нашу учетную запись Fly. В оболочке:

npm install -g @fly/fly
fly login

Затем мы можем поместить приведенный выше код в файл с именем index.js, настроить приложение Fly и развернуть! (вы бы изменили redirects-test на свое собственное уникальное имя приложения Fly). Снова в оболочке:

fly apps create redirects-test
fly deploy -a redirect-test

Сразу мы можем проверить это и увидеть перенаправление:

> curl -I http://redirects-test.edgeapp.net/
HTTP/1.1 301 Moved Permanently
Date: Fri, 15 Jun 2018 00:41:00 GMT
Fly-Request-Id: bHmOra288bOTGBD4wh6d6jPU1D
Location: https://redirects-test.edgeapp.net/
Server: Fly.io/0.1.1
Content-Type: text/plain; charset=utf-8

Затем довольно легко добавить еще одно предложение if для проверки канонического имени хоста и перенаправления при необходимости:

const canonicalHostname = 'example.com'
if (url.hostname !== canonicalHostname) {
  redirectNeeded = true
  url.hostname = canonicalHostname
}

И если мы протестируем снова, мы увидим, что и протокол, и имя хоста обновляются в перенаправлении:

> curl -I http://redirects-test.edgeapp.net/
HTTP/1.1 301 Moved Permanently
Date: Fri, 15 Jun 2018 00:43:26 GMT
Fly-Request-Id: bHmOrXMzWz0FSdPPAm4AmJzT04
Location: https://example.com/
Server: Fly.io/0.1.1
Content-Type: text/plain; charset=utf-8

Чтобы перейти к производству, нам просто нужно привязать DNS нашего домена к нашему приложению Fly и сообщить им, какие имена хостов следует направить в наше приложение (снова замените www.example.com ниже своим доменом и используйте свое уникальное имя приложения Fly). Снова в оболочке:

fly hostnames add www.example.com -a redirects-test

Более того, я собрал некоторую общую логику перенаправления для быстрой интеграции, посмотрите ее на Github:



С приложениями Fly Edge вы можете сделать гораздо больше, поэтому просмотрите их документацию, чтобы узнать больше!