(url, application_id: str)
| 217 | |
| 218 | |
| 219 | def get_url_content(url, application_id: str): |
| 220 | application = Application.objects.filter(id=application_id).first() |
| 221 | if application is None: |
| 222 | raise AppApiException(500, _('Application does not exist')) |
| 223 | if not application.file_upload_enable: |
| 224 | raise AppApiException(500, _('File upload is not enabled')) |
| 225 | file_limit = 50 * 1024 * 1024 |
| 226 | if application.file_upload_setting and application.file_upload_setting.get('fileLimit'): |
| 227 | file_limit = application.file_upload_setting.get('fileLimit') * 1024 * 1024 |
| 228 | parsed = validate_url(url) |
| 229 | |
| 230 | # 创建带有安全检查的 session |
| 231 | session = requests.Session() |
| 232 | safe_adapter = SafeHTTPAdapter() |
| 233 | session.mount('http://', safe_adapter) |
| 234 | session.mount('https://', safe_adapter) |
| 235 | |
| 236 | try: |
| 237 | response = session.get( |
| 238 | url, |
| 239 | timeout=3, |
| 240 | allow_redirects=False |
| 241 | ) |
| 242 | finally: |
| 243 | session.close() |
| 244 | |
| 245 | final_host = urlparse(response.url).hostname |
| 246 | if is_private_ip(final_host): |
| 247 | raise ValueError("Blocked unsafe redirect to internal host") |
| 248 | # 判断文件大小 |
| 249 | if int(response.headers.get('Content-Length', 0)) > file_limit: |
| 250 | raise AppApiException(500, _('File size exceeds limit')) |
| 251 | # 返回状态码 响应内容大小 响应的contenttype 还有字节流 |
| 252 | content_type = response.headers.get('Content-Type', '') |
| 253 | # 根据内容类型决定如何处理 |
| 254 | if 'text' in content_type or 'json' in content_type: |
| 255 | content = response.text |
| 256 | else: |
| 257 | # 二进制内容使用Base64编码 |
| 258 | content = base64.b64encode(response.content).decode('utf-8') |
| 259 | |
| 260 | return { |
| 261 | 'status_code': response.status_code, |
| 262 | 'Content-Length': response.headers.get('Content-Length', 0), |
| 263 | 'Content-Type': content_type, |
| 264 | 'content': content, |
| 265 | } |
| 266 | |
| 267 | |
| 268 | def is_private_ip(host: str) -> bool: |
no test coverage detected