void ClientCache::handleCheckResponse()

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;
}