HttpTransact::handle_forward_server_connection_open(State* s)
{
  DebugTxn("http_trans", "[handle_forward_server_connection_open] (hfsco)");
  DebugTxn("http_seq", "[HttpTransact::handle_server_connection_open] ");
  ink_release_assert(s->current.state == CONNECTION_ALIVE);

  if (s->hdr_info.server_response.version_get() == HTTPVersion(0, 9)) {
    DebugTxn("http_trans", "[hfsco] server sent 0.9 response, reading...");
    build_response(s, &s->hdr_info.client_response, s->client_info.http_version, HTTP_STATUS_OK, "Connection Established");

    s->client_info.keep_alive = HTTP_NO_KEEPALIVE;
    s->cache_info.action = CACHE_DO_NO_ACTION;
    s->next_action = SM_ACTION_SERVER_READ;
    return;

  }
  else if (s->hdr_info.server_response.version_get() == HTTPVersion(1, 0)) {
    if (s->current.server->http_version == HTTPVersion(0, 9)) {
      // update_hostdb_to_indicate_server_version_is_1_0
      s->updated_server_version = HostDBApplicationInfo::HTTP_VERSION_10;
    } else if (s->current.server->http_version == HTTPVersion(1, 1)) {
      // update_hostdb_to_indicate_server_version_is_1_0
      s->updated_server_version = HostDBApplicationInfo::HTTP_VERSION_10;
    } else {
      // dont update the hostdb. let us try again with what we currently think.
    }
  } else if (s->hdr_info.server_response.version_get() == HTTPVersion(1, 1)) {
    if (s->current.server->http_version == HTTPVersion(0, 9)) {
      // update_hostdb_to_indicate_server_version_is_1_1
      s->updated_server_version = HostDBApplicationInfo::HTTP_VERSION_11;
    } else if (s->current.server->http_version == HTTPVersion(1, 0)) {
      // update_hostdb_to_indicate_server_version_is_1_1
      s->updated_server_version = HostDBApplicationInfo::HTTP_VERSION_11;
    } else {
      // dont update the hostdb. let us try again with what we currently think.
    }
  } else {
    // dont update the hostdb. let us try again with what we currently think.
  }

  if (s->hdr_info.server_response.status_get() == HTTP_STATUS_CONTINUE) {
    handle_100_continue_response(s);
    return;
  }

  s->state_machine->do_hostdb_update_if_necessary();

  if (s->www_auth_content == CACHE_AUTH_FRESH) {
    // no update is needed - either to serve from cache if authorized,
    // or tunnnel the server response
    if (s->hdr_info.server_response.status_get() == HTTP_STATUS_OK) {
      // borrow a state variable used by the API function
      // this enable us to serve from cache without doing any updating
      s->api_server_response_ignore = true;
    }
    //s->cache_info.action = CACHE_PREPARE_TO_SERVE;
    // xing xing in the tunneling case, need to check when the cache_read_vc is closed, make sure the cache_read_vc is closed right away
  }

  CacheVConnection* cw_vc = s->state_machine->get_cache_sm().cache_write_vc;

  if (s->redirect_info.redirect_in_process && s->state_machine->enable_redirection) {
    if (s->cache_info.action == CACHE_DO_NO_ACTION) {
      switch (s->hdr_info.server_response.status_get())
      {
      case HTTP_STATUS_MULTIPLE_CHOICES:     //300
      case HTTP_STATUS_MOVED_PERMANENTLY:    //301
      case HTTP_STATUS_MOVED_TEMPORARILY:    //302
      case HTTP_STATUS_SEE_OTHER:            //303
      case HTTP_STATUS_USE_PROXY:            //305
      case HTTP_STATUS_TEMPORARY_REDIRECT:   //307
        break;
      default:
        DebugTxn("http_trans", "[hfsco] redirect in progress, non-3xx response, setting cache_do_write");
        if (cw_vc) s->cache_info.action = CACHE_DO_WRITE;
        break;
      }
    }
  }

  switch (s->cache_info.action) {
  case CACHE_DO_WRITE:
    /* fall through */
  case CACHE_DO_UPDATE:
    /* fall through */
  case CACHE_DO_DELETE:
    DebugTxn("http_trans", "[hfsco] cache action: %s", HttpDebugNames::get_cache_action_name(s->cache_info.action));
    handle_cache_operation_on_forward_server_response(s);
    break;
  case CACHE_PREPARE_TO_DELETE:
    /* fall through */
  case CACHE_PREPARE_TO_UPDATE:
    /* fall through */
  case CACHE_PREPARE_TO_WRITE:
    ink_release_assert(!"Why still preparing for cache action - we skipped a step somehow.");
    break;
  case CACHE_DO_LOOKUP:
    /* fall through */
  case CACHE_DO_SERVE:
    ink_assert(!("Why server response? Should have been a cache operation"));
    break;
  case CACHE_DO_UNDEFINED:
    /* fall through */
  case CACHE_DO_NO_ACTION:
    /* fall through */
  default:
    // Just tunnel?
    DebugTxn("http_trans", "[hfsco] cache action: %s", HttpDebugNames::get_cache_action_name(s->cache_info.action));
    handle_no_cache_operation_on_forward_server_response(s);
    break;
  }

  return;
}