|
@@ -183,7 +183,16 @@ void WebhookController::handleWebhook(const httplib::Request& req, httplib::Resp
|
|
|
if (parsed_ok && parsed.is_object() && parsed.contains("_webhookResponse")) {
|
|
if (parsed_ok && parsed.is_object() && parsed.contains("_webhookResponse")) {
|
|
|
const auto& spec = parsed["_webhookResponse"];
|
|
const auto& spec = parsed["_webhookResponse"];
|
|
|
|
|
|
|
|
- int status_code = spec.value("status", 200);
|
|
|
|
|
|
|
+ int status_code = 200;
|
|
|
|
|
+ if (spec.contains("status")) {
|
|
|
|
|
+ if (spec["status"].is_number_integer()) {
|
|
|
|
|
+ status_code = spec["status"].get<int>();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ LOG_WARN("Webhook response status must be a whole number, got {}; sending 500",
|
|
|
|
|
+ spec["status"].dump());
|
|
|
|
|
+ status_code = 500;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
if (status_code < 100 || status_code > 599) {
|
|
if (status_code < 100 || status_code > 599) {
|
|
|
LOG_WARN("Webhook response asked for status {}, which is not a valid HTTP status; sending 500",
|
|
LOG_WARN("Webhook response asked for status {}, which is not a valid HTTP status; sending 500",
|
|
|
status_code);
|
|
status_code);
|
|
@@ -194,6 +203,7 @@ void WebhookController::handleWebhook(const httplib::Request& req, httplib::Resp
|
|
|
if (spec.contains("headers") && spec["headers"].is_object()) {
|
|
if (spec.contains("headers") && spec["headers"].is_object()) {
|
|
|
for (auto it = spec["headers"].begin(); it != spec["headers"].end(); ++it) {
|
|
for (auto it = spec["headers"].begin(); it != spec["headers"].end(); ++it) {
|
|
|
if (!it.value().is_string()) {
|
|
if (!it.value().is_string()) {
|
|
|
|
|
+ LOG_WARN("Webhook response header {} is not a string, skipping it", it.key());
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
|
// Content-Type reaches httplib through set_content rather
|
|
// Content-Type reaches httplib through set_content rather
|
|
@@ -215,6 +225,10 @@ void WebhookController::handleWebhook(const httplib::Request& req, httplib::Resp
|
|
|
if (spec.contains("body")) {
|
|
if (spec.contains("body")) {
|
|
|
const auto& value = spec["body"];
|
|
const auto& value = spec["body"];
|
|
|
body = value.is_string() ? value.get<std::string>() : value.dump();
|
|
body = value.is_string() ? value.get<std::string>() : value.dump();
|
|
|
|
|
+ } else if (content_type.find("json") != std::string::npos) {
|
|
|
|
|
+ // An empty body is not valid JSON, and a strict client would
|
|
|
|
|
+ // fail to parse it against the Content-Type we are sending.
|
|
|
|
|
+ body = "{}";
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
res.status = status_code;
|
|
res.status = status_code;
|