mirror of
https://github.com/donlon/cloudflare-error-page.git
synced 2025-12-19 14:59:28 +00:00
editor/server: support showing real Cloudflare DC city
This commit is contained in:
1
editor/server/.gitignore
vendored
Normal file
1
editor/server/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
cf-colos.json
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
# SPDX-License-Identifier: MIT
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
import json
|
||||||
import os
|
import os
|
||||||
import secrets
|
import secrets
|
||||||
import string
|
import string
|
||||||
@@ -52,6 +53,7 @@ def create_app(test_config=None) -> Flask:
|
|||||||
url_prefix = os.getenv('URL_PREFIX', '')
|
url_prefix = os.getenv('URL_PREFIX', '')
|
||||||
|
|
||||||
|
|
||||||
|
from . import utils
|
||||||
from . import models
|
from . import models
|
||||||
from . import examples
|
from . import examples
|
||||||
from . import editor
|
from . import editor
|
||||||
@@ -86,19 +88,5 @@ def create_app(test_config=None) -> Flask:
|
|||||||
return app
|
return app
|
||||||
|
|
||||||
|
|
||||||
def get_common_cf_template_params():
|
|
||||||
# Get real Ray ID from Cloudflare header
|
|
||||||
ray_id = request.headers.get('Cf-Ray')
|
|
||||||
if ray_id:
|
|
||||||
ray_id = ray_id[:16]
|
|
||||||
# Get real client ip from Cloudflare header or request.remote_addr
|
|
||||||
client_ip = request.headers.get('X-Forwarded-For')
|
|
||||||
if not client_ip:
|
|
||||||
client_ip = request.remote_addr
|
|
||||||
return {
|
|
||||||
'ray_id': ray_id,
|
|
||||||
'client_ip': client_ip,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['create_app', 'db', 'get_common_cf_template_params', 'render_cf_error_page']
|
__all__ = ['create_app', 'db', 'get_common_cf_template_params', 'render_cf_error_page']
|
||||||
|
|||||||
2883
editor/server/cf-colos.bundled.json
Normal file
2883
editor/server/cf-colos.bundled.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,6 @@
|
|||||||
# SPDX-License-Identifier: MIT
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
import copy
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
||||||
@@ -10,8 +11,8 @@ from flask import (
|
|||||||
redirect,
|
redirect,
|
||||||
)
|
)
|
||||||
|
|
||||||
from . import get_common_cf_template_params
|
|
||||||
from cloudflare_error_page import render as render_cf_error_page
|
from cloudflare_error_page import render as render_cf_error_page
|
||||||
|
from .utils import fill_cf_template_params
|
||||||
|
|
||||||
root_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../../')
|
root_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../../')
|
||||||
examples_dir = os.path.join(root_dir, 'examples')
|
examples_dir = os.path.join(root_dir, 'examples')
|
||||||
@@ -25,12 +26,12 @@ def get_page_params(name: str) -> dict:
|
|||||||
name = re.sub(r'[^\w]', '', name)
|
name = re.sub(r'[^\w]', '', name)
|
||||||
params = param_cache.get(name)
|
params = param_cache.get(name)
|
||||||
if params is not None:
|
if params is not None:
|
||||||
return params
|
return copy.deepcopy(params)
|
||||||
try:
|
try:
|
||||||
with open(os.path.join(examples_dir, f'{name}.json')) as f:
|
with open(os.path.join(examples_dir, f'{name}.json')) as f:
|
||||||
params = json.load(f)
|
params = json.load(f)
|
||||||
param_cache[name] = params
|
param_cache[name] = params
|
||||||
return params
|
return copy.deepcopy(params)
|
||||||
except Exception as _:
|
except Exception as _:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -49,10 +50,7 @@ def index(name: str):
|
|||||||
if params is None:
|
if params is None:
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
params = {
|
fill_cf_template_params(params)
|
||||||
**params,
|
|
||||||
**get_common_cf_template_params(),
|
|
||||||
}
|
|
||||||
|
|
||||||
# Render the error page
|
# Render the error page
|
||||||
return render_cf_error_page(params, use_cdn=True), 500
|
return render_cf_error_page(params, use_cdn=True)
|
||||||
|
|||||||
@@ -13,12 +13,18 @@ from flask import (
|
|||||||
)
|
)
|
||||||
from jinja2 import Environment, select_autoescape
|
from jinja2 import Environment, select_autoescape
|
||||||
|
|
||||||
from cloudflare_error_page import render as render_cf_error_page, fill_params, default_template as cf_template
|
from cloudflare_error_page import (
|
||||||
|
fill_params as fill_template_params,
|
||||||
|
default_template as cf_template
|
||||||
|
)
|
||||||
|
|
||||||
from . import get_common_cf_template_params
|
from . import (
|
||||||
from . import db
|
db,
|
||||||
from . import limiter
|
limiter,
|
||||||
from . import models
|
models
|
||||||
|
)
|
||||||
|
|
||||||
|
from .utils import fill_cf_template_params
|
||||||
|
|
||||||
# root_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../../')
|
# root_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../../')
|
||||||
# examples_dir = os.path.join(root_dir, 'examples')
|
# examples_dir = os.path.join(root_dir, 'examples')
|
||||||
@@ -89,7 +95,7 @@ def get(name: str):
|
|||||||
if not item:
|
if not item:
|
||||||
if is_json:
|
if is_json:
|
||||||
return jsonify({
|
return jsonify({
|
||||||
'status': 'not-found'
|
'status': 'notfound'
|
||||||
})
|
})
|
||||||
else:
|
else:
|
||||||
return abort(404)
|
return abort(404)
|
||||||
@@ -104,22 +110,19 @@ def get(name: str):
|
|||||||
'parameters': params,
|
'parameters': params,
|
||||||
})
|
})
|
||||||
else:
|
else:
|
||||||
params = {
|
|
||||||
**params,
|
|
||||||
**get_common_cf_template_params(),
|
|
||||||
}
|
|
||||||
params['creator_info'] = {
|
params['creator_info'] = {
|
||||||
'hidden': False,
|
'hidden': False,
|
||||||
'text': 'CF Error Page Editor',
|
'text': 'CF Error Page Editor',
|
||||||
'link': f'https://virt.moe/cloudflare-error-page/editor/#from={name}',
|
'link': f'https://virt.moe/cloudflare-error-page/editor/#from={name}',
|
||||||
}
|
}
|
||||||
fill_params(params)
|
# Always escape HTML
|
||||||
params['what_happened'] = html.escape(params.get('what_happened', '')) # TODO: common render function?
|
params['what_happened'] = html.escape(params.get('what_happened', '')) # TODO: common render function?
|
||||||
params['what_can_i_do'] = html.escape(params.get('what_can_i_do', ''))
|
params['what_can_i_do'] = html.escape(params.get('what_can_i_do', ''))
|
||||||
|
fill_cf_template_params(params)
|
||||||
|
fill_template_params(params)
|
||||||
|
|
||||||
return template.render(base=cf_template,
|
return template.render(base=cf_template,
|
||||||
params=params,
|
params=params,
|
||||||
url=request.url,
|
url=request.url,
|
||||||
description='Cloudflare error page',
|
description='Cloudflare error page',
|
||||||
resources_use_cdn=True)
|
resources_use_cdn=True)
|
||||||
# return render_cf_error_page(params=params, allow_html=False, use_cdn=True), 200
|
|
||||||
|
|||||||
50
editor/server/utils.py
Normal file
50
editor/server/utils.py
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
|
from flask import request
|
||||||
|
from . import root_dir
|
||||||
|
|
||||||
|
|
||||||
|
loc_data: dict = None
|
||||||
|
|
||||||
|
def read_loc_file(path: str):
|
||||||
|
try:
|
||||||
|
with open(os.path.join(root_dir, path)) as f:
|
||||||
|
return json.load(f)
|
||||||
|
except:
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def get_cf_location(loc: str):
|
||||||
|
global loc_data
|
||||||
|
loc = loc.upper()
|
||||||
|
if loc_data is None:
|
||||||
|
loc_data = read_loc_file('editor/server/cf-colos.json')
|
||||||
|
if loc_data is None:
|
||||||
|
# From https://github.com/Netrvin/cloudflare-colo-list/blob/main/DC-Colos.json
|
||||||
|
loc_data = read_loc_file('editor/server/cf-colos.bundled.json')
|
||||||
|
if loc_data is None:
|
||||||
|
return
|
||||||
|
data: dict = loc_data.get(loc)
|
||||||
|
if not data:
|
||||||
|
return
|
||||||
|
return data.get('city')
|
||||||
|
|
||||||
|
|
||||||
|
def fill_cf_template_params(params: dict):
|
||||||
|
# Get real Ray ID / data center location from Cloudflare header
|
||||||
|
ray_id_loc = request.headers.get('Cf-Ray')
|
||||||
|
if ray_id_loc:
|
||||||
|
params['ray_id'] = ray_id_loc[:16]
|
||||||
|
|
||||||
|
cf_status: dict = params.get('cloudflare_status', {})
|
||||||
|
if not cf_status.get('location'):
|
||||||
|
loc = get_cf_location()
|
||||||
|
if loc:
|
||||||
|
cf_status['location'] = loc
|
||||||
|
|
||||||
|
# Get real client ip from Cloudflare header or request.remote_addr
|
||||||
|
client_ip = request.headers.get('X-Forwarded-For')
|
||||||
|
if not client_ip:
|
||||||
|
client_ip = request.remote_addr
|
||||||
|
params['client_ip'] = client_ip
|
||||||
Reference in New Issue
Block a user