@@ -11,7 +11,7 @@ import requests
1111import requests.utils
1212import subprocess
1313import sys
14- from urllib.parse import urlparse
14+ from urllib.parse import urlparse, urljoin
1515
1616_myself = os.path.basename(sys.argv[0])
1717_default_user_agent = requests.utils.default_user_agent()
@@ -48,6 +48,13 @@ def parse_api_response(endpoint: str, response: requests.Response) -> bytes:
4848 return response.content
4949
5050
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+
5158def do_api_request(endpoint: str, method: str = 'GET', jsonData: dict = {},
5259 data: dict = {}, files: dict = {}, decode: bool = True):
5360 '''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 = {},
5663 API via HTTP or CLI.
5764
5865 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
6068 method (str): the method to use, GET or PUT are supported
6169 jsonData (dict): the JSON data to PUT. Only used when method is PUT
6270 data (dict): data to pass in a POST request
@@ -73,12 +81,14 @@ def do_api_request(endpoint: str, method: str = 'GET', jsonData: dict = {},
7381 # For the recursive call below to ignore SSL validation:
7482 orig_kwargs = locals()
7583
76- if domjudge_api_url is None:
84+ if domjudge_api_url is None and is_relative(endpoint) :
7785 result = api_via_cli(endpoint, method, {}, {}, jsonData)
7886 else:
87+ if not is_relative(endpoint):
88+ raise RuntimeError(f'Cannot access non-relative URL {endpoint} without API base URL')
7989 global ca_check
80- url = f'{domjudge_api_url}/{endpoint}'
8190 parsed = urlparse(domjudge_api_url)
91+ url = urljoin(domjudge_api_url, endpoint)
8292 auth = None
8393 if parsed.username and parsed.password:
8494 auth = (parsed.username, parsed.password)
@@ -104,8 +114,7 @@ def do_api_request(endpoint: str, method: str = 'GET', jsonData: dict = {},
104114 ca_check = not confirm(
105115 "Can not verify certificate, ignore certificate check?", False)
106116 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}')
109118 else:
110119 # Retry with SSL verification disabled
111120 return do_api_request(**orig_kwargs)
0 commit comments