HttpTransact::HandleCacheOpenReadHitFreshness(State* s)
{
  CacheHTTPInfo *&obj = s->cache_info.object_read;

  ink_release_assert((s->request_sent_time == UNDEFINED_TIME) && (s->response_received_time == UNDEFINED_TIME));
  DebugTxn("http_seq", "[HttpTransact::HandleCacheOpenReadHitFreshness] Hit in cache");

  if (delete_all_document_alternates_and_return(s, true)) {
    DebugTxn("http_trans", "[HandleCacheOpenReadHitFreshness] Delete and return");
    s->cache_info.action = CACHE_DO_DELETE;
    s->next_action = HttpTransact::SM_ACTION_INTERNAL_CACHE_DELETE;
    return;
  }

  s->request_sent_time = obj->request_sent_time_get();
  s->response_received_time = obj->response_received_time_get();

  // There may be clock skew if one of the machines
  // went down and we do not have the correct delta
  // for it. this is just to deal with the effects
  // of the skew by setting minimum and maximum times
  // so that ages are not negative, etc.
  s->request_sent_time = min(s->client_request_time, s->request_sent_time);
  s->response_received_time = min(s->client_request_time, s->response_received_time);

  ink_assert(s->request_sent_time <= s->response_received_time);

  DebugTxn("http_trans", "[HandleCacheOpenReadHitFreshness] request_sent_time      : %" PRId64,
           (int64_t)s->request_sent_time);
  DebugTxn("http_trans", "[HandleCacheOpenReadHitFreshness] response_received_time : %" PRId64,
           (int64_t)s->response_received_time);
  // if the plugin has already decided the freshness, we don't need to
  // do it again
  if (s->cache_lookup_result == HttpTransact::CACHE_LOOKUP_NONE) {
    // is the document still fresh enough to be served back to
    // the client without revalidation?
    Freshness_t freshness = what_is_document_freshness(s, &s->hdr_info.client_request, obj->response_get());
    switch (freshness) {
    case FRESHNESS_FRESH:
      DebugTxn("http_seq", "[HttpTransact::HandleCacheOpenReadHitFreshness] " "Fresh copy");
      s->cache_lookup_result = HttpTransact::CACHE_LOOKUP_HIT_FRESH;
      break;
    case FRESHNESS_WARNING:
      DebugTxn("http_seq", "[HttpTransact::HandleCacheOpenReadHitFreshness] " "Heuristic-based Fresh copy");
      s->cache_lookup_result = HttpTransact::CACHE_LOOKUP_HIT_WARNING;
      break;
    case FRESHNESS_STALE:
      DebugTxn("http_seq", "[HttpTransact::HandleCacheOpenReadHitFreshness] " "Stale in cache");
      s->cache_lookup_result = HttpTransact::CACHE_LOOKUP_HIT_STALE;
      s->is_revalidation_necessary = true;      // to identify a revalidation occurrence
      break;
    default:
      ink_assert(!("what_is_document_freshness has returned unsupported code."));
      break;
    }
  }

  ink_assert(s->cache_lookup_result != HttpTransact::CACHE_LOOKUP_MISS);
  if (s->cache_lookup_result == HttpTransact::CACHE_LOOKUP_HIT_STALE)
    SET_VIA_STRING(VIA_DETAIL_CACHE_LOOKUP, VIA_DETAIL_MISS_EXPIRED);

  if (!s->force_dns) {          // If DNS is not performed before
    if (need_to_revalidate(s)) {
      TRANSACT_RETURN(SM_ACTION_API_CACHE_LOOKUP_COMPLETE, CallOSDNSLookup); // content needs to be revalidated and we did not perform a dns ....calling DNS lookup
    } else {                    // document can be served can cache
      TRANSACT_RETURN(SM_ACTION_API_CACHE_LOOKUP_COMPLETE, HttpTransact::HandleCacheOpenReadHit);
    }
  } else {                      // we have done dns . Its up to HandleCacheOpenReadHit to decide to go OS or serve from cache
    TRANSACT_RETURN(SM_ACTION_API_CACHE_LOOKUP_COMPLETE, HttpTransact::HandleCacheOpenReadHit);
  }
}