flysuper commited on
Commit
3e4cd48
·
verified ·
1 Parent(s): 86a31da

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +6 -90
app.py CHANGED
@@ -19,7 +19,6 @@ import json
19
  from urllib.parse import urlparse
20
  import tempfile
21
  import shutil
22
- import re
23
 
24
  # 創建臨時輸出目錄
25
  OUTPUT_DIR = tempfile.mkdtemp(prefix="edge_tts_")
@@ -62,15 +61,9 @@ ALLOWED_ORIGINS = [
62
  "https://www.dfes.ntpc.edu.tw/"
63
  ]
64
 
65
- # GAS 動態網域格式模式(用於正則表達式匹配)
66
- GAS_DYNAMIC_DOMAIN_PATTERN = r"^https://[a-zA-Z0-9\-]+-script\.googleusercontent\.com$"
67
-
68
  # 如果希望允許所有 GAS,取消下面兩行的註解
69
  # "https://script.google.com", # 所有 Google Apps Script
70
 
71
- # GAS 專用 API 密鑰(可選,用於額外安全驗證)
72
- GAS_API_KEY = os.getenv("GAS_API_KEY", "your-secret-key-here")
73
-
74
  # 掛載靜態文件(如果存在)
75
  if os.path.exists("static"):
76
  app.mount("/static", StaticFiles(directory="static"), name="static")
@@ -97,35 +90,7 @@ def _is_origin_allowed(request: Request) -> bool:
97
 
98
  print(f"請求來源檢查 - Origin: {origin}, Referer: {referer}, User-Agent: {user_agent}")
99
 
100
- # 特殊處理 Google Apps Script 環境
101
- # GAS 請求的特徵:
102
- # 1. Origin 通常包含 script.googleusercontent.com
103
- # 2. 或者沒有 Origin/Referer 標頭(沙箱環境)
104
- # 3. User-Agent 通常是標準的瀏覽器標頭
105
-
106
- # 檢查是否為 GAS 的 Origin(支援動態網域格式)
107
- if origin:
108
- # 使用正則表達式檢查 GAS 動態網域格式:https://[隨機字符]-script.googleusercontent.com
109
- if re.match(GAS_DYNAMIC_DOMAIN_PATTERN, origin):
110
- print("✅ 檢測到 Google Apps Script 動態網域 Origin")
111
- return True
112
- # 檢查是否包含 script.googleusercontent.com(向後兼容)
113
- elif "script.googleusercontent.com" in origin:
114
- print("✅ 檢測到 Google Apps Script Origin")
115
- return True
116
-
117
- # 檢查是否為 GAS 的 Referer(支援動態網域格式)
118
- if referer:
119
- # 使用正則表達式檢查 GAS 動態網域格式:https://[隨機字符]-script.googleusercontent.com
120
- if re.match(GAS_DYNAMIC_DOMAIN_PATTERN, referer):
121
- print("✅ 檢測到 Google Apps Script 動態網域 Referer")
122
- return True
123
- # 檢查是否包含 script.googleusercontent.com(向後兼容)
124
- elif "script.googleusercontent.com" in referer:
125
- print("✅ 檢測到 Google Apps Script Referer")
126
- return True
127
-
128
- # 檢查其他允許的來源(一般網頁)
129
  if origin:
130
  for allowed_origin in ALLOWED_ORIGINS:
131
  if origin.startswith(allowed_origin):
@@ -138,23 +103,6 @@ def _is_origin_allowed(request: Request) -> bool:
138
  print(f"✅ Referer 匹配: {referer} 匹配 {allowed_origin}")
139
  return True
140
 
141
- # 檢查是否為 GAS 沙箱環境(沒有 Origin/Referer 但有標準瀏覽器 User-Agent)
142
- # 這種情況下,我們需要通過其他方式驗證
143
- if not origin and not referer and "mozilla" in user_agent.lower():
144
- # 檢查是否有 GAS 特有的標頭或特徵
145
- # 可以通過檢查特定的請求標頭來驗證
146
- print("⚠️ 檢測到可能的 GAS 沙箱請求")
147
-
148
- # 檢查是否有 API 密鑰驗證
149
- api_key = request.headers.get("x-api-key")
150
- if api_key and api_key == GAS_API_KEY:
151
- print("✅ GAS API 密鑰驗證通過")
152
- return True
153
-
154
- # 如果沒有 API 密鑰,暫時允許(但建議在生產環境中啟用密鑰驗證)
155
- print("⚠️ 沒有 API 密鑰驗證,暫時允許請求")
156
- return True
157
-
158
  # 允許來自 Hugging Face Spaces 的直接調用
159
  if "huggingface" in user_agent.lower():
160
  print("✅ 檢測到 Hugging Face Spaces 環境")
@@ -175,8 +123,7 @@ async def root():
175
  "GET /tts": "文字轉語音 (GET 方法)",
