HttpTransact::build_request(State* s, HTTPHdr* base_request, HTTPHdr* outgoing_request, HTTPVersion outgoing_version)
{
  // this part is to restore the original URL in case, multiple cache
  // lookups have happened - client request has been changed as the result
  //
  // notice that currently, based_request IS client_request
  if (base_request == &s->hdr_info.client_request) {
    if (s->redirect_info.redirect_in_process) {
      // this is for auto redirect
      URL *r_url = &s->redirect_info.redirect_url;

      ink_assert(r_url->valid());
      base_request->url_get()->copy(r_url);
    } else {
      // this is for multiple cache lookup
      URL *o_url = &s->cache_info.original_url;

      if (o_url->valid())
        base_request->url_get()->copy(o_url);
    }
  }

  HttpTransactHeaders::copy_header_fields(base_request, outgoing_request, s->txn_conf->fwd_proxy_auth_to_parent);
  add_client_ip_to_outgoing_request(s, outgoing_request);
  HttpTransactHeaders::remove_privacy_headers_from_request(s->http_config_param, s->txn_conf, outgoing_request);
  HttpTransactHeaders::add_global_user_agent_header_to_request(s->txn_conf, outgoing_request);
  handle_request_keep_alive_headers(s, outgoing_version, outgoing_request);

  // handle_conditional_headers appears to be obsolete.  Nothing happens
  // unelss s->cache_info.action == HttpTransact::CACHE_DO_UPDATE.  In that
  // case an assert will go off.  The functionality of this method
  // (e.g., setting the if-modfied-since header occurs in issue_revalidate
  //HttpTransactHeaders::handle_conditional_headers(&s->cache_info, outgoing_request);

  if (s->next_hop_scheme < 0)
    s->next_hop_scheme = URL_WKSIDX_HTTP;
  if (s->orig_scheme < 0)
    s->orig_scheme = URL_WKSIDX_HTTP;

  if (s->txn_conf->insert_request_via_string)
    HttpTransactHeaders::insert_via_header_in_request(s, outgoing_request);

  // We build 1.1 request header and then convert as necessary to
  //  the appropriate version in HttpTransact::build_request
  outgoing_request->version_set(HTTPVersion(1, 1));

  // Make sure our request version is defined
  ink_assert(outgoing_version != HTTPVersion(0, 0));

  // HttpTransactHeaders::convert_request(outgoing_version, outgoing_request); // commented out this idea


  // Check whether a Host header field is missing from a 1.0 or 1.1 request.
  if (outgoing_version != HTTPVersion(0, 9) && !outgoing_request->presence(MIME_PRESENCE_HOST)) {
    URL *url = outgoing_request->url_get();
    int host_len;
    const char *host = url->host_get(&host_len);

    // Add a ':port' to the HOST header if the request is not going
    // to the default port.
    int port = url->port_get();
    if (port != url_canonicalize_port(URL_TYPE_HTTP, 0)) {
      char *buf = (char *) alloca(host_len + 15);
      memcpy(buf, host, host_len);
      host_len += snprintf(buf + host_len, 15, ":%d", port);
      outgoing_request->value_set(MIME_FIELD_HOST, MIME_LEN_HOST, buf, host_len);
    } else {
      outgoing_request->value_set(MIME_FIELD_HOST, MIME_LEN_HOST, host, host_len);
    }
  }

  if (s->current.server == &s->server_info &&
      (s->next_hop_scheme == URL_WKSIDX_HTTP || s->next_hop_scheme == URL_WKSIDX_HTTPS ||
       s->next_hop_scheme == URL_WKSIDX_WS || s->next_hop_scheme == URL_WKSIDX_WSS)) {
    DebugTxn("http_trans", "[build_request] removing host name from url");
    HttpTransactHeaders::remove_host_name_from_url(outgoing_request);
  }

  // If we're going to a parent proxy, make sure we pass host and port
  // in the URL even if we didn't get them (e.g. transparent proxy)
  if (s->current.request_to == PARENT_PROXY &&
      !outgoing_request->is_target_in_url()) {
    DebugTxn("http_trans", "[build_request] adding target to URL for parent proxy");

    // No worry about HTTP/0.9 because we reject forward proxy requests that
    // don't have a host anywhere.
    outgoing_request->set_url_target_from_host_field();
  }

  // If the response is most likely not cacheable, eg, request with Authorization,
  // do we really want to remove conditional headers to get large 200 response?
  // Answer: NO.  Since if the response is most likely not cacheable,
  // we don't remove conditional headers so that for a non-200 response
  // from the O.S., we will save bandwidth between proxy and O.S.
  if (s->current.mode == GENERIC_PROXY) {
    if (is_request_likely_cacheable(s, base_request)) {
      if (s->txn_conf->cache_when_to_revalidate != 4) {
        DebugTxn("http_trans", "[build_request] " "request like cacheable and conditional headers removed");
        HttpTransactHeaders::remove_conditional_headers(outgoing_request);
      } else
        DebugTxn("http_trans", "[build_request] " "request like cacheable but keep conditional headers");
    } else {
      // In this case, we send a conditional request
      // instead of the normal non-conditional request.
      DebugTxn("http_trans", "[build_request] " "request not like cacheable and conditional headers not removed");
    }
  }

  if (s->http_config_param->send_100_continue_response) {
    HttpTransactHeaders::remove_100_continue_headers(s, outgoing_request);
    DebugTxn("http_trans", "[build_request] request expect 100-continue headers removed");
  }

  s->request_sent_time = ink_cluster_time();
  s->current.now = s->request_sent_time;
  // The assert is backwards in this case because request is being (re)sent.
  ink_assert(s->request_sent_time >= s->response_received_time);


  DebugTxn("http_trans", "[build_request] request_sent_time: %" PRId64, (int64_t)s->request_sent_time);
  if (!s->cop_test_page)
    DUMP_HEADER("http_hdrs", outgoing_request, s->state_machine_id, "Proxy's Request");

  HTTP_INCREMENT_TRANS_STAT(http_outgoing_requests_stat);
}