in src/envoy/http/service_control/client_cache.cc [364:449]
void ClientCache::handleCheckResponse(const Status& http_status,
CheckResponse* response,
CheckDoneFunc on_done) {
CheckResponseInfo response_info;
Status final_status;
if (http_status.ok()) {
// If the http call succeeded, then use the CheckResponseInfo
// to retrieve the final status.
final_status = api_proxy::service_control::ConvertCheckResponse(
*response, config_.service_name(), &response_info);
collectScResponseErrorStats(response_info.error.type);
} else {
// Otherwise, http call failed. Use that status to respond.
final_status = http_status;
}
if (final_status.ok()) {
// Everything succeeded, API Key is trusted.
response_info.api_key_state = ApiKeyState::VERIFIED;
on_done(final_status, response_info);
} else if (final_status.code() == StatusCode::kUnavailable) {
// All 5xx errors are already translated to Unavailable.
// API Key cannot be trusted due to a network error.
response_info.api_key_state = ApiKeyState::NOT_CHECKED;
if (network_fail_open_) {
filter_stats_.filter_.allowed_control_plane_fault_.inc();
ENVOY_LOG(warn,
"Google Service Control Check is unavailable, but the "
"request is allowed due to network fail open. Original "
"error: {}",
final_status.message());
on_done(OkStatus(), response_info);
} else {
// Preserve the original 5xx error code in the response back.
filter_stats_.filter_.denied_control_plane_fault_.inc();
ENVOY_LOG(warn,
"Google Service Control Check is unavailable, and the "
"request is denied due to network fail closed, with error: {}",
final_status.message());
// If http_status is not ok, the StatusCode::kUnavailable is from
// http_status.
if (!http_status.ok()) {
response_info.error = failCallStatusToScResponseError(http_status);
}
on_done(final_status, response_info);
}
} else {
if (!http_status.ok()) {
// Most likely an auth error in ESPv2 or API producer deployment.
filter_stats_.filter_.denied_producer_error_.inc();
// API Key cannot be trusted due to network error with Service Control.
response_info.api_key_state = ApiKeyState::NOT_CHECKED;
// This is not caused by a client request error, so translate
// non-5xx error codes to 500 Internal Server Error. Error message
// contains details on the original error (including the original
// HTTP status code).
Status scrubbed_status(StatusCode::kInternal, final_status.message());
response_info.error = failCallStatusToScResponseError(http_status);
on_done(scrubbed_status, response_info);
} else {
// HTTP succeeded, but SC Check returned 4xx.
// Stats already incremented for this case.
// Handle API Key validity.
if (response_info.error.type == ScResponseErrorType::API_KEY_INVALID) {
response_info.api_key_state = ApiKeyState::INVALID;
} else if (response_info.error.type ==
ScResponseErrorType::SERVICE_NOT_ACTIVATED) {
response_info.api_key_state = ApiKeyState::NOT_ENABLED;
} else {
// All other SC Check errors assume consumer was identified.
response_info.api_key_state = ApiKeyState::VERIFIED;
}
on_done(final_status, response_info);
}
}
delete response;
}