176
  "GET /health": "健康檢查",
177
  "GET /allowed-origins": "查看允許的來源網址",
178
- "GET /debug-request": "調試請求信息(用於診斷 GAS 問題)",
179
- "GET /gas-verify": "GAS 專用驗證端點"
180
  },
181
  "note": "此服務部署在 Hugging Face Spaces 上,僅允許特定來源網址訪問"
182
  }
@@ -208,45 +155,14 @@ async def debug_request(request: Request):
208
  "user_agent": headers.get("user-agent"),
209
  "is_allowed": _is_origin_allowed(request),
210
  "client_ip": request.client.host if request.client else "unknown",
211
- "gas_detection": {
212
- "has_script_googleusercontent": "script.googleusercontent.com" in str(headers.get("origin", "")) + str(headers.get("referer", "")),
213
- "is_dynamic_gas_domain": re.match(GAS_DYNAMIC_DOMAIN_PATTERN, headers.get("origin", "")) or re.match(GAS_DYNAMIC_DOMAIN_PATTERN, headers.get("referer", "")),
214
- "is_sandbox_request": not headers.get("origin") and not headers.get("referer") and "mozilla" in headers.get("user-agent", "").lower(),
215
  "api_key_provided": "x-api-key" in headers
216
  }
217
  }
218
 
219
- @app.get("/gas-verify")
220
- async def gas_verify(request: Request):
221
- """GAS 專用驗證端點"""
222
- headers = dict(request.headers)
223
- is_gas = _is_origin_allowed(request)
224
-
225
- return {
226
- "is_gas_request": is_gas,
227
- "verification_method": "origin_check" if headers.get("origin") else "sandbox_detection",
228
- "recommendations": {
229
- "use_api_key": "建議在 GAS 中添加 'x-api-key' 標頭以提高安全性",
230
- "current_status": "✅ 請求已通過驗證" if is_gas else "❌ 請求被拒絕"
231
- },
232
- "gas_usage_example": {
233
- "description": "在 GAS 中使用此 API 的範例",
234
- "code": """
235
- // 在 Google Apps Script 中
236
- const response = UrlFetchApp.fetch('https://your-api-url/tts', {
237
- method: 'POST',
238
- headers: {
239
- 'Content-Type': 'application/json',
240
- 'x-api-key': 'your-secret-key-here' // 可選,用於額外安全驗證
241
- },
242
- payload: JSON.stringify({
243
- text: '要轉換的文字',
244
- voice: 'zh-TW-HsiaoChenNeural'
245
- })
246
- });
247
- """
248
- }
249
- }
250
 
251
  @app.get("/voices")
252
  async def get_voices():
 
19
  from urllib.parse import urlparse
20
  import tempfile
21
  import shutil
 
22
 
23
  # 創建臨時輸出目錄
24
  OUTPUT_DIR = tempfile.mkdtemp(prefix="edge_tts_")
 
61
  "https://www.dfes.ntpc.edu.tw/"
62
  ]
63
 
 
 
 
64
  # 如果希望允許所有 GAS,取消下面兩行的註解
65
  # "https://script.google.com", # 所有 Google Apps Script
66
 
 
 
 
67
  # 掛載靜態文件(如果存在)
68
  if os.path.exists("static"):
69
  app.mount("/static", StaticFiles(directory="static"), name="static")
 
90
 
91
  print(f"請求來源檢查 - Origin: {origin}, Referer: {referer}, User-Agent: {user_agent}")
92
 
93
+ # 檢查允許的來源(一般網頁)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  if origin:
95
  for allowed_origin in ALLOWED_ORIGINS:
96
  if origin.startswith(allowed_origin):
 
103
  print(f"✅ Referer 匹配: {referer} 匹配 {allowed_origin}")
104
  return True
105
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
  # 允許來自 Hugging Face Spaces 的直接調用
107
  if "huggingface" in user_agent.lower():
108
  print("✅ 檢測到 Hugging Face Spaces 環境")
 
123
  "GET /tts": "文字轉語音 (GET 方法)",
124
  "GET /health": "健康檢查",
125
  "GET /allowed-origins": "查看允許的來源網址",
126
+ "GET /debug-request": "調試請求信息"
 
127
  },
128
  "note": "此服務部署在 Hugging Face Spaces 上,僅允許特定來源網址訪問"
129
  }
 
155
  "user_agent": headers.get("user-agent"),
156
  "is_allowed": _is_origin_allowed(request),
157
  "client_ip": request.client.host if request.client else "unknown",
158
+ "request_info": {
159
+ "has_origin": bool(headers.get("origin")),
160
+ "has_referer": bool(headers.get("referer")),
161
+ "is_huggingface": "huggingface" in headers.get("user-agent", "").lower(),
162
  "api_key_provided": "x-api-key" in headers
163
  }
164
  }
165
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166
 
167
  @app.get("/voices")
168
  async def get_voices():