HttpTransact::HandleRequest(State* s)
{
  DebugTxn("http_trans", "START HttpTransact::HandleRequest");

  ink_assert(!s->hdr_info.server_request.valid());

  HTTP_INCREMENT_TRANS_STAT(http_incoming_requests_stat);

  if (s->client_info.port_attribute == HttpProxyPort::TRANSPORT_SSL) {
    HTTP_INCREMENT_TRANS_STAT(https_incoming_requests_stat);
  }

  if (s->api_release_server_session == true) {
    s->api_release_server_session = false;
  }
  ///////////////////////////////////////////////
  // if request is bad, return error response  //
  ///////////////////////////////////////////////

  if (!(is_request_valid(s, &s->hdr_info.client_request))) {
    HTTP_INCREMENT_TRANS_STAT(http_invalid_client_requests_stat);
    DebugTxn("http_seq", "[HttpTransact::HandleRequest] request invalid.");
    s->next_action = SM_ACTION_SEND_ERROR_CACHE_NOOP;
    //  s->next_action = HttpTransact::PROXY_INTERNAL_CACHE_NOOP;
    return;
  }
  DebugTxn("http_seq", "[HttpTransact::HandleRequest] request valid.");

  if (is_debug_tag_set("http_chdr_describe")) {
    obj_describe(s->hdr_info.client_request.m_http, 1);
  }

  // at this point we are guaranteed that the request is good and acceptable.
  // initialize some state variables from the request (client version,
  // client keep-alive, cache action, etc.
  initialize_state_variables_from_request(s, &s->hdr_info.client_request);

  // Cache lookup or not will be decided later at DecideCacheLookup().
  // Before it's decided to do a cache lookup,
  // assume no cache lookup and using proxy (not tunneling)
  s->cache_info.action = CACHE_DO_NO_ACTION;
  s->current.mode = GENERIC_PROXY;

  // initialize the cache_control structure read from cache.config
  update_cache_control_information_from_config(s);

  // We still need to decide whether or not to do a cache lookup since
  // the scheduled update code depends on this info.
  if (is_request_cache_lookupable(s))
    s->cache_info.action = CACHE_DO_LOOKUP;

  // If the hostname is "$internal$" then this is a request for
  // internal proxy information.
  if (handle_internal_request(s, &s->hdr_info.client_request)) {
    TRANSACT_RETURN(SM_ACTION_INTERNAL_REQUEST, NULL);
  }

  // this needs to be called after initializing state variables from request
  // it adds the client-ip to the incoming client request.

  if (!s->cop_test_page)
    DUMP_HEADER("http_hdrs", &s->hdr_info.client_request, s->state_machine_id, "Incoming Request");

  if (s->state_machine->plugin_tunnel_type == HTTP_PLUGIN_AS_INTERCEPT) {
    setup_plugin_request_intercept(s);
    return;
  }

  // if ip in url or cop test page, not do srv lookup.
  if (s->srv_lookup) {
    if (s->cop_test_page)
      s->srv_lookup = false;
    else {
      IpEndpoint addr;
      ats_ip_pton(s->server_info.name, &addr);
      s->srv_lookup = !ats_is_ip(&addr);
    }
  }

  // if the request is a trace or options request, decrement the
  // max-forwards value. if the incoming max-forwards value was 0,
  // then we have to return a response to the client with the
  // appropriate action for trace/option. in this case this routine
  // is responsible for building the response.
  if (handle_trace_and_options_requests(s, &s->hdr_info.client_request)) {
    TRANSACT_RETURN(SM_ACTION_INTERNAL_CACHE_NOOP, NULL);
  }

  if (s->http_config_param->no_dns_forward_to_parent
    && s->scheme != URL_WKSIDX_HTTPS
    && strcmp(s->server_info.name, "127.0.0.1") != 0
  ) {
    // for HTTPS requests, we must go directly to the
    // origin server. Ignore the no_dns_just_forward_to_parent setting.
    // we need to see if the hostname is an
    //   ip address since the parent selection code result
    //   could change as a result of this ip address
    IpEndpoint addr;
    ats_ip_pton(s->server_info.name, &addr);
    if (ats_is_ip(&addr)) {
      ats_ip_copy(&s->request_data.dest_ip, &addr);
    }

    if (s->parent_params->parentExists(&s->request_data)) {
      // If the proxy is behind and firewall and there is no
      //  DNS service available, we just want to forward the request
      //  the parent proxy.  In this case, we never find out the
      //  origin server's ip.  So just skip past OSDNS
      ats_ip_invalidate(&s->server_info.addr);
      StartAccessControl(s);
      return;
    } else if (s->http_config_param->no_origin_server_dns) {
      build_error_response(s, HTTP_STATUS_BAD_GATEWAY, "Next Hop Connection Failed", "connect#failed_connect", NULL);

      TRANSACT_RETURN(SM_ACTION_SEND_ERROR_CACHE_NOOP, NULL);
    }
  }

  // Added to skip the dns if the document is in the cache.
  // DNS is requested before cache lookup only if there are rules in cache.config , parent.config or
  // if the newly added varible doc_in_cache_skip_dns is not enabled
  if (s->dns_info.lookup_name[0] <= '9' &&
      s->dns_info.lookup_name[0] >= '0' &&
      (!s->state_machine->enable_redirection || !s->redirect_info.redirect_in_process) &&
      s->parent_params->ParentTable->hostMatch) {
    s->force_dns = 1;
  }
  //YTS Team, yamsat Plugin
  //Doing a Cache Lookup in case of a Redirection to ensure that
  //the newly requested object is not in the CACHE
  if (s->txn_conf->cache_http && s->redirect_info.redirect_in_process && s->state_machine->enable_redirection) {
    TRANSACT_RETURN(SM_ACTION_CACHE_LOOKUP, NULL);
  }


  if (s->force_dns) {
    TRANSACT_RETURN(SM_ACTION_DNS_LOOKUP, OSDNSLookup);   // After handling the request, DNS is done.
  } else {
    // After the requested is properly handled No need of requesting the DNS directly check the ACLs
    // if the request is authorized
    StartAccessControl(s);
  }
}