Skip to content

Commit 0578d56

Browse files
authored
Merge pull request #326 from ynput/enhancement/benevolent-validate-url
Benevolent validate url
2 parents fc2215f + 0447840 commit 0578d56

2 files changed

Lines changed: 35 additions & 22 deletions

File tree

ayon_api/exceptions.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from __future__ import annotations
2+
13
import copy
24

35
try:
@@ -21,13 +23,23 @@ class UrlError(Exception):
2123
UI if needed.
2224
"""
2325

24-
def __init__(self, message, title, hints=None):
26+
27+
def __init__(
28+
self,
29+
message: str,
30+
title: str,
31+
hints: list[str] | None = None,
32+
) -> None:
2533
if hints is None:
2634
hints = []
2735

2836
self.title = title
2937
self.hints = hints
30-
super(UrlError, self).__init__(message)
38+
super().__init__(message)
39+
40+
41+
class UrlNotReached(UrlError):
42+
pass
3143

3244

3345
class ServerError(Exception):

ayon_api/utils.py

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
)
2828
from .exceptions import (
2929
UrlError,
30+
UrlNotReached,
3031
ServerError,
3132
UnauthorizedError,
3233
HTTPRequestError,
@@ -570,11 +571,12 @@ def _try_connect_to_server(
570571
# TODO add validation if the url lead to AYON server
571572
# - this won't validate if the url lead to 'google.com'
572573
response = requests.get(
573-
url,
574+
f"{url}/api/info",
574575
timeout=timeout,
575576
verify=verify,
576577
cert=cert,
577578
)
579+
_ = response.json()
578580
if response.history:
579581
return response.history[-1].headers["location"].rstrip("/")
580582
return url
@@ -749,34 +751,39 @@ def validate_url(
749751
UrlError: Error with short description and hints for user.
750752
751753
"""
752-
stripperd_url = url.strip()
753-
if not stripperd_url:
754+
stripped_url = url.strip()
755+
if not stripped_url:
754756
raise UrlError(
755757
"Invalid url format. Url is empty.",
756758
title="Invalid url format",
757759
hints=["url seems to be empty"]
758760
)
759761

760762
# Not sure if this is good idea?
761-
modified_url = stripperd_url.rstrip("/")
763+
modified_url = stripped_url.rstrip("/")
764+
765+
# Make sure url has http scheme
766+
if not modified_url.lower().startswith("http"):
767+
modified_url = f"http://{modified_url}"
768+
762769
parsed_url = _try_parse_url(modified_url)
763770
universal_hints = [
764771
"does the url work in browser?"
765772
]
766773
if parsed_url is None:
767774
raise UrlError(
768-
"Invalid url format. Url cannot be parsed as url \"{}\".".format(
769-
modified_url
775+
(
776+
"Invalid url format. Url cannot be parsed"
777+
f" as url \"{modified_url}\"."
770778
),
771779
title="Invalid url format",
772780
hints=universal_hints
773781
)
774782

775-
# Try add 'https://' scheme if is missing
776-
# - this will trigger UrlError if both will crash
777-
if not parsed_url.scheme:
783+
pathless_url = f"{parsed_url.scheme}://{parsed_url.netloc}"
784+
if parsed_url.path:
778785
new_url = _try_connect_to_server(
779-
"http://" + modified_url,
786+
pathless_url,
780787
timeout=timeout,
781788
verify=verify,
782789
cert=cert,
@@ -794,17 +801,11 @@ def validate_url(
794801
return new_url
795802

796803
hints = []
797-
if "/" in parsed_url.path or not parsed_url.scheme:
798-
new_path = parsed_url.path.split("/")[0]
799-
if not parsed_url.scheme:
800-
new_path = "https://" + new_path
801-
802-
hints.append(
803-
"did you mean \"{}\"?".format(parsed_url.scheme + new_path)
804-
)
804+
if parsed_url.path:
805+
hints.append(f"did you mean \"{pathless_url}\"?")
805806

806-
raise UrlError(
807-
"Couldn't connect to server on \"{}\"".format(url),
807+
raise UrlNotReached(
808+
f"Couldn't connect to server on \"{url}\"",
808809
title="Couldn't connect to server",
809810
hints=hints + universal_hints
810811
)

0 commit comments

Comments
 (0)