Skip to content

Commit 5233751

Browse files
committed
fix: handle non-ASCII URLs and false positives in external link checker
1 parent e7f8fb4 commit 5233751

3 files changed

Lines changed: 27 additions & 10 deletions

File tree

.github/workflows/check_external_links.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
name: Check external links
1111
runs-on: ubuntu-latest
1212
steps:
13-
- uses: actions/checkout@v4
13+
- uses: actions/checkout@v5
1414

1515
- uses: actions/setup-python@v5
1616
with:

ja/use-dify/tutorials/build-ai-image-generation-app.mdx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ title: ゼロからAI画像生成アプリの構築方法
88

99
<div class="image-side-by-side">
1010
<img
11-
src="https://assets-docs.dify.ai/dify-enterprise-mintlify/jp/workshop/basic/05ff829cf382e82c9ece2676032d2383.png)
11+
src="https://assets-docs.dify.ai/dify-enterprise-mintlify/jp/workshop/basic/05ff829cf382e82c9ece2676032d2383.png"
12+
/>
1213

1314
## 今回の学ぶポイント
1415

tools/check-links.py

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import re
1313
import sys
1414
import urllib.error
15+
import urllib.parse
1516
import urllib.request
1617
from pathlib import Path
1718

@@ -66,9 +67,8 @@ def classify_link(url: str) -> str:
6667
"""Classify a link as internal, external, anchor, or skip."""
6768
if url.startswith(("http://", "https://")):
6869
# Skip localhost/loopback URLs
69-
from urllib.parse import urlparse
7070
try:
71-
host = urlparse(url).hostname or ""
71+
host = urllib.parse.urlparse(url).hostname or ""
7272
if host in ("localhost", "127.0.0.1", "0.0.0.0", "::1"):
7373
return "skip"
7474
except Exception:
@@ -246,18 +246,34 @@ def check_external_links():
246246
broken = []
247247
skipped = 0
248248

249+
# Domains that reliably block automated requests or are geo-restricted
250+
skip_domains = {"assets-docs.dify.ai", "volcengine.com", "twitter.com", "x.com"}
251+
249252
for i, url in enumerate(unique_urls):
250253
if (i + 1) % 50 == 0:
251254
print(f" Progress: {i + 1}/{len(unique_urls)}")
252255

253-
# Skip asset CDN URLs (usually reliable, many of them)
254-
if "assets-docs.dify.ai" in url:
255-
skipped += 1
256-
continue
256+
# Skip unreliable domains by checking parsed hostname
257+
try:
258+
host = urllib.parse.urlparse(url).hostname or ""
259+
if any(host == d or host.endswith("." + d) for d in skip_domains):
260+
skipped += 1
261+
continue
262+
except Exception:
263+
pass
264+
265+
# Encode non-ASCII characters in URL path, preserving existing percent-escapes
266+
try:
267+
parsed = urllib.parse.urlparse(url)
268+
encoded_url = urllib.parse.urlunparse(parsed._replace(
269+
path=urllib.parse.quote(parsed.path, safe="/:@!$&'()*+,;=-._~%")
270+
))
271+
except Exception:
272+
encoded_url = url
257273

258274
try:
259275
req = urllib.request.Request(
260-
url,
276+
encoded_url,
261277
method="HEAD",
262278
headers={"User-Agent": "Mozilla/5.0 (Dify-Docs-LinkChecker/1.0)"}
263279
)
@@ -270,7 +286,7 @@ def check_external_links():
270286
if e.code == 405:
271287
try:
272288
req = urllib.request.Request(
273-
url,
289+
encoded_url,
274290
method="GET",
275291
headers={"User-Agent": "Mozilla/5.0 (Dify-Docs-LinkChecker/1.0)"}
276292
)

0 commit comments

Comments
 (0)