Skip to content

Commit fe5ba1c

Browse files
committed
fix(file-descriptor): 🔧 accept application/json and treat Link header case-insensitively for remote context retrieval
1 parent 944ec82 commit fe5ba1c

1 file changed

Lines changed: 20 additions & 13 deletions

File tree

rocrate_validator/profiles/ro-crate/must/0_file_descriptor_format.py

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -89,46 +89,53 @@ class FileDescriptorJsonLdFormat(PyFunctionCheck):
8989
"""
9090

9191
def __get_remote_context__(self, context_uri: str) -> object:
92-
raw_data = HttpRequester().get(context_uri, headers={"Accept": "application/ld+json"})
92+
raw_data = HttpRequester().get(context_uri, headers={"Accept": "application/ld+json, application/json"})
9393
if raw_data.status_code != 200:
9494
raise RuntimeError(f"Unable to retrieve the JSON-LD context '{context_uri}'", self)
9595
logger.debug(f"Retrieved context from {context_uri}")
9696

9797
# Check if the response header contains the correct content type
9898
content_type = raw_data.headers.get("Content-Type", "")
99-
# If the content type is not application/ld+json...
100-
if "application/ld+json" not in content_type:
99+
is_valid_content_type = "application/ld+json" in content_type or "application/json" in content_type
100+
# If the content type is not application/ld+json or application/json,
101+
# try to find an alternate link for the JSON-LD context in the response header
102+
if not is_valid_content_type:
101103
logger.debug(
102104
f"The retrieved context from {context_uri} "
103-
f"does not have a Content-Type of application/ld+json: "
105+
f"does not have a Content-Type of application/ld+json or application/json: "
104106
f"the actual Content-Type is {content_type}. "
105-
f"This may indicate that the retrieved context is not a valid JSON-LD context."
106107
)
107108
# check if the response header contains an alternate link location for the JSON-LD context
108-
link_header = raw_data.headers.get("Link", "") or raw_data.headers.get("link", "")
109+
# (https headers are case-insensitive, according to RFC 7230,
110+
# so we can use .get() without worrying about the case)
111+
link_header = raw_data.headers.get("Link", "")
109112
logger.debug(f"Checking Link header for alternate JSON-LD context: {link_header}")
110-
if 'rel="alternate"' in link_header and 'type="application/ld+json"' in link_header:
113+
has_alternate_link = ('rel="alternate"' in link_header and
114+
('type="application/ld+json"' in link_header or
115+
'type="application/json"' in link_header))
116+
117+
if has_alternate_link:
111118
logger.debug(f"Found alternate link for JSON-LD context in Link header: {link_header}")
112119
# extract the URL of the alternate link
113-
match = re.search(r'<([^>]+)>;\s*rel="alternate";\s*type="application/ld\+json"', link_header)
120+
match = re.search(r'<([^>]+)>;\s*rel="alternate";\s*type="application/(ld\+json|json)"', link_header)
114121
if match:
115122
alternate_url = match.group(1)
116123
# If the alternate URL is relative, resolve it against the original context URI
117124
if not alternate_url.startswith("http"):
118125
alternate_url = urljoin(context_uri, alternate_url)
119126
logger.debug(f"Trying to retrieve JSON-LD context from alternate URL: {alternate_url}")
120-
raw_data = HttpRequester().get(alternate_url, headers={"Accept": "application/ld+json"})
127+
raw_data = HttpRequester().get(alternate_url, headers={
128+
"Accept": "application/ld+json, application/json"})
121129
if raw_data.status_code != 200:
122130
raise RuntimeError(
123131
f"Unable to retrieve the JSON-LD context from alternate URL '{alternate_url}'", self)
124132
logger.debug(f"Retrieved context from alternate URL {alternate_url}")
125133
content_type = raw_data.headers.get("Content-Type", "")
126-
if "application/ld+json" not in content_type:
134+
if "application/ld+json" not in content_type and "application/json" not in content_type:
127135
raise RuntimeError(
128136
f"The retrieved context from alternate URL {alternate_url} "
129-
f"does not have a Content-Type of application/ld+json: "
130-
f"the actual Content-Type is {content_type}. "
131-
f"This may indicate that the retrieved context is not a valid JSON-LD context.", self)
137+
"does not have a Content-Type of application/ld+json or application/json: "
138+
f"the actual Content-Type is {content_type}. ", self)
132139
else:
133140
logger.debug(f"No valid alternate link found in Link header: {link_header}")
134141
raise RuntimeError(

0 commit comments

Comments
 (0)