HttpTransact::initialize_state_variables_from_request(State* s, HTTPHdr* obsolete_incoming_request)
{
  HTTPHdr* incoming_request = &s->hdr_info.client_request;

  // Temporary, until we're confident that the second argument is redundant.
  ink_assert(incoming_request == obsolete_incoming_request);

  int host_len;
  const char *host_name = incoming_request->host_get(&host_len);

  // check if the request is conditional (IMS or INM)
  if (incoming_request->presence(MIME_PRESENCE_IF_MODIFIED_SINCE | MIME_PRESENCE_IF_NONE_MATCH)) {
    SET_VIA_STRING(VIA_CLIENT_REQUEST, VIA_CLIENT_IMS);
  } else {
    SET_VIA_STRING(VIA_CLIENT_REQUEST, VIA_CLIENT_SIMPLE);
  }

  // Is the user agent Keep-Alive?
  //  If we are transparent or if the user-agent is following
  //  the 1.1 spec, we will see a "Connection" header to
  //  indicate a keep-alive.  However most user-agents including
  //  MSIE3.0, Netscape4.04 and Netscape3.01 send Proxy-Connection
  //  when they are configured to use a proxy.  Proxy-Connection
  //  is not in the spec but was added to prevent problems
  //  with a dumb proxy forwarding all headers (including "Connection")
  //  to the origin server and confusing it.  In cases of transparent
  //  deployments we use the Proxy-Connect hdr (to be as transparent
  //  as possible).
  MIMEField *pc = incoming_request->field_find(MIME_FIELD_PROXY_CONNECTION, MIME_LEN_PROXY_CONNECTION);

  // If we need to send a close header later check to see if it should be "Proxy-Connection"
  if (pc != NULL) {
    s->client_info.proxy_connect_hdr = true;
  }

  if (!s->txn_conf->keep_alive_enabled_in) {
    s->client_info.keep_alive = HTTP_NO_KEEPALIVE;
  } else {
    // If there is a Proxy-Connection header use that, otherwise use the Connection header
    if (pc != NULL) {
      s->client_info.keep_alive = is_header_keep_alive(s->client_info.http_version, s->client_info.http_version, pc);
    } else {
      MIMEField *c = incoming_request->field_find(MIME_FIELD_CONNECTION, MIME_LEN_CONNECTION);

      s->client_info.keep_alive = is_header_keep_alive(s->client_info.http_version, s->client_info.http_version, c);
    }
  }

  if (s->client_info.keep_alive == HTTP_KEEPALIVE && s->client_info.http_version == HTTPVersion(1, 1)) {
    s->client_info.pipeline_possible = true;
  }

  if (!s->server_info.name || s->redirect_info.redirect_in_process) {
    s->server_info.name = s->arena.str_store(host_name, host_len);
    s->server_info.port = incoming_request->port_get();
  }

  s->next_hop_scheme = s->scheme = incoming_request->url_get()->scheme_get_wksidx();

  // With websockets we need to make an outgoing request
  // as http or https.
  // We switch back to HTTP or HTTPS for the next hop
  // I think this is required to properly establish outbound WSS connections,
  // you'll need to force the next hop to be https.
  if (s->is_websocket) {
    if (s->next_hop_scheme == URL_WKSIDX_WS) {
      DebugTxn("http_trans", "Switching WS next hop scheme to http.");
      s->next_hop_scheme = URL_WKSIDX_HTTP;
      s->scheme = URL_WKSIDX_HTTP;
      //s->request_data.hdr->url_get()->scheme_set(URL_SCHEME_HTTP, URL_LEN_HTTP);
    } else if (s->next_hop_scheme == URL_WKSIDX_WSS) {
      DebugTxn("http_trans", "Switching WSS next hop scheme to https.");
      s->next_hop_scheme = URL_WKSIDX_HTTPS;
      s->scheme = URL_WKSIDX_HTTPS;
      //s->request_data.hdr->url_get()->scheme_set(URL_SCHEME_HTTPS, URL_LEN_HTTPS);
    } else {
      Error("Scheme doesn't match websocket...!");
    }

    s->current.mode = GENERIC_PROXY;
    s->cache_info.action = CACHE_DO_NO_ACTION;
  }

  s->method = incoming_request->method_get_wksidx();

  if (s->method == HTTP_WKSIDX_GET) {
    HTTP_INCREMENT_TRANS_STAT(http_get_requests_stat);
  } else if (s->method == HTTP_WKSIDX_HEAD) {
    HTTP_INCREMENT_TRANS_STAT(http_head_requests_stat);
  } else if (s->method == HTTP_WKSIDX_POST) {
    HTTP_INCREMENT_TRANS_STAT(http_post_requests_stat);
  } else if (s->method == HTTP_WKSIDX_PUT) {
    HTTP_INCREMENT_TRANS_STAT(http_put_requests_stat);
  } else if (s->method == HTTP_WKSIDX_CONNECT) {
    HTTP_INCREMENT_TRANS_STAT(http_connect_requests_stat);
  } else if (s->method == HTTP_WKSIDX_DELETE) {
    HTTP_INCREMENT_TRANS_STAT(http_delete_requests_stat);
  } else if (s->method == HTTP_WKSIDX_PURGE) {
    HTTP_INCREMENT_TRANS_STAT(http_purge_requests_stat);
  } else if (s->method == HTTP_WKSIDX_TRACE) {
    HTTP_INCREMENT_TRANS_STAT(http_trace_requests_stat);
  } else if (s->method == HTTP_WKSIDX_PUSH) {
    HTTP_INCREMENT_TRANS_STAT(http_push_requests_stat);
  } else if (s->method == HTTP_WKSIDX_OPTIONS) {
    HTTP_INCREMENT_TRANS_STAT(http_options_requests_stat);
  } else if (s->method == HTTP_WKSIDX_TRACE) {
    HTTP_INCREMENT_TRANS_STAT(http_trace_requests_stat);
  } else {
    HTTP_INCREMENT_TRANS_STAT(http_extension_method_requests_stat);
    SET_VIA_STRING(VIA_DETAIL_TUNNEL, VIA_DETAIL_TUNNEL_METHOD);
    s->squid_codes.log_code = SQUID_LOG_TCP_MISS;
    s->hdr_info.extension_method = true;
  }

  // if transfer encoding is chunked content length is undefined
  if (s->client_info.transfer_encoding == CHUNKED_ENCODING) {
    s->hdr_info.request_content_length = HTTP_UNDEFINED_CL;
  }
  s->request_data.hdr = &s->hdr_info.client_request;

  s->request_data.hostname_str = s->arena.str_store(host_name, host_len);
  ats_ip_copy(&s->request_data.src_ip, &s->client_info.addr);
  memset(&s->request_data.dest_ip, 0, sizeof(s->request_data.dest_ip));
  if (s->state_machine->ua_session) {
    s->request_data.incoming_port = s->state_machine->ua_session->get_netvc()->get_local_port();
  }
  s->request_data.xact_start = s->client_request_time;
  s->request_data.api_info = &s->api_info;

  /////////////////////////////////////////////
  // Do dns lookup for the host. We need     //
  // the expanded host for cache lookup, and //
  // the host ip for reverse proxy.          //
  /////////////////////////////////////////////
  s->dns_info.looking_up = ORIGIN_SERVER;
  s->dns_info.attempts = 0;
  s->dns_info.lookup_name = s->server_info.name;
}