HttpTransact::is_request_valid(State* s, HTTPHdr* incoming_request)
{
  RequestError_t incoming_error;
  URL *url = NULL;

  if (incoming_request)
    url = incoming_request->url_get();

  incoming_error = check_request_validity(s, incoming_request);
  switch (incoming_error) {
  case NO_REQUEST_HEADER_ERROR:
    DebugTxn("http_trans", "[is_request_valid]" "no request header errors");
    break;
  case FAILED_PROXY_AUTHORIZATION:
    DebugTxn("http_trans", "[is_request_valid]" "failed proxy authorization");
    SET_VIA_STRING(VIA_DETAIL_TUNNEL, VIA_DETAIL_TUNNEL_NO_FORWARD);
    build_error_response(s, HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED, "Proxy Authentication Required",
                         "access#proxy_auth_required", NULL);
    return false;
  case NON_EXISTANT_REQUEST_HEADER:
    /* fall through */
  case BAD_HTTP_HEADER_SYNTAX:
    {
      DebugTxn("http_trans", "[is_request_valid]" "non-existant/bad header");
      SET_VIA_STRING(VIA_DETAIL_TUNNEL, VIA_DETAIL_TUNNEL_NO_FORWARD);
      build_error_response(s, HTTP_STATUS_BAD_REQUEST, "Invalid HTTP Request", "request#syntax_error", NULL);
      return false;
    }

  case MISSING_HOST_FIELD:

    ////////////////////////////////////////////////////////////////////
    // FIX: are we sure the following logic is right?  it seems that  //
    //      we shouldn't complain about the missing host header until //
    //      we know we really need one --- are we sure we need a host //
    //      header at this point?                                     //
    //                                                                //
    // FIX: also, let's clean up the transparency code to remove the  //
    //      SunOS conditionals --- we will be transparent on all      //
    //      platforms soon!  in fact, I really want a method that i   //
    //      can call for each transaction to say if the transaction   //
    //      is a forward proxy request, a transparent request, a      //
    //      reverse proxy request, etc --- the detail of how we       //
    //      determine the cases should be hidden behind the method.   //
    ////////////////////////////////////////////////////////////////////

    DebugTxn("http_trans", "[is_request_valid] missing host field");
    SET_VIA_STRING(VIA_DETAIL_TUNNEL, VIA_DETAIL_TUNNEL_NO_FORWARD);
    if (s->http_config_param->reverse_proxy_enabled) {   // host header missing and reverse proxy on
      build_error_response(s, HTTP_STATUS_BAD_REQUEST, "Host Header Required", "request#no_host", NULL);
    } else {
      // host header missing and reverse proxy off
      build_error_response(s, HTTP_STATUS_BAD_REQUEST, "Host Required In Request", "request#no_host", NULL);
    }

    return false;
  case SCHEME_NOT_SUPPORTED:
  case NO_REQUEST_SCHEME:
    {
      DebugTxn("http_trans", "[is_request_valid] unsupported " "or missing request scheme");
      SET_VIA_STRING(VIA_DETAIL_TUNNEL, VIA_DETAIL_TUNNEL_NO_FORWARD);
      build_error_response(s, HTTP_STATUS_BAD_REQUEST, "Unsupported URL Scheme", "request#scheme_unsupported", NULL);
      return false;
    }
    /* fall through */
  case METHOD_NOT_SUPPORTED:
    DebugTxn("http_trans", "[is_request_valid]" "unsupported method");
    s->current.mode = TUNNELLING_PROXY;
    return true;
  case BAD_CONNECT_PORT:
    int port;
    port = url ? url->port_get() : 0;
    DebugTxn("http_trans", "[is_request_valid]" "%d is an invalid connect port", port);
    SET_VIA_STRING(VIA_DETAIL_TUNNEL, VIA_DETAIL_TUNNEL_NO_FORWARD);
    build_error_response(s, HTTP_STATUS_FORBIDDEN, "Tunnel Forbidden", "access#connect_forbidden", NULL);
    return false;
  case NO_POST_CONTENT_LENGTH:
    {
      DebugTxn("http_trans", "[is_request_valid] post request without content length");
      SET_VIA_STRING(VIA_DETAIL_TUNNEL, VIA_DETAIL_TUNNEL_NO_FORWARD);
      build_error_response(s, HTTP_STATUS_LENGTH_REQUIRED, "Content Length Required", "request#no_content_length", NULL);
      return false;
    }
  case UNACCEPTABLE_TE_REQUIRED:
    {
      DebugTxn("http_trans", "[is_request_valid] TE required is unacceptable.");
      SET_VIA_STRING(VIA_DETAIL_TUNNEL, VIA_DETAIL_TUNNEL_NO_FORWARD);
      build_error_response(s, HTTP_STATUS_NOT_ACCEPTABLE, "Transcoding Not Available", "transcoding#unsupported", NULL);
      return false;
    }
  case INVALID_POST_CONTENT_LENGTH :
    {
      DebugTxn("http_trans", "[is_request_valid] post request with negative content length value");
      SET_VIA_STRING(VIA_DETAIL_TUNNEL, VIA_DETAIL_TUNNEL_NO_FORWARD);
      build_error_response(s, HTTP_STATUS_BAD_REQUEST, "Invalid Content Length", "request#invalid_content_length", NULL);
      return false;
    }
  default:
    return true;
  }

  return true;
}