HttpTransact::ModifyRequest(State* s)
{
  int scheme, hostname_len;
  const char *hostname;
  HTTPHdr& request = s->hdr_info.client_request;

  DebugTxn("http_trans", "START HttpTransact::ModifyRequest");

  // Initialize the state vars necessary to sending error responses
  bootstrap_state_variables_from_request(s, &request);

  ////////////////////////////////////////////////
  // If there is no scheme default to http      //
  ////////////////////////////////////////////////
  URL *url = request.url_get();

  s->orig_scheme = (scheme = url->scheme_get_wksidx());

  s->method = request.method_get_wksidx();
  if (scheme < 0 && s->method != HTTP_WKSIDX_CONNECT) {
    if (s->client_info.port_attribute == HttpProxyPort::TRANSPORT_SSL) {
      url->scheme_set(URL_SCHEME_HTTPS, URL_LEN_HTTPS);
      s->orig_scheme = URL_WKSIDX_HTTPS;
    } else {
      url->scheme_set(URL_SCHEME_HTTP, URL_LEN_HTTP);
      s->orig_scheme = URL_WKSIDX_HTTP;
    }
  }

  if (s->method == HTTP_WKSIDX_CONNECT && !request.is_port_in_header())
    url->port_set(80);

  // Ugly - this must come after the call to url->scheme_set or
  // it can't get the scheme properly and the wrong data is cached.
  // The solution should be to move the scheme detecting logic in to
  // the header class, rather than doing it in a random bit of
  // external code.
  hostname = request.host_get(&hostname_len);
  if (!request.is_target_in_url()) {
    s->hdr_info.client_req_is_server_style = true;
  }

  // If the incoming request is proxy-style make sure the Host: header
  // matches the incoming request URL. The exception is if we have
  // Max-Forwards set to 0 in the request
  int max_forwards = -1;  // -1 is a valid value meaning that it didn't find the header
  if (request.presence(MIME_PRESENCE_MAX_FORWARDS)) {
    max_forwards = request.get_max_forwards();
  }

  if ((max_forwards != 0) && !s->hdr_info.client_req_is_server_style && s->method != HTTP_WKSIDX_CONNECT) {
    MIMEField *host_field = request.field_find(MIME_FIELD_HOST, MIME_LEN_HOST);
    int host_val_len = hostname_len;
    const char **host_val = &hostname;
    int port = url->port_get_raw();
    char *buf = NULL;

    // Form the host:port string if not a default port (e.g. 80)
    if (port > 0) {
      buf = (char *)alloca(host_val_len + 15);
      memcpy(buf, hostname, host_val_len);
      host_val_len += snprintf(buf + host_val_len, 15, ":%d", port);
      host_val = (const char**)(&buf);
    }

    if (mimefield_value_equal(host_field, *host_val, host_val_len) == false) {
      if (!host_field) { // Assure we have a Host field, before setting it
        host_field = request.field_create(MIME_FIELD_HOST, MIME_LEN_HOST);
        request.field_attach(host_field);
      }
      request.field_value_set(host_field, *host_val, host_val_len);
      request.mark_target_dirty();
    }
  }

  if (s->txn_conf->normalize_ae_gzip) {
    // if enabled, force Accept-Encoding header to gzip or no header
    MIMEField *ae_field = s->hdr_info.client_request.field_find(MIME_FIELD_ACCEPT_ENCODING, MIME_LEN_ACCEPT_ENCODING);

    if (ae_field) {
      if (HttpTransactCache::match_gzip(ae_field) == GZIP) {
        s->hdr_info.client_request.field_value_set(ae_field, "gzip", 4);
        DebugTxn("http_trans", "[ModifyRequest] normalized Accept-Encoding to gzip");
      } else {
        s->hdr_info.client_request.field_delete(ae_field);
        DebugTxn("http_trans", "[ModifyRequest] removed non-gzip Accept-Encoding");
      }
    }
  }

  /////////////////////////////////////////////////////////
  // Modify Accept-Encoding for several specific User-Agent
  /////////////////////////////////////////////////////////
  if (s->txn_conf->accept_encoding_filter_enabled) {
    perform_accept_encoding_filtering(s);
  }

  DebugTxn("http_trans", "END HttpTransact::ModifyRequest");

  DebugTxn("http_trans", "Checking if transaction wants to upgrade");
  if(handle_upgrade_request(s)) {
    // everything should be handled by the upgrade handler.
    DebugTxn("http_trans", "Transaction will be upgraded by the appropriate upgrade handler.");
    return;
  }

  TRANSACT_RETURN(SM_ACTION_API_READ_REQUEST_HDR, HttpTransact::StartRemapRequest);
}