DraconicDragon commited on
Commit
083a50d
·
verified ·
1 Parent(s): cea9733

Update fetch_url_util.py

Browse files
Files changed (1) hide show
  1. fetch_url_util.py +14 -11
fetch_url_util.py CHANGED
@@ -6,46 +6,49 @@ from curl_cffi import requests
6
  def fetch_image_from_url(url):
7
  """
8
  Robustly fetches an image from a URL using TLS impersonation and
9
- dynamic Referer headers to bypass 403 Forbidden errors.
10
  """
11
- if not url or not url.startswith("http"):
12
  return None
 
 
 
 
 
13
 
14
- # Extract base domain to bypass hotlinking protections (like Pixiv)
 
15
  parsed_url = urllib.parse.urlparse(url)
16
  base_domain = f"{parsed_url.scheme}://{parsed_url.netloc}/"
17
 
18
- # Standard browser headers
19
  headers = {
20
- "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
21
  "Accept": "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8",
22
  "Accept-Language": "en-US,en;q=0.9",
23
  "Referer": base_domain,
24
  "Cache-Control": "no-cache",
25
- "Pragma": "no-cache",
26
  }
27
 
28
  try:
29
- # 'impersonate' mimics Chrome's TLS handshake and HTTP/2 settings
30
  response = requests.get(
31
  url,
32
  headers=headers,
33
  impersonate="chrome120",
34
  timeout=15,
35
- follow_redirects=True
36
  )
37
 
38
  response.raise_for_status()
39
 
40
- # Open and verify the image
41
  image_bytes = io.BytesIO(response.content)
42
  img = Image.open(image_bytes)
43
- img.load() # Force loading to verify it's a valid image
44
 
45
  return img.convert("RGB")
46
 
47
  except Exception as e:
48
  print(f"Error fetching {url}: {str(e)}")
49
- # You can raise a specific Gradio error here if preferred
50
  import gradio as gr
 
51
  raise gr.Error(f"Failed to fetch image: {str(e)}")
 
6
  def fetch_image_from_url(url):
7
  """
8
  Robustly fetches an image from a URL using TLS impersonation and
9
+ dynamic Referer headers. Automatically handles missing http/https prefixes.
10
  """
11
+ if not url:
12
  return None
13
+
14
+ # 1. Handle missing protocol (e.g., pixiv.net -> https://pixiv.net)
15
+ url = url.strip()
16
+ if not url.startswith(("http://", "https://")):
17
+ url = "https://" + url
18
 
19
+ # 2. Extract base domain for the Referer header
20
+ # This is crucial for Pixiv and similar sites to prevent 403 Forbidden
21
  parsed_url = urllib.parse.urlparse(url)
22
  base_domain = f"{parsed_url.scheme}://{parsed_url.netloc}/"
23
 
 
24
  headers = {
25
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
26
  "Accept": "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8",
27
  "Accept-Language": "en-US,en;q=0.9",
28
  "Referer": base_domain,
29
  "Cache-Control": "no-cache",
 
30
  }
31
 
32
  try:
33
+ # Changed 'follow_redirects' to 'allow_redirects' for curl_cffi compatibility
34
  response = requests.get(
35
  url,
36
  headers=headers,
37
  impersonate="chrome120",
38
  timeout=15,
39
+ allow_redirects=True
40
  )
41
 
42
  response.raise_for_status()
43
 
 
44
  image_bytes = io.BytesIO(response.content)
45
  img = Image.open(image_bytes)
46
+ img.load()
47
 
48
  return img.convert("RGB")
49
 
50
  except Exception as e:
51
  print(f"Error fetching {url}: {str(e)}")
 
52
  import gradio as gr
53
+ # This will show a red toast notification in the UI
54
  raise gr.Error(f"Failed to fetch image: {str(e)}")