mirror of
https://github.com/donlon/cloudflare-error-page.git
synced 2025-12-19 14:59:28 +00:00
add simple error page generator
This commit is contained in:
33
cloudflare_error_page/__init__.py
Normal file
33
cloudflare_error_page/__init__.py
Normal file
@@ -0,0 +1,33 @@
|
||||
import os
|
||||
import secrets
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from jinja2 import Environment, PackageLoader, select_autoescape
|
||||
|
||||
env = Environment(
|
||||
loader=PackageLoader("cloudflare_error_page"),
|
||||
autoescape=select_autoescape()
|
||||
)
|
||||
|
||||
|
||||
def get_resources_folder() -> str:
|
||||
"""
|
||||
Get resources folder that contains stylesheet and icons for the error page.
|
||||
If you pass resources_use_cdn=True to render(), local resources are not used.
|
||||
"""
|
||||
return os.path.join(os.path.dirname(os.path.abspath(__file__)), 'resources')
|
||||
|
||||
|
||||
def render(params: dict, use_cdn: bool=True) -> str:
|
||||
"""
|
||||
Render a customized Cloudflare error page.
|
||||
"""
|
||||
params = {**params}
|
||||
if not params.get('time'):
|
||||
utc_now = datetime.now(timezone.utc)
|
||||
params['time'] = utc_now.strftime("%Y-%m-%d %H:%M:%S UTC")
|
||||
if not params.get('ray_id'):
|
||||
params['ray_id'] = secrets.token_hex(8)
|
||||
|
||||
template = env.get_template("error.html")
|
||||
return template.render(params=params, resources_use_cdn=use_cdn)
|
||||
BIN
cloudflare_error_page/resources/images/cf-icon-browser.png
Normal file
BIN
cloudflare_error_page/resources/images/cf-icon-browser.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 484 B |
BIN
cloudflare_error_page/resources/images/cf-icon-cloud.png
Normal file
BIN
cloudflare_error_page/resources/images/cf-icon-cloud.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
BIN
cloudflare_error_page/resources/images/cf-icon-error.png
Normal file
BIN
cloudflare_error_page/resources/images/cf-icon-error.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 854 B |
BIN
cloudflare_error_page/resources/images/cf-icon-ok.png
Normal file
BIN
cloudflare_error_page/resources/images/cf-icon-ok.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 946 B |
BIN
cloudflare_error_page/resources/images/cf-icon-server.png
Normal file
BIN
cloudflare_error_page/resources/images/cf-icon-server.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
1
cloudflare_error_page/resources/styles/main.css
Normal file
1
cloudflare_error_page/resources/styles/main.css
Normal file
File diff suppressed because one or more lines are too long
107
cloudflare_error_page/templates/error.html
Normal file
107
cloudflare_error_page/templates/error.html
Normal file
@@ -0,0 +1,107 @@
|
||||
{% set resources_cdn = 'https://cloudflare.com' if resources_use_cdn else '' %}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<!--[if lt IE 7]> <html class="no-js ie6 oldie" lang="en-US"> <![endif]-->
|
||||
<!--[if IE 7]> <html class="no-js ie7 oldie" lang="en-US"> <![endif]-->
|
||||
<!--[if IE 8]> <html class="no-js ie8 oldie" lang="en-US"> <![endif]-->
|
||||
<!--[if gt IE 8]><!--> <html class="no-js" lang="en-US"> <!--<![endif]-->
|
||||
<head>
|
||||
{% set error_code = params.error_code or 500 %}
|
||||
{% set title = params.title or 'Internal server error' %}
|
||||
<title>{{ params.html_title or ((error_code | string) + ': ' + title) }}</title>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
|
||||
<meta name="robots" content="noindex, nofollow" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
<link rel="stylesheet" id="cf_styles-css" href="{{resources_cdn}}/cdn-cgi/styles/main.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="cf-wrapper">
|
||||
<div id="cf-error-details" class="p-0">
|
||||
<header class="mx-auto pt-10 lg:pt-6 lg:px-8 w-240 lg:w-full mb-8">
|
||||
<h1 class="inline-block sm:block sm:mb-2 font-light text-60 lg:text-4xl text-black-dark leading-tight mr-2">
|
||||
<span class="inline-block">{{ title }}</span>
|
||||
<span class="code-label">Error code {{ error_code }}</span>
|
||||
</h1>
|
||||
{% set more_info = params.more_information or {} %}
|
||||
{% if not more_info.hidden or false %}
|
||||
<div>
|
||||
Visit <a href="{{more_info.link or 'https://www.cloudflare.com/'}}" target="_blank" rel="noopener noreferrer">{{more_info.text or 'cloudflare.com'}}</a> for more information.
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="mt-3">{{ params.time }}</div>
|
||||
</header>
|
||||
<div class="my-8 bg-gradient-gray">
|
||||
<div class="w-240 lg:w-full mx-auto">
|
||||
<div class="clearfix md:px-8">
|
||||
{% for item_id in ['browser', 'cloudflare', 'host'] %}
|
||||
{% if item_id == 'browser' %}
|
||||
{% set icon = 'browser' -%}
|
||||
{% set default_location = 'You' -%}
|
||||
{% set default_name = 'Browser' -%}
|
||||
{% elif item_id == 'cloudflare' %}
|
||||
{% set icon = 'cloud' -%}
|
||||
{% set default_location = 'San Francisco' -%}
|
||||
{% set default_name = 'Cloudflare' -%}
|
||||
{% else %}
|
||||
{% set icon = 'server' -%}
|
||||
{% set default_location = 'example.com' -%}
|
||||
{% set default_name = 'Host' -%}
|
||||
{% endif %}
|
||||
{% set item = params.get(item_id + '_status', {}) -%}
|
||||
{% set status = item.get('status', 'ok') -%}
|
||||
{% if item.status_text_color %}
|
||||
{% set text_color = item.status_text_color -%}
|
||||
{% elif status == 'ok' %}
|
||||
{% set text_color = '#9bca3e' -%} {# text-green-success #}
|
||||
{% elif status == 'error' %}
|
||||
{% set text_color = '#bd2426' -%} {# text-red-error #}
|
||||
{% endif %}
|
||||
{% set status_text = item.get('status_text', 'Working' if status == 'ok' else 'Not Working') -%}
|
||||
<div id="cf-{{item_id}}-status" class="{{'cf-error-source' if params.error_source == item_id else ''}} relative w-1/3 md:w-full py-15 md:p-0 md:py-8 md:text-left md:border-solid md:border-0 md:border-b md:border-gray-400 overflow-hidden float-left md:float-none text-center">
|
||||
<div class="relative mb-10 md:m-0">
|
||||
<span class="cf-icon-{{icon}} block md:hidden h-20 bg-center bg-no-repeat"></span>
|
||||
<span class="cf-icon-{{status}} w-12 h-12 absolute left-1/2 md:left-auto md:right-0 md:top-0 -ml-6 -bottom-4"></span>
|
||||
</div>
|
||||
<span class="md:block w-full truncate">{{item.location or default_location}}</span>
|
||||
<h3 class="md:inline-block mt-3 md:mt-0 text-2xl text-gray-600 font-light leading-1.3">{{item.name or default_name}}</h3>
|
||||
<span class="leading-1.3 text-2xl" style="color: {{text_color}}">{{status_text}}</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="w-240 lg:w-full mx-auto mb-8 lg:px-8">
|
||||
<div class="clearfix">
|
||||
<div class="w-1/2 md:w-full float-left pr-6 md:pb-10 md:pr-0 leading-relaxed">
|
||||
<h2 class="text-3xl font-normal leading-1.3 mb-4">What happened?</h2>
|
||||
{{ (params.what_happened or '<p>There is an internal server error on Cloudflare\'s network.</p>') | safe }}
|
||||
</div>
|
||||
<div class="w-1/2 md:w-full float-left leading-relaxed">
|
||||
<h2 class="text-3xl font-normal leading-1.3 mb-4">What can I do?</h2>
|
||||
{{ (params.what_can_i_do or '<p>Please try again in a few minutes.</p>') | safe }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cf-error-footer cf-wrapper w-240 lg:w-full py-10 sm:py-4 sm:px-8 mx-auto text-center sm:text-left border-solid border-0 border-t border-gray-300">
|
||||
<p class="text-13">
|
||||
<span class="cf-footer-item sm:block sm:mb-1">Cloudflare Ray ID: <strong class="font-semibold">{{ params.ray_id }}</strong></span>
|
||||
<span class="cf-footer-separator sm:hidden">•</span>
|
||||
<span id="cf-footer-item-ip" class="cf-footer-item hidden sm:block sm:mb-1">
|
||||
Your IP:
|
||||
<button type="button" id="cf-footer-ip-reveal" class="cf-footer-ip-reveal-btn">Click to reveal</button>
|
||||
<span class="hidden" id="cf-footer-ip">{{ params.client_ip or '1.1.1.1' }}</span>
|
||||
<span class="cf-footer-separator sm:hidden">•</span>
|
||||
</span>
|
||||
{% set perf_sec_by = params.get('perf_sec_by', {}) %}
|
||||
<span class="cf-footer-item sm:block sm:mb-1"><span>Performance & security by</span> <a rel="noopener noreferrer" href="{{perf_sec_by.link or 'https://www.cloudflare.com/'}}" id="brand_link" target="_blank">{{perf_sec_by.get('text', 'Cloudflare')}}</a></span>
|
||||
</p>
|
||||
</div><!-- /.error-footer -->
|
||||
</div>
|
||||
</div>
|
||||
<script>(function(){function d(){var b=a.getElementById("cf-footer-item-ip"),c=a.getElementById("cf-footer-ip-reveal");b&&"classList"in b&&(b.classList.remove("hidden"),c.addEventListener("click",function(){c.classList.add("hidden");a.getElementById("cf-footer-ip").classList.remove("hidden")}))}var a=document;document.addEventListener&&a.addEventListener("DOMContentLoaded",d)})();</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user