Skip to content

Commit a5154a9

Browse files
committed
fix: add trailing URL slash so we not break query string in the URL
Use urlparse to do it properly. QFieldCloud expects trailing slashes in the resource URLs. We add them in a very naive way now, just checking the string. This causes issues if the URL has querystring, hash or other elements.
1 parent 16a6dfb commit a5154a9

File tree

2 files changed

+39
-4
lines changed

2 files changed

+39
-4
lines changed

qfieldcloud_sdk/sdk.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from requests.adapters import HTTPAdapter, Retry
1414

1515
from .interfaces import QfcException, QfcRequest, QfcRequestException
16-
from .utils import calc_etag, log
16+
from .utils import calc_etag, log, add_trailing_slash_to_url
1717
from pathvalidate import is_valid_filepath
1818

1919

@@ -1727,11 +1727,10 @@ def _request(
17271727
if path.startswith("/"):
17281728
path = path[1:]
17291729

1730-
if not path.endswith("/"):
1731-
path += "/"
1732-
17331730
path = self.url + path
17341731

1732+
path = add_trailing_slash_to_url(path)
1733+
17351734
if pagination:
17361735
limit = pagination.limit or DEFAULT_PAGINATION_LIMIT
17371736
offset = pagination.offset or 0

qfieldcloud_sdk/utils.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import os
44
import sys
55
from typing import List
6+
from urllib.parse import urlparse, urlunparse
67

78

89
def print_json(data):
@@ -114,3 +115,38 @@ def format_project_table(projects: List) -> str:
114115
headers=["ID", "OWNER/NAME", "IS PUBLIC", "DESCRIPTION"],
115116
data=data,
116117
)
118+
119+
120+
def add_trailing_slash_to_url(url: str) -> str:
121+
"""
122+
Add a trailing slash to a URL if it doesn't already have one.
123+
124+
Args:
125+
url (str): The URL to process
126+
127+
Returns:
128+
str: URL with trailing slash added
129+
130+
Examples:
131+
>>> add_trailing_slash("https://example.com")
132+
'https://example.com/'
133+
>>> add_trailing_slash("https://example.com/")
134+
'https://example.com/'
135+
>>> add_trailing_slash("https://example.com/path")
136+
'https://example.com/path/'
137+
>>> add_trailing_slash("https://example.com/file.txt")
138+
'https://example.com/file.txt/'
139+
"""
140+
if not url:
141+
return url
142+
143+
parsed = urlparse(url)
144+
145+
# Add trailing slash to path if it doesn't end with one
146+
path = parsed.path
147+
if not path.endswith("/"):
148+
path += "/"
149+
150+
# Reconstruct the URL with the modified path
151+
modified_parsed = parsed._replace(path=path)
152+
return urlunparse(modified_parsed)

0 commit comments

Comments
 (0)