Skip to content

Commit 756b37c

Browse files
authored
Merge pull request #94 from Xpirix/handle_invalid_url
Add timeout handling for URL validation
2 parents 866bb9b + 67b7cf7 commit 756b37c

File tree

3 files changed

+52
-2
lines changed

3 files changed

+52
-2
lines changed

qgis-app/plugins/tests/test_validator.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,19 @@ def setUp(self):
1818
)
1919
web_not_exist_plugins = os.path.join(TESTFILE_DIR, "web_not_exist.zip")
2020
valid_plugins = os.path.join(TESTFILE_DIR, "valid_metadata_link.zip")
21+
timeout_plugin_link = os.path.join(TESTFILE_DIR, "timeout_plugin_link.zip_")
2122
self.valid_metadata_link = open(valid_plugins, "rb")
2223
self.invalid_metadata_link = open(invalid_plugins, "rb")
2324
self.web_not_exist = open(web_not_exist_plugins, "rb")
2425
self.invalid_url_scheme = open(invalid_url_scheme_plugins, "rb")
26+
self.timeout_plugin_link = open(timeout_plugin_link, "rb")
2527

2628
def tearDown(self):
2729
self.valid_metadata_link.close()
2830
self.invalid_metadata_link.close()
2931
self.invalid_url_scheme.close()
3032
self.web_not_exist.close()
33+
self.timeout_plugin_link.close()
3134

3235
def test_valid_metadata(self):
3336
self.assertTrue(
@@ -112,6 +115,28 @@ def test_invalid_metadata_web_does_not_exist(self):
112115
),
113116
)
114117

118+
def test_timeout_plugin_link(self):
119+
"""
120+
The timeout_plugin_link.zip contains metadata file with
121+
invalid scheme.
122+
bug tracker : http://www.example.com
123+
repo : http://www.example.com/
124+
homepage: http://www.google.com:81/
125+
"""
126+
self.assertRaises(
127+
ValidationError,
128+
validator,
129+
InMemoryUploadedFile(
130+
self.timeout_plugin_link,
131+
field_name="tempfile",
132+
name="testfile.zip",
133+
content_type="application/zip",
134+
size=39889,
135+
charset="utf8",
136+
),
137+
)
138+
139+
115140
@mock.patch("requests.get", side_effect=requests.exceptions.SSLError())
116141
def test_check_url_link_ssl_error(self, mock_request):
117142
urls = [{'url': "http://example.com/", 'forbidden_url': "forbidden_url", 'metadata_attr': "metadata attribute"}]
44.5 KB
Binary file not shown.

qgis-app/plugins/validator.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,9 @@ def error_check_if_exist(url: str)->bool:
121121
# add the headers parameter to make the request appears like coming
122122
# from browser, otherwise some websites will return 403
123123
headers = {
124-
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) "
124+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
125125
"AppleWebKit/537.36 (KHTML, like Gecko) "
126-
"Chrome/56.0.2924.76 Safari/537.36"
126+
"Chrome/117.0.0.0 Safari/537.36"
127127
}
128128
req = requests.head(url, headers=headers)
129129
except requests.exceptions.SSLError:
@@ -132,6 +132,31 @@ def error_check_if_exist(url: str)->bool:
132132
return True
133133
return req.status_code >= 400
134134

135+
def error_check_if_timeout(url: str) -> bool:
136+
# Check if url exists with a timeout
137+
try:
138+
# Add headers to make the request appear like it's coming from a browser
139+
headers = {
140+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
141+
"AppleWebKit/537.36 (KHTML, like Gecko) "
142+
"Chrome/117.0.0.0 Safari/537.36"
143+
}
144+
req = requests.head(url, headers=headers, timeout=10) # Set timeout to 10 seconds
145+
except requests.exceptions.Timeout:
146+
return True
147+
except Exception:
148+
return True
149+
return req.status_code >= 400
150+
151+
timeout_url_error = [item for item in [url_item['metadata_attr'] for url_item in urls if error_check_if_timeout(url_item['url'])]]
152+
if len(timeout_url_error) > 0:
153+
timeout_url_error_str = ", ".join(timeout_url_error)
154+
raise ValidationError(
155+
_(
156+
f"Please provide valid url link for the following key(s) in the metadata source: <strong>{timeout_url_error_str}</strong>. "
157+
"The website(s) cannot be reached within 10 seconds."
158+
)
159+
)
135160
url_error = [item for item in [url_item['metadata_attr'] for url_item in urls if error_check(url_item['url'], url_item['forbidden_url'])]]
136161
if len(url_error) > 0:
137162
url_error_str = ", ".join(url_error)

0 commit comments

Comments
 (0)