Spaces:
Running on Zero
Running on Zero
Update utils.py
Browse files
utils.py
CHANGED
|
@@ -30,7 +30,7 @@ from urllib3.util import Retry
|
|
| 30 |
import shutil
|
| 31 |
import subprocess
|
| 32 |
import json
|
| 33 |
-
|
| 34 |
|
| 35 |
IS_ZERO_GPU = bool(os.getenv("SPACES_ZERO_GPU"))
|
| 36 |
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:127.0) Gecko/20100101 Firefox/127.0'
|
|
@@ -42,32 +42,32 @@ MODEL_ARCH = {
|
|
| 42 |
|
| 43 |
|
| 44 |
def validate_url(url: str) -> str:
|
| 45 |
-
"""Validate URL protocol and
|
| 46 |
url = url.strip()
|
| 47 |
if not url:
|
| 48 |
raise ValueError("URL cannot be empty.")
|
| 49 |
|
| 50 |
parsed = urllib.parse.urlparse(url)
|
| 51 |
-
if parsed.scheme
|
| 52 |
-
raise ValueError(f"Invalid protocol '{parsed.scheme}'. Only
|
| 53 |
|
| 54 |
hostname = (parsed.hostname or "").lower()
|
| 55 |
if not hostname:
|
| 56 |
raise ValueError("Invalid URL: missing hostname.")
|
| 57 |
|
| 58 |
-
#
|
| 59 |
if hostname in ("localhost", "0.0.0.0", "127.0.0.1", "::1"):
|
| 60 |
-
raise ValueError("
|
| 61 |
|
| 62 |
-
#
|
| 63 |
try:
|
| 64 |
ip = ipaddress.ip_address(hostname)
|
| 65 |
if ip.is_private or ip.is_loopback or ip.is_link_local or ip.is_reserved:
|
| 66 |
-
raise ValueError(f"Access to
|
| 67 |
except ValueError:
|
| 68 |
pass # Standard domain name
|
| 69 |
|
| 70 |
-
# Normalize
|
| 71 |
if hostname == "civitai.red" or hostname.endswith(".civitai.red"):
|
| 72 |
url = url.replace("civitai.red", "civitai.com")
|
| 73 |
|
|
@@ -180,9 +180,6 @@ class LoraHeaderInformation:
|
|
| 180 |
Return a compact HTML snippet (string) showing the parsed info
|
| 181 |
in a small font. Values are HTML-escaped.
|
| 182 |
"""
|
| 183 |
-
# helper to escape
|
| 184 |
-
esc = _html.escape
|
| 185 |
-
|
| 186 |
rows = [
|
| 187 |
("Title", esc(str(self.title))),
|
| 188 |
("Author", esc(str(self.author))),
|
|
@@ -415,7 +412,6 @@ def download_things(directory, url, hf_token="", civitai_api_key="", romanize=Fa
|
|
| 415 |
if not url:
|
| 416 |
return None
|
| 417 |
|
| 418 |
-
# SSRF & protocol validation
|
| 419 |
try:
|
| 420 |
url = validate_url(url)
|
| 421 |
except Exception as e:
|
|
@@ -531,7 +527,7 @@ def get_my_lora(link_url, romanize):
|
|
| 531 |
new_lora_model_list = new_lora_model_list + DIFFUSERS_FORMAT_LORAS
|
| 532 |
msg_lora = "Downloaded"
|
| 533 |
if l_name:
|
| 534 |
-
msg_lora += f": <b>{l_name}</b>"
|
| 535 |
print(msg_lora)
|
| 536 |
|
| 537 |
try:
|
|
@@ -776,4 +772,6 @@ def html_template_message(msg):
|
|
| 776 |
|
| 777 |
def escape_html(text):
|
| 778 |
"""Escapes HTML special characters in the input text."""
|
| 779 |
-
|
|
|
|
|
|
|
|
|
| 30 |
import shutil
|
| 31 |
import subprocess
|
| 32 |
import json
|
| 33 |
+
from html import escape as esc
|
| 34 |
|
| 35 |
IS_ZERO_GPU = bool(os.getenv("SPACES_ZERO_GPU"))
|
| 36 |
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:127.0) Gecko/20100101 Firefox/127.0'
|
|
|
|
| 42 |
|
| 43 |
|
| 44 |
def validate_url(url: str) -> str:
|
| 45 |
+
"""Validate URL protocol and host."""
|
| 46 |
url = url.strip()
|
| 47 |
if not url:
|
| 48 |
raise ValueError("URL cannot be empty.")
|
| 49 |
|
| 50 |
parsed = urllib.parse.urlparse(url)
|
| 51 |
+
if parsed.scheme != "https":
|
| 52 |
+
raise ValueError(f"Invalid protocol '{parsed.scheme}'. Only HTTPS is allowed.")
|
| 53 |
|
| 54 |
hostname = (parsed.hostname or "").lower()
|
| 55 |
if not hostname:
|
| 56 |
raise ValueError("Invalid URL: missing hostname.")
|
| 57 |
|
| 58 |
+
# Restrict local and internal endpoints
|
| 59 |
if hostname in ("localhost", "0.0.0.0", "127.0.0.1", "::1"):
|
| 60 |
+
raise ValueError("Restricted address.")
|
| 61 |
|
| 62 |
+
# Restrict private IP addresses
|
| 63 |
try:
|
| 64 |
ip = ipaddress.ip_address(hostname)
|
| 65 |
if ip.is_private or ip.is_loopback or ip.is_link_local or ip.is_reserved:
|
| 66 |
+
raise ValueError(f"Access to ({hostname}) is blocked.")
|
| 67 |
except ValueError:
|
| 68 |
pass # Standard domain name
|
| 69 |
|
| 70 |
+
# Normalize domain alias
|
| 71 |
if hostname == "civitai.red" or hostname.endswith(".civitai.red"):
|
| 72 |
url = url.replace("civitai.red", "civitai.com")
|
| 73 |
|
|
|
|
| 180 |
Return a compact HTML snippet (string) showing the parsed info
|
| 181 |
in a small font. Values are HTML-escaped.
|
| 182 |
"""
|
|
|
|
|
|
|
|
|
|
| 183 |
rows = [
|
| 184 |
("Title", esc(str(self.title))),
|
| 185 |
("Author", esc(str(self.author))),
|
|
|
|
| 412 |
if not url:
|
| 413 |
return None
|
| 414 |
|
|
|
|
| 415 |
try:
|
| 416 |
url = validate_url(url)
|
| 417 |
except Exception as e:
|
|
|
|
| 527 |
new_lora_model_list = new_lora_model_list + DIFFUSERS_FORMAT_LORAS
|
| 528 |
msg_lora = "Downloaded"
|
| 529 |
if l_name:
|
| 530 |
+
msg_lora += f": <b>{escape_html(os.path.basename(l_name))}</b>"
|
| 531 |
print(msg_lora)
|
| 532 |
|
| 533 |
try:
|
|
|
|
| 772 |
|
| 773 |
def escape_html(text):
|
| 774 |
"""Escapes HTML special characters in the input text."""
|
| 775 |
+
if text is None:
|
| 776 |
+
return ""
|
| 777 |
+
return esc(str(text), quote=True).replace("\n", "<br>")
|