Skip to content

Commit 52da900

Browse files
committed
Improve error messages when metadata fetch/parse fails
When the metadata file is corrupt on the issuer, it's difficult to see what / where the failure occurred. This includes the URL of the problem (or problem JSON) in the exception message.
1 parent 2f12079 commit 52da900

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed

src/scitokens_internal.cpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ SimpleCurlGet::GetStatus SimpleCurlGet::perform_start(const std::string &url) {
7373
if (rv != CURLE_OK) {
7474
throw CurlException("Failed to set CURLOPT_TIMEOUT.");
7575
}
76+
rv = curl_easy_setopt(m_curl.get(), CURLOPT_FOLLOWLOCATION, 1L);
77+
if (rv != CURLE_OK) {
78+
throw CurlException("Failed to set CURLOPT_FOLLOWLOCATION.");
79+
}
7680

7781
{
7882
auto mres = curl_multi_add_handle(m_curl_multi.get(), m_curl.get());
@@ -84,6 +88,16 @@ SimpleCurlGet::GetStatus SimpleCurlGet::perform_start(const std::string &url) {
8488
return perform_continue();
8589
}
8690

91+
std::string SimpleCurlGet::get_url() const {
92+
if (!m_curl) {return "";}
93+
94+
char *url = nullptr;
95+
auto rv = curl_easy_getinfo(m_curl.get(), CURLINFO_EFFECTIVE_URL, &url);
96+
if (rv != CURLE_OK) {return "";}
97+
98+
return std::string(url);
99+
}
100+
87101
SimpleCurlGet::GetStatus SimpleCurlGet::perform_continue() {
88102
int still_running;
89103
auto resm = curl_multi_perform(m_curl_multi.get(), &still_running);
@@ -648,17 +662,21 @@ std::unique_ptr<AsyncStatus> Validator::get_public_keys_from_web_continue(
648662
picojson::value json_obj;
649663
auto err = picojson::parse(json_obj, metadata);
650664
if (!err.empty()) {
651-
throw JsonException(err);
665+
throw JsonException(
666+
"JSON parse failure when downloading from the metadata URL "
667+
+ status->m_cget->get_url() + ": " + err);
652668
}
653669
if (!json_obj.is<picojson::object>()) {
654670
throw JsonException(
655-
"Metadata resource contains improperly-formatted JSON.");
671+
"Metadata resource " + status->m_cget->get_url() + " contains "
672+
"improperly-formatted JSON.");
656673
}
657674
auto top_obj = json_obj.get<picojson::object>();
658675
auto iter = top_obj.find("jwks_uri");
659676
if (iter == top_obj.end() || (!iter->second.is<std::string>())) {
660677
throw JsonException(
661-
"Metadata resource is missing 'jwks_uri' string value");
678+
"Metadata resource " + status->m_cget->get_url() +
679+
" is missing 'jwks_uri' string value");
662680
}
663681
auto jwks_uri = iter->second.get<std::string>();
664682
status->m_has_metadata = true;
@@ -683,7 +701,8 @@ std::unique_ptr<AsyncStatus> Validator::get_public_keys_from_web_continue(
683701
auto err = picojson::parse(json_obj, metadata);
684702
status->m_cget.reset();
685703
if (!err.empty()) {
686-
throw JsonException(err);
704+
throw JsonException("JSON parse failure when downloading from the "
705+
" public key URL " + status->m_cget->get_url() + ": " + err);
687706
}
688707

689708
auto now = std::time(NULL);

src/scitokens_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ class SimpleCurlGet {
8484
GetStatus perform_continue();
8585
int perform(const std::string &url, time_t expiry_time);
8686
void get_data(char *&buffer, size_t &len);
87+
std::string get_url() const;
8788

8889
long get_timeout_ms() const { return m_timeout_ms; }
8990
int get_max_fd() const { return m_max_fd; }

0 commit comments

Comments
 (0)