@@ -11,7 +11,7 @@ import requests
11
11
import requests.utils
12
12
import subprocess
13
13
import sys
14
- from urllib.parse import urlparse
14
+ from urllib.parse import urlparse, urljoin
15
15
16
16
_myself = os.path.basename(sys.argv[0])
17
17
_default_user_agent = requests.utils.default_user_agent()
@@ -48,6 +48,13 @@ def parse_api_response(endpoint: str, response: requests.Response) -> bytes:
48
48
return response.content
49
49
50
50
51
+ def is_relative(url: str) -> bool:
52
+ parsed = urlparse(url)
53
+
54
+ return (parsed.scheme=='' and parsed.netloc=='' and
55
+ (len(parsed.path)==0 or parsed.path[0]!='/'))
56
+
57
+
51
58
def do_api_request(endpoint: str, method: str = 'GET', jsonData: dict = {},
52
59
data: dict = {}, files: dict = {}, decode: bool = True):
53
60
'''Perform an API call to the given endpoint and return its data.
@@ -56,7 +63,8 @@ def do_api_request(endpoint: str, method: str = 'GET', jsonData: dict = {},
56
63
API via HTTP or CLI.
57
64
58
65
Parameters:
59
- endpoint (str): the endpoint to call
66
+ endpoint (str): the endpoint to call, relative to `domjudge_api_url`;
67
+ it may also contain a complete URL, which will then be used as-is
60
68
method (str): the method to use, GET or PUT are supported
61
69
jsonData (dict): the JSON data to PUT. Only used when method is PUT
62
70
data (dict): data to pass in a POST request
@@ -73,12 +81,14 @@ def do_api_request(endpoint: str, method: str = 'GET', jsonData: dict = {},
73
81
# For the recursive call below to ignore SSL validation:
74
82
orig_kwargs = locals()
75
83
76
- if domjudge_api_url is None:
84
+ if domjudge_api_url is None and is_relative(endpoint) :
77
85
result = api_via_cli(endpoint, method, {}, {}, jsonData)
78
86
else:
87
+ if not is_relative(endpoint):
88
+ raise RuntimeError(f'Cannot access non-relative URL {endpoint} without API base URL')
79
89
global ca_check
80
- url = f'{domjudge_api_url}/{endpoint}'
81
90
parsed = urlparse(domjudge_api_url)
91
+ url = urljoin(domjudge_api_url, endpoint)
82
92
auth = None
83
93
if parsed.username and parsed.password:
84
94
auth = (parsed.username, parsed.password)
@@ -104,8 +114,7 @@ def do_api_request(endpoint: str, method: str = 'GET', jsonData: dict = {},
104
114
ca_check = not confirm(
105
115
"Can not verify certificate, ignore certificate check?", False)
106
116
if ca_check:
107
- print('Can not verify certificate chain for DOMserver.')
108
- exit(1)
117
+ raise RuntimeError(f'Cannot verify certificate chain for {url}')
109
118
else:
110
119
# Retry with SSL verification disabled
111
120
return do_api_request(**orig_kwargs)
0 commit comments