# -*- coding: utf-8 -*-
# dzw_secure_server.py — 태블릿(구형, 앱 설치불가)용 비밀주소 뷰어 서버 [2026-07-04]
#   ① 비밀 토큰 경로로만 접근 (모르면 404)  ② 화이트리스트 파일만 서빙 (폴더 목록·도면원본 차단)
#   실행: python dzw_secure_server.py   (포트 9090)
import http.server, socketserver, os, sys

PORT = 9090
TOKEN = 'dzw-k7x9m2q8w3'            # 비밀 경로 — 태블릿 북마크에만 저장
ROOT = os.path.dirname(os.path.abspath(__file__))

# 뷰어 구동에 필요한 파일만 (도면 원본 PDF/DXF/DWG·JBI 원본 등은 절대 미포함)
ALLOW = {
    'DOZIKWORKS_OS_v5_locked.dc.html',
    'threejs/three.min.js', 'TransformControls.js',
    'dozikworks_data_v5.js', 'dozikworks_engine_v5.js',
    'dozikworks_edgepath_v5.js', 'dozikworks_ui_v5.js',
    'support.js', 'dzw_teach_core.js', 'dzw_project_core.js',
    'jbi.json', 'ar2010_stl.json', 'jeonban_buf.json',
    'weld_path.json', 'knuckle.obj',
    'assets/welding_torch_CAD_v1.obj', 'assets/welding_torch_CAD_v2_bendfix.obj',
}

class H(http.server.SimpleHTTPRequestHandler):
    def translate_path(self, path):
        return path  # 직접 처리
    def do_GET(self):
        p = self.path.split('?')[0].lstrip('/')
        if not p.startswith(TOKEN + '/'):
            self.send_error(404); return
        rel = p[len(TOKEN)+1:]
        if rel == '' or rel == 'view':
            rel = 'DOZIKWORKS_OS_v5_locked.dc.html'
        if rel not in ALLOW:
            self.send_error(404); return
        fp = os.path.join(ROOT, rel.replace('/', os.sep))
        if not os.path.isfile(fp):
            self.send_error(404); return
        try:
            with open(fp, 'rb') as f:
                data = f.read()
            self.send_response(200)
            ct = 'text/html; charset=utf-8' if fp.endswith('.html') else \
                 'application/javascript' if fp.endswith('.js') else \
                 'application/json' if fp.endswith('.json') else 'application/octet-stream'
            self.send_header('Content-Type', ct)
            self.send_header('Content-Length', str(len(data)))
            self.send_header('Cache-Control', 'no-cache')
            self.end_headers()
            self.wfile.write(data)
        except Exception:
            self.send_error(500)
    def log_message(self, fmt, *args):
        sys.stderr.write('[dzw-secure] %s %s\n' % (self.address_string(), fmt % args))

if __name__ == '__main__':
    os.chdir(ROOT)
    with socketserver.ThreadingTCPServer(('0.0.0.0', PORT), H) as srv:
        print('비밀주소 서버 가동: http://<IP>:%d/%s/view' % (PORT, TOKEN))
        srv.serve_forever()
