-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtool.py
More file actions
126 lines (110 loc) · 4.9 KB
/
Copy pathtool.py
File metadata and controls
126 lines (110 loc) · 4.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import os
import platform
from fastapi.responses import FileResponse
import re
import tomllib # Python 3.11+
def get_absolute_path(relative_path):
if os.path.isabs(relative_path):
raise ValueError(f"only can use releative path: {relative_path}")
# 檢查是否包含非法字符(Windows: < > : " | ? * 和控制字符)
if platform.system() == 'Windows':
illegal_chars = r'[<>:"|?*\x00-\x1f]'
if re.search(illegal_chars, relative_path):
raise ValueError(f"windows iligal chart: {relative_path}")
else: # Unix/Linux/Darwin
if '\x00' in relative_path:
raise ValueError(f"unix or linux iligal chart: {relative_path}")
script_dir = os.path.dirname(os.path.abspath(__file__))
absolute_path = os.path.join(script_dir, relative_path)
absolute_path = os.path.normpath(absolute_path)
if not absolute_path.startswith(script_dir):
raise ValueError(f"only can open the file in this project: {relative_path}")
return absolute_path
def read_toml_file(relative_path):
"""讀取並解析 TOML 檔案,返回字典"""
absolute_path = get_absolute_path(relative_path)
with open(absolute_path, 'rb') as file:
return tomllib.load(file)
def transfer_dict_to_tuple_list(data:dict) -> list[tuple]:
"""將字典轉換為包含鍵值對的元組列表"""
return [(key, value) for key, value in data.items()]
def is_file_exists(relative_path) -> bool:
"""檢查指定的相對路徑對應的文件是否存在"""
try:
absolute_path = get_absolute_path(relative_path)
return os.path.exists(absolute_path)
except ValueError:
return False
# Helper function to get error page response
def get_err_page_path(status_code: int|str) -> str:
return get_absolute_path(f"./_web/error_page/{str(status_code)}.html")
ERROR_PAGE_MAP = {
400: get_err_page_path(400),
401: get_err_page_path(401),
403: get_err_page_path(403),
404: get_err_page_path(404),
500: get_err_page_path(500),
}
def get_error_page_response(status_code: int) -> FileResponse | None:
"""根據狀態碼返回對應的錯誤頁面"""
error_file_path = ERROR_PAGE_MAP.get(status_code)
if not error_file_path:
return None
try:
# ERROR_PAGE_MAP 已經包含絕對路徑,直接使用
if os.path.exists(error_file_path):
return FileResponse(
error_file_path,
media_type='text/html',
status_code=status_code
)
except Exception:
pass
return None
# if __name__ == "__main__":
# print("=== 測試 transfer_dict_to_tuple_list ===")
# sample_dict = {"a": 1, "b": 2, "c": 3}
# tuple_list = transfer_dict_to_tuple_list(sample_dict)
# print(f"Original dict: {sample_dict}")
# print(f"Tuple list: {tuple_list}")
# print("=== 測試ServerSetting.toml ===")
# server_config: dict = read_toml_file("./_setting/ServerSetting.toml").get("dev", {})
# print(server_config["headers"])
# print("=== 測試toml型別 ===")
# type_test: dict = read_toml_file("./unit_test/type_test.toml").get("type", {})
# for key, value in type_test.items():
# print(f"{key}: {value} (type: {type(value)})")
# type_dict_o: dict = type_test.get("dict_o", {})
# for key, value in type_dict_o.items():
# print(f"dict_o - {key}: {value} (type: {type(value)})")
# print("=== 測試InfoSec.toml ===")
# infoSec_config: dict = read_toml_file("./_setting/InfoSec.toml").get("CORS", {})
# allow_list = infoSec_config.get("allow_origins", [])
# allow_credentials = infoSec_config.get("allow_credentials", None)
# print(f"Allow List: {allow_list}")
# print(f"Allow List Type: {type(allow_list)}")
# print(f"Allow Credentials: {allow_credentials}")
# print(f"Allow Credentials Type: {type(allow_credentials)}")
# print("=== 測試路徑驗證 ===")
# test_cases = [
# "./data/sample.txt", # 正常路徑
# "data/sample.txt", # 正常路徑
# "data@#/sample.txt", # 非法字符
# "../../../etc/passwd", # 路徑遍歷攻擊
# "C:/absolute/path.txt", # 絕對路徑
# ]
# for relative_path in test_cases:
# try:
# absolute_path = get_absolute_path(relative_path)
# print(f"✓ {relative_path} -> {absolute_path}")
# except ValueError as e:
# print(f"✗ {relative_path} -> Error: {e}")
# print("\n=== 測試讀取 TOML 檔案 ===")
# try:
# config = read_toml_file("./unit_test/test_config.toml")
# print(f"✓ 成功讀取 TOML 檔案")
# print(f" App Name: {config.get('app', {}).get('name')}")
# print(f" Version: {config.get('app', {}).get('version')}")
# print(f" Server Port: {config.get('server', {}).get('port')}")
# except Exception as e:
# print(f"✗ 讀取 TOML 檔案失敗: {e}")