174 lines
6.5 KiB
Python
174 lines
6.5 KiB
Python
import os
|
|
import mimetypes
|
|
from pathlib import Path
|
|
from django.http import HttpResponse, Http404, JsonResponse, HttpResponseRedirect
|
|
from django.views import View
|
|
from django.conf import settings
|
|
from gvsds.template_engine import render_template
|
|
|
|
TEMPLATE_DIR = Path(settings.BASE_DIR) / "TempLate"
|
|
|
|
MIME_TYPES = {
|
|
'.js': 'application/javascript',
|
|
'.mjs': 'application/javascript',
|
|
'.css': 'text/css',
|
|
'.png': 'image/png',
|
|
'.jpg': 'image/jpeg',
|
|
'.jpeg': 'image/jpeg',
|
|
'.gif': 'image/gif',
|
|
'.svg': 'image/svg+xml',
|
|
'.ico': 'image/x-icon',
|
|
'.woff': 'font/woff',
|
|
'.woff2': 'font/woff2',
|
|
'.ttf': 'font/ttf',
|
|
'.eot': 'application/vnd.ms-fontobject',
|
|
'.json': 'application/json',
|
|
'.xml': 'application/xml',
|
|
'.html': 'text/html',
|
|
'.htm': 'text/html',
|
|
'.txt': 'text/plain',
|
|
'.pdf': 'application/pdf',
|
|
'.zip': 'application/zip',
|
|
'.mp4': 'video/mp4',
|
|
'.webp': 'image/webp',
|
|
'.map': 'application/json',
|
|
}
|
|
|
|
SUBDOMAIN_CONFIG = {
|
|
'www': {'dir': '', 'root_is_index': True, 'use_base': True},
|
|
'gerp': {'dir': 'GERP', 'root_is_index': True, 'base': 'GERP/_Base'},
|
|
'ugm': {'dir': '', 'root_is_index': True},
|
|
'api': {'dir': None, 'root_is_index': False},
|
|
'mc': {'dir': 'MC', 'root_is_index': True},
|
|
'3crb': {'dir': 'CCCRB', 'root_is_index': True},
|
|
'ccgo': {'dir': 'CCGO', 'root_is_index': True},
|
|
'invite': {'dir': 'Invite', 'root_is_index': True, 'use_base': True},
|
|
'doc': {'dir': 'Document', 'root_is_index': True},
|
|
't4': {'dir': None, 'root_is_index': False},
|
|
'verify': {'dir': 'Verify', 'root_is_index': True},
|
|
'verifox': {'dir': 'Verifox', 'root_is_index': True},
|
|
'nav': {'dir': 'nav', 'root_is_index': True},
|
|
'history': {'dir': 'history', 'root_is_index': True},
|
|
'cdn': {'dir': 'cdn', 'root_is_index': False, 'root_text': 'GVSDS CDN'},
|
|
'yc8z': {'dir': 'yc8z', 'root_is_index': True},
|
|
'omc': {'dir': 'omc', 'root_is_index': True},
|
|
'tailwind': {'dir': 'Tailwindcss', 'root_is_index': False, 'root_redirect': '/3.4.17'},
|
|
'nanjingmassacre': {'dir': 'NanjingMassacre', 'root_is_index': True},
|
|
'3c': {'dir': None, 'root_is_index': False},
|
|
'vu': {'dir': None, 'root_is_index': False},
|
|
'links': {'dir': None, 'root_is_index': False},
|
|
'unclear': {'dir': 'Unclear', 'root_is_index': True},
|
|
}
|
|
|
|
|
|
def _get_subdomain(request):
|
|
return getattr(request, 'subdomain', 'www') or 'www'
|
|
|
|
|
|
def _get_subdomain_dir(subdomain):
|
|
config = SUBDOMAIN_CONFIG.get(subdomain, {})
|
|
return config.get('dir', '')
|
|
|
|
|
|
def _resolve_file(subdomain, file_path):
|
|
if '..' in file_path.split('/') or '..' in file_path.split(os.sep):
|
|
return None
|
|
subdomain_dir = _get_subdomain_dir(subdomain)
|
|
if subdomain_dir is None:
|
|
return None
|
|
if subdomain_dir:
|
|
candidate = TEMPLATE_DIR / subdomain_dir / file_path
|
|
try:
|
|
candidate.resolve().relative_to(TEMPLATE_DIR.resolve())
|
|
except ValueError:
|
|
return None
|
|
if candidate.is_file():
|
|
return candidate
|
|
candidate = TEMPLATE_DIR / file_path
|
|
try:
|
|
candidate.resolve().relative_to(TEMPLATE_DIR.resolve())
|
|
except ValueError:
|
|
return None
|
|
if candidate.is_file():
|
|
return candidate
|
|
return None
|
|
|
|
|
|
def _serve_file(full_path, subdomain=None):
|
|
ext = full_path.suffix.lower()
|
|
content_type = MIME_TYPES.get(ext, mimetypes.guess_type(str(full_path))[0] or 'application/octet-stream')
|
|
|
|
if ext in ('.html', '.htm'):
|
|
rel_path = full_path.relative_to(TEMPLATE_DIR)
|
|
template_name = str(rel_path).replace('\\', '/')
|
|
base = None
|
|
use_base = False
|
|
if subdomain:
|
|
config = SUBDOMAIN_CONFIG.get(subdomain, {})
|
|
base = config.get('base')
|
|
use_base = config.get('use_base', False)
|
|
if base:
|
|
return render_template(request=None, template_name=template_name, UseBase='false', SubBase=base)
|
|
if not use_base:
|
|
return render_template(request=None, template_name=template_name, UseBase='false')
|
|
return render_template(request=None, template_name=template_name, UseBase='true')
|
|
|
|
with open(full_path, 'rb') as f:
|
|
response = HttpResponse(f.read(), content_type=content_type)
|
|
|
|
if ext in ('.css', '.js', '.mjs', '.json', '.xml', '.txt', '.svg'):
|
|
response['Cache-Control'] = 'public, max-age=3600'
|
|
elif ext in ('.png', '.jpg', '.jpeg', '.gif', '.webp', '.ico', '.woff', '.woff2', '.ttf', '.eot', '.mp4'):
|
|
response['Cache-Control'] = 'public, max-age=86400'
|
|
|
|
return response
|
|
|
|
|
|
class SubdomainView(View):
|
|
def get(self, request, file_path=''):
|
|
subdomain = _get_subdomain(request)
|
|
config = SUBDOMAIN_CONFIG.get(subdomain, {})
|
|
|
|
if config.get('dir') is None:
|
|
raise Http404
|
|
|
|
# ugm 子域:未登录则跳转登录页,已登录则跳转 gerp
|
|
if subdomain == 'ugm':
|
|
elt_token = request.COOKIES.get('ELToken')
|
|
if not elt_token:
|
|
# 未登录 → 跳转登录页
|
|
if file_path and file_path not in ('/', 'login.html', 'register.html'):
|
|
from django.urls import reverse
|
|
login_url = f"https://ugm.gvsds.com/login.html?redirect=https://gerp.gvsds.com/"
|
|
return HttpResponseRedirect(login_url)
|
|
if not file_path or file_path == '/':
|
|
return HttpResponseRedirect('https://ugm.gvsds.com/login.html')
|
|
else:
|
|
# 已登录 → 跳转 gerp
|
|
if not file_path or file_path == '/' or file_path == 'index.html':
|
|
return HttpResponseRedirect('https://gerp.gvsds.com/')
|
|
|
|
if not file_path or file_path == '/':
|
|
if config.get('root_redirect'):
|
|
return HttpResponseRedirect(config['root_redirect'])
|
|
if config.get('root_text') is not None:
|
|
return HttpResponse(config['root_text'])
|
|
if config.get('root_is_index'):
|
|
file_path = 'index.html'
|
|
else:
|
|
raise Http404
|
|
|
|
if file_path.endswith('/'):
|
|
file_path += 'index.html'
|
|
|
|
if subdomain == 'tailwind' and not file_path.endswith('.js') and not file_path.endswith('.json'):
|
|
js_path = _resolve_file(subdomain, file_path + '.js')
|
|
if js_path:
|
|
return _serve_file(js_path, subdomain)
|
|
|
|
resolved = _resolve_file(subdomain, file_path)
|
|
if resolved:
|
|
return _serve_file(resolved, subdomain)
|
|
|
|
raise Http404
|