Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions conf/http/errorpages/errorpages.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
load_module modules/ngx_http_js_module.so;

events { }

http {
js_path /etc/nginx/njs/;

js_import utils.js;
js_import http/errorpages/errorpages.js;

js_set $badRequest errorpages.badRequest;

map $http_user_agent $badBot {
"~badbot" 1;
default 0;
}

if ($badBot) {
return 400 $badRequest;
}

error_page 301 /request-status/301;
error_page 302 /request-status/302;
error_page 303 /request-status/303;
error_page 307 /request-status/307;
error_page 308 /request-status/308;
error_page 400 /request-status/400;
error_page 401 /request-status/401;
error_page 403 /request-status/403;
error_page 404 /request-status/404;
error_page 405 /request-status/405;
error_page 410 /request-status/410;
error_page 413 /request-status/413;
error_page 414 /request-status/414;
error_page 429 /request-status/429;
error_page 431 /request-status/431;
error_page 500 /request-status/500;
error_page 501 /request-status/501;
error_page 502 /request-status/502;
error_page 503 /request-status/503;
error_page 504 /request-status/504;

server {
listen 80;

location ~ "^/request-status/[0-9]{3}$" {
internal;
default_type text/html;

js_content errorpages.response;
}
}
}
102 changes: 102 additions & 0 deletions njs/http/errorpages/errorpages.definitions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
export default {
'301' : {
en : 'Moved permanently',
uk : 'Сторінку перенесено',
ru : 'Страница перемещена'
},
'302' : {
en : 'Found',
uk : 'Сторінку тимчасово перенесено',
ru : 'Страница временно перемещена'
},
'303' : {
en : 'See other',
uk : 'Дивіться іншу сторінку',
ru : 'Смотрите другую страницу'
},
'307' : {
en : 'Temporary redirect',
uk : 'Сторінку тимчасово перенесено',
ru : 'Страница временно перемещена'
},
'308' : {
en : 'Permanent redirect',
uk : 'Сторінку перенесено',
ru : 'Страница перемещена'
},
'400' : {
en : 'Bad request',
uk : 'Помилковий запит',
ru : 'Ошибочный запрос'
},
'401' : {
en : 'Unauthorized',
uk : 'Авторизацію не пройдено',
ru : 'Требуется авторизация'
},
'403' : {
en : 'Forbidden',
uk : 'Доступ заборонено',
ru : 'Доступ запрещен'
},
'404' : {
en : 'Not found',
uk : 'Сторінку не знайдено',
ru : 'Страница не найдена'
},
'405' : {
en : 'Method not allowed',
uk : 'Метод не підтримується',
ru : 'Метод не поддерживается'
},
'410' : {
en : 'Gone',
uk : 'Сторінки не існує',
ru : 'Страницы не существует'
},
'413' : {
en : 'Payload too large',
uk : 'Надто великий запит',
ru : 'Слишком большой запрос'
},
'414' : {
en : 'URI too long',
uk : 'Надто довга адреса сторінки',
ru : 'Слишком длинный адрес страницы'
},
'429' : {
en : 'Too many requests',
uk : 'Перевищено частоту запитів',
ru : 'Превышена частота запросов'
},
'431' : {
en : 'Request header fields too large',
uk : 'Надто довгі заголовки у запиті',
ru : 'Слишком длинные заголовки в запросе'
},
'500' : {
en : 'Internal server error',
uk : 'Внутрішня помилка сервера',
ru : 'Внутренняя ошибка сервера'
},
'501' : {
en : 'Not implemented',
uk : 'Не підтримується',
ru : 'Не поддерживается'
},
'502' : {
en : 'Bad gateway',
uk : 'Шлюз тимчасово недоступний',
ru : 'Шлюз временно недоступен'
},
'503' : {
en : 'Service unavailable',
uk : 'Сервіс тимчасово недоступний',
ru : 'Сервис временно недоступен'
},
'504' : {
en : 'Gateway timeout',
uk : 'Перевищено час очікування відповіді на шлюзі',
ru : 'Превышено время ожидания ответа на шлюзе'
}
}
42 changes: 42 additions & 0 deletions njs/http/errorpages/errorpages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import pagehtml from 'errorpages.template.js'
import definitions from 'errorpages.definitions.js'

function guessLang (request) {
var acceptLanguage = (request.headersIn['Accept-Language'] || '').split(',')
.map((elm) => elm.trim().slice(0, 2).toLowerCase())

var isUk = acceptLanguage.indexOf('uk')
var isRu = acceptLanguage.indexOf('ru')
var lang = 'en'

if (isUk !== -1 || isRu !== -1) {
if (isUk !== -1 && isRu !== -1) {
lang = isUk < isRu ? 'uk' : 'ru'
} else {
lang = isUk === -1 ? 'ru' : 'uk'
}
}

return lang
}

function response (request) {
var status = request.uri.split('/').pop()
var html = ''

if (Object.keys(definitions).includes(status)) {
var lang = guessLang(request)

html = pagehtml(lang, status, definitions[status][lang])
}

request.return(200, html)
}

function badRequest (request) {
var lang = guessLang(request)

return pagehtml(lang, '400', definitions['400'][lang])
}

export default { response, badRequest }
59 changes: 59 additions & 0 deletions njs/http/errorpages/errorpages.template.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
export default (lang, status, description) => `<!DOCTYPE html>
<html lang="${ lang }">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0, initial-scale=1.0, user-scalable=no">
<link rel="icon" href="/favicon.ico">
<title>${ status } ${ description }</title>
<style>
html,
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}

body {
display: -webkit-box;
display: -ms-flexbox;
display: -webkit-flex;
display: -moz-box;
display: flex;
align-items: center;
justify-content: center;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, system-ui, sans-serif;
font-size: 1em;
line-height: 1;
text-rendering: optimizeLegibility;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
}

ruby {
font-weight: 600;
font-size: 3em;
margin: 1em;
color: #e53935;
letter-spacing: -.01em;
}

rt {
display: inline-block;
font-weight: 500;
font-size: inherit;
color: #263238;
letter-spacing: -.025em;
text-align: center;
}
</style>
</head>
<body>
<ruby>
${ status } <rt>${ description }</rt>
</ruby>
</body>
</html>`