mturk       2004/08/06 10:12:00

  Modified:    ajp/proxy proxy_ajp.c
  Log:
  Use the new connection pool for AJP.
  
  Revision  Changes    Path
  1.12      +75 -346   jakarta-tomcat-connectors/ajp/proxy/proxy_ajp.c
  
  Index: proxy_ajp.c
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/ajp/proxy/proxy_ajp.c,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- proxy_ajp.c       2 Aug 2004 17:05:06 -0000       1.11
  +++ proxy_ajp.c       6 Aug 2004 17:12:00 -0000       1.12
  @@ -20,24 +20,6 @@
   
   module AP_MODULE_DECLARE_DATA proxy_ajp_module;
   
  -int ap_proxy_ajp_canon(request_rec *r, char *url);
  -int ap_proxy_ajp_handler(request_rec *r, proxy_server_conf *conf,
  -                          char *url, const char *proxyname, 
  -                          apr_port_t proxyport);
  -
  -typedef struct {
  -    const char     *name;
  -    apr_port_t      port;
  -    apr_sockaddr_t *addr;
  -    apr_socket_t   *sock;
  -    int             close;
  -    void           *data;  /* To store ajp data */
  -} proxy_ajp_conn_t;
  -
  -static apr_status_t ap_proxy_ajp_cleanup(request_rec *r,
  -                                          proxy_ajp_conn_t *p_conn,
  -                                          proxy_conn_rec *backend);
  -
   /*
    * Canonicalise http-like URLs.
    *  scheme is the scheme for the URL
  @@ -116,230 +98,9 @@
   }
    
   static
  -apr_status_t ap_proxy_http_determine_connection(apr_pool_t *p, request_rec *r,
  -                                                proxy_ajp_conn_t *p_conn,
  -                                                conn_rec *c,
  -                                                proxy_server_conf *conf,
  -                                                apr_uri_t *uri,
  -                                                char **url,
  -                                                const char *proxyname,
  -                                                apr_port_t proxyport,
  -                                                char *server_portstr,
  -                                                int server_portstr_size) {
  -    int server_port;
  -    apr_status_t err;
  -    apr_sockaddr_t *uri_addr;
  -    /*
  -     * Break up the URL to determine the host to connect to
  -     */
  -
  -    /* we break the URL into host, port, uri */
  -    if (APR_SUCCESS != apr_uri_parse(p, *url, uri)) {
  -        return ap_proxyerror(r, HTTP_BAD_REQUEST,
  -                             apr_pstrcat(p,"URI cannot be parsed: ", *url,
  -                                         NULL));
  -    }
  -    if (!uri->port) {
  -        uri->port = apr_uri_port_of_scheme(uri->scheme);
  -    }
  -
  -    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
  -                 "proxy: AJP connecting %s to %s:%d", *url, uri->hostname,
  -                 uri->port);
  -
  -    /* do a DNS lookup for the destination host */
  -    /* see memory note above */
  -    err = apr_sockaddr_info_get(&uri_addr, apr_pstrdup(c->pool, uri->hostname),
  -                                APR_UNSPEC, uri->port, 0, c->pool);
  -
  -    /* allocate these out of the connection pool - the check on
  -     * r->connection->id makes sure that this string does not get accessed
  -     * past the connection lifetime */
  -    /* are we connecting directly, or via a proxy? */
  -    if (proxyname) {
  -        p_conn->name = apr_pstrdup(c->pool, proxyname);
  -        p_conn->port = proxyport;
  -        /* see memory note above */
  -        err = apr_sockaddr_info_get(&p_conn->addr, p_conn->name, APR_UNSPEC,
  -                                    p_conn->port, 0, c->pool);
  -    } else {
  -        p_conn->name = apr_pstrdup(c->pool, uri->hostname);
  -        p_conn->port = uri->port;
  -        p_conn->addr = uri_addr;
  -        *url = apr_pstrcat(p, uri->path, uri->query ? "?" : "",
  -                           uri->query ? uri->query : "",
  -                           uri->fragment ? "#" : "",
  -                           uri->fragment ? uri->fragment : "", NULL);
  -    }
  -
  -    if (err != APR_SUCCESS) {
  -        return ap_proxyerror(r, HTTP_BAD_GATEWAY,
  -                             apr_pstrcat(p, "DNS lookup failure for: ",
  -                                         p_conn->name, NULL));
  -    }
  -
  -    /* Get the server port for the Via headers */
  -    {
  -        server_port = ap_get_server_port(r);
  -        if (ap_is_default_port(server_port, r)) {
  -            strcpy(server_portstr,"");
  -        } else {
  -            apr_snprintf(server_portstr, server_portstr_size, ":%d",
  -                         server_port);
  -        }
  -    }
  -
  -    /* check if ProxyBlock directive on this host */
  -    if (OK != ap_proxy_checkproxyblock(r, conf, uri_addr)) {
  -        return ap_proxyerror(r, HTTP_FORBIDDEN,
  -                             "Connect to remote machine blocked");
  -    }
  -    return OK;
  -}
  -
  -static
  -apr_status_t ap_proxy_http_create_connection(apr_pool_t *p, request_rec *r,
  -                                             proxy_ajp_conn_t *p_conn,
  -                                             conn_rec *c, conn_rec **origin,
  -                                             proxy_conn_rec *backend,
  -                                             proxy_server_conf *conf,
  -                                             const char *proxyname) {
  -    int failed = 0, new_conn = 0;
  -    apr_socket_t *client_socket = NULL;
  -
  -    /* We have determined who to connect to. Now make the connection, supporting
  -     * a KeepAlive connection.
  -     */
  -
  -    /* get all the possible IP addresses for the destname and loop through them
  -     * until we get a successful connection
  -     */
  -
  -    /* if a keepalive socket is already open, check whether it must stay
  -     * open, or whether it should be closed and a new socket created.
  -     */
  -    /* see memory note above */
  -    if (backend->connection) {
  -        client_socket = ap_get_module_config(backend->connection->conn_config, 
&core_module);
  -        if ((backend->connection->id == c->id) &&
  -            (backend->port == p_conn->port) &&
  -            (backend->hostname) &&
  -            (!apr_strnatcasecmp(backend->hostname, p_conn->name))) {
  -            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
  -                         "proxy: keepalive address match (keep original socket)");
  -        } else {
  -            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
  -                         "proxy: keepalive address mismatch / connection has"
  -                         " changed (close old socket (%s/%s, %d/%d))", 
  -                         p_conn->name, backend->hostname, p_conn->port,
  -                         backend->port);
  -            apr_socket_close(client_socket);
  -            backend->connection = NULL;
  -        }
  -    }
  -
  -    /* get a socket - either a keepalive one, or a new one */
  -    new_conn = 1;
  -    if ((backend->connection) && (backend->connection->id == c->id)) {
  -        apr_size_t buffer_len = 1;
  -        char test_buffer[1]; 
  -        apr_status_t socket_status;
  -        apr_interval_time_t current_timeout;
  -
  -        /* use previous keepalive socket */
  -        *origin = backend->connection;
  -        p_conn->sock = client_socket;
  -        new_conn = 0;
  -
  -        /* save timeout */
  -        apr_socket_timeout_get(p_conn->sock, &current_timeout);
  -        /* set no timeout */
  -        apr_socket_timeout_set(p_conn->sock, 0);
  -        socket_status = apr_socket_recv(p_conn->sock, test_buffer, &buffer_len);
  -        /* put back old timeout */
  -        apr_socket_timeout_set(p_conn->sock, current_timeout);
  -        if ( APR_STATUS_IS_EOF(socket_status) ) {
  -            ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
  -                         "proxy: AJP: previous connection is closed");
  -            new_conn = 1;
  -        }
  -    }
  -    if (new_conn) {
  -
  -        /* create a new socket */
  -        backend->connection = NULL;
  -
  -        /*
  -         * At this point we have a list of one or more IP addresses of
  -         * the machine to connect to. If configured, reorder this
  -         * list so that the "best candidate" is first try. "best
  -         * candidate" could mean the least loaded server, the fastest
  -         * responding server, whatever.
  -         *
  -         * For now we do nothing, ie we get DNS round robin.
  -         * XXX FIXME
  -         */
  -        failed = ap_proxy_connect_to_backend(&p_conn->sock, "AJP",
  -                                             p_conn->addr, p_conn->name,
  -                                             conf, r->server, c->pool);
  -
  -        /* handle a permanent error on the connect */
  -        if (failed) {
  -            if (proxyname) {
  -                return DECLINED;
  -            } else {
  -                return HTTP_BAD_GATEWAY;
  -            }
  -        }
  -
  -        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
  -                     "proxy: socket is connected");
  -
  -        /* the socket is now open, create a new backend server connection */
  -        *origin = ap_run_create_connection(c->pool, r->server, p_conn->sock,
  -                                           r->connection->id,
  -                                           r->connection->sbh, c->bucket_alloc);
  -        if (!*origin) {
  -        /* the peer reset the connection already; ap_run_create_connection() 
  -         * closed the socket
  -         */
  -            ap_log_error(APLOG_MARK, APLOG_ERR, 0,
  -                         r->server, "proxy: an error occurred creating a "
  -                         "new connection to %pI (%s)", p_conn->addr,
  -                         p_conn->name);
  -            apr_socket_close(p_conn->sock);
  -            return HTTP_INTERNAL_SERVER_ERROR;
  -        }
  -        backend->connection = *origin;
  -        backend->hostname = apr_pstrdup(c->pool, p_conn->name);
  -        backend->port = p_conn->port;
  -
  -        if (backend->is_ssl) {
  -            if (!ap_proxy_ssl_enable(backend->connection)) {
  -                ap_log_error(APLOG_MARK, APLOG_ERR, 0,
  -                             r->server, "proxy: failed to enable ssl support "
  -                             "for %pI (%s)", p_conn->addr, p_conn->name);
  -                return HTTP_INTERNAL_SERVER_ERROR;
  -            }
  -        }
  -        else {
  -            ap_proxy_ssl_disable(backend->connection);
  -        }
  -
  -        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
  -                     "proxy: connection complete to %pI (%s)",
  -                     p_conn->addr, p_conn->name);
  -
  -        /* set up the connection filters */
  -        ap_run_pre_connection(*origin, p_conn->sock);
  -    }
  -    return OK;
  -}
  -
  -
  -static
   apr_status_t ap_proxy_ajp_request(apr_pool_t *p, request_rec *r,
  -                                   proxy_ajp_conn_t *p_conn, conn_rec *origin, 
  +                                   proxy_conn_rec *conn, 
  +                                   conn_rec *origin, 
                                      proxy_server_conf *conf,
                                      apr_uri_t *uri,
                                      char *url, char *server_portstr)
  @@ -353,11 +114,13 @@
        */
   
       /* send request headers */
  -    status = ajp_send_header(p_conn->sock,r);
  +    status = ajp_send_header(conn->sock, r);
       if (status != APR_SUCCESS) {
  +        conn->close++;
           ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server,
                        "proxy: request failed to %pI (%s)",
  -                     p_conn->addr, p_conn->name);
  +                     conn->worker->cp->addr,
  +                     conn->worker->hostname);
           return status;
       }
   
  @@ -402,32 +165,35 @@
           ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                        "proxy: got %d byte of data", bufsiz);
           if (bufsiz > 0) {
  -            status = ajp_send_data_msg(p_conn->sock, r, msg, bufsiz);
  +            status = ajp_send_data_msg(conn->sock, r, msg, bufsiz);
               if (status != APR_SUCCESS) {
                   ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server,
                                "proxy: request failed to %pI (%s)",
  -                             p_conn->addr, p_conn->name);
  +                             conn->worker->cp->addr,
  +                             conn->worker->hostname);
                   return status;
               }
           }
       }
   
       /* read the response */
  -    status = ajp_read_header(p_conn->sock, r,
  -                             (ajp_msg_t **)&(p_conn->data));
  +    status = ajp_read_header(conn->sock, r,
  +                             (ajp_msg_t **)&(conn->data));
       if (status != APR_SUCCESS) {
           ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server,
                        "proxy: request failed to %pI (%s)",
  -                     p_conn->addr, p_conn->name);
  +                     conn->worker->cp->addr,
  +                     conn->worker->hostname);
           return status;
       }
   
       /* parse the reponse */
  -    result = ajp_parse_type(r, p_conn->data);
  +    result = ajp_parse_type(r, conn->data);
       if (result == CMD_AJP13_SEND_HEADERS) {
           ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                        "proxy: got response from %pI (%s)",
  -                     p_conn->addr, p_conn->name);
  +                     conn->worker->cp->addr,
  +                     conn->worker->hostname);
           return APR_SUCCESS;
       }
   
  @@ -450,7 +216,6 @@
    */
   static
   apr_status_t ap_proxy_ajp_process_response(apr_pool_t * p, request_rec *r,
  -                                            proxy_ajp_conn_t *p_conn,
                                               conn_rec *origin,
                                               proxy_conn_rec *backend,
                                               proxy_server_conf *conf,
  @@ -464,39 +229,43 @@
   
       bb = apr_brigade_create(p, c->bucket_alloc);
       
  -    type = ajp_parse_type(r, p_conn->data);
  +    type = ajp_parse_type(r, backend->data);
       status = APR_SUCCESS;
       while (type != CMD_AJP13_END_RESPONSE) {
           if (type == CMD_AJP13_SEND_HEADERS) {
               /* AJP13_SEND_HEADERS: process them */
  -            status = ajp_parse_header(r, p_conn->data); 
  +            status = ajp_parse_header(r, backend->data); 
               if (status != APR_SUCCESS) {
                   break;
               }
  -        } else if  (type == CMD_AJP13_SEND_BODY_CHUNK) {
  +        } 
  +        else if  (type == CMD_AJP13_SEND_BODY_CHUNK) {
               /* AJP13_SEND_BODY_CHUNK: piece of data */
               apr_uint16_t size;
               char *buff;
   
  -            status = ajp_parse_data(r, p_conn->data, &size, &buff);
  +            status = ajp_parse_data(r, backend->data, &size, &buff);
               e = apr_bucket_transient_create(buff, size, c->bucket_alloc);
               APR_BRIGADE_INSERT_TAIL(bb, e);
  -        } else {
  +        } 
  +        else {
               status = APR_EGENERAL;
               break;
           }
           /* Read the next message */
  -        status = ajp_read_header(p_conn->sock, r,
  -                                 (ajp_msg_t **)&(p_conn->data));
  +        status = ajp_read_header(backend->sock, r,
  +                                 (ajp_msg_t **)&(backend->data));
           if (status != APR_SUCCESS) {
               break;
           }
  -        type = ajp_parse_type(r, p_conn->data);
  +        type = ajp_parse_type(r, backend->data);
       }
       if (status != APR_SUCCESS) {
           ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                         "proxy: error reading headers from remote "
  -                      "server %s:%d", p_conn->name, p_conn->port);
  +                      "server %s:%d",
  +                      backend->worker->cp->addr,
  +                      backend->worker->hostname);
           return ap_proxyerror(r, HTTP_BAD_GATEWAY,
                                "Error reading from remote server");
       }
  @@ -514,28 +283,6 @@
       return OK;
   }
   
  -static
  -apr_status_t ap_proxy_ajp_cleanup(request_rec *r, proxy_ajp_conn_t *p_conn,
  -                                   proxy_conn_rec *backend) {
  -    /* If the connection has been signalled
  -     * to close, close the socket and clean up
  -     */
  -
  -    /* if the connection is < HTTP/1.1, or Connection: close,
  -     * we close the socket, otherwise we leave it open for KeepAlive support
  -     */
  -    if (p_conn->close) {
  -        ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
  -                      "ap_proxy_ajp_cleanup closing");
  -        if (p_conn->sock) {
  -            apr_socket_close(p_conn->sock);
  -            p_conn->sock = NULL;
  -            backend->connection = NULL;
  -        }
  -    }
  -    return OK;
  -}
  -
   /*
    * This handles http:// URLs, and other URLs using a remote proxy over http
    * If proxyhost is NULL, then contact the server directly, otherwise
  @@ -545,15 +292,17 @@
    * we return DECLINED so that we can try another proxy. (Or the direct
    * route.)
    */
  -int ap_proxy_ajp_handler(request_rec *r, proxy_server_conf *conf,
  -                          char *url, const char *proxyname, 
  -                          apr_port_t proxyport)
  +int ap_proxy_ajp_handler(request_rec *r, proxy_worker *worker,
  +                         proxy_server_conf *conf,
  +                         char *url, const char *proxyname, 
  +                         apr_port_t proxyport)
   {
       int status;
       char server_portstr[32];
       conn_rec *origin = NULL;
       proxy_conn_rec *backend = NULL;
       int is_ssl = 0;
  +    const char *scheme = "ajp";
   
       /* Note: Memory pool allocation.
        * A downstream keepalive connection is always connected to the existence
  @@ -571,28 +320,8 @@
       apr_pool_t *p = r->connection->pool;
       conn_rec *c = r->connection;
       apr_uri_t *uri = apr_palloc(r->connection->pool, sizeof(*uri));
  -    proxy_ajp_conn_t *p_conn = apr_pcalloc(r->connection->pool,
  -                                           sizeof(*p_conn));
   
       
  -    /* only use stored info for top-level pages. Sub requests don't share 
  -     * in keepalives
  -     */
  -    if (!r->main) {
  -        backend = (proxy_conn_rec *) ap_get_module_config(c->conn_config,
  -                                                      &proxy_ajp_module);
  -    }
  -    /* create space for state information */
  -    if (!backend) {
  -        backend = apr_pcalloc(c->pool, sizeof(proxy_conn_rec));
  -        backend->connection = NULL;
  -        backend->hostname = NULL;
  -        backend->port = 0;
  -        if (!r->main) {
  -            ap_set_module_config(c->conn_config, &proxy_ajp_module, backend);
  -        }
  -    }
  -
       if (strncasecmp(url, "ajp:", 4) != 0) {
           ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                        "proxy: AJP: declining URL %s", url);
  @@ -601,7 +330,7 @@
       ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                "proxy: AJP: serving URL %s", url);
       
  -    
  +
       /* only use stored info for top-level pages. Sub requests don't share 
        * in keepalives
        */
  @@ -611,59 +340,59 @@
       }
       /* create space for state information */
       if (!backend) {
  -        backend = apr_pcalloc(c->pool, sizeof(proxy_conn_rec));
  -        backend->connection = NULL;
  -        backend->hostname = NULL;
  -        backend->port = 0;
  +        status = ap_proxy_acquire_connection(scheme, &backend, worker, r->server);
  +        if (status != OK) {
  +            if (backend) {
  +                backend->close_on_recycle = 1;
  +                ap_proxy_release_connection(scheme, backend, r->server);
  +            }
  +            return status;
  +        }
           if (!r->main) {
               ap_set_module_config(c->conn_config, &proxy_ajp_module, backend);
           }
       }
   
  -    backend->is_ssl = is_ssl;
  +    backend->is_ssl = 0;
  +    backend->close_on_recycle = 0;
   
       /* Step One: Determine Who To Connect To */
  -    status = ap_proxy_http_determine_connection(p, r, p_conn, c, conf, uri,
  -                                                &url, proxyname, proxyport,
  -                                                server_portstr,
  -                                                sizeof(server_portstr));
  -    if ( status != OK ) {
  -        return status;
  -    }
  +    status = ap_proxy_determine_connection(p, r, conf, worker, backend, c->pool,
  +                                           uri, &url, proxyname, proxyport,
  +                                           server_portstr,
  +                                           sizeof(server_portstr));
  +
  +    if (status != OK)
  +        goto cleanup;
   
       /* Step Two: Make the Connection */
  -    status = ap_proxy_http_create_connection(p, r, p_conn, c, &origin, backend,
  -                                             conf, proxyname);
  -    if ( status != OK ) {
  -        return status;
  +    status = ap_proxy_connect_backend(scheme, backend, worker, r->server);
  +    if (status != OK)
  +        goto cleanup;
  +
  +    /* Step Three: Create conn_rec */
  +    if (!backend->connection) {
  +        status = ap_proxy_connection_create(scheme, backend, c, r->server);
  +        if (status != OK)
  +            goto cleanup;
       }
      
  -    /* Step Three: Send the Request */
  -    status = ap_proxy_ajp_request(p, r, p_conn, origin, conf, uri, url,
  -                                   server_portstr);
  -    if ( status != OK ) {
  -        p_conn->close++;
  -        ap_proxy_ajp_cleanup(r, p_conn, backend);
  -        return status;
  -    }
  +   
  +    /* Step Four: Send the Request */
  +    status = ap_proxy_ajp_request(p, r, backend, origin, conf, uri, url,
  +                                  server_portstr);
  +    if (status != OK)
  +        goto cleanup;
   
  -    /* Step Four: Receive the Response */
  -    status = ap_proxy_ajp_process_response(p, r, p_conn, origin, backend,
  +    /* Step Five: Receive the Response */
  +    status = ap_proxy_ajp_process_response(p, r, origin, backend,
                                              conf, server_portstr);
  -    if ( status != OK ) {
  -        /* clean up even if there is an error */
  -        p_conn->close++;
  -        ap_proxy_ajp_cleanup(r, p_conn, backend);
  -        return status;
  -    }
  -
  -    /* Step Five: Clean Up */
  -    status = ap_proxy_ajp_cleanup(r, p_conn, backend);
  -    if ( status != OK ) {
  -        return status;
  -    }
  -
  -    return OK;
  +cleanup:
  +    /* Clear the module config */
  +    ap_set_module_config(c->conn_config, &proxy_ajp_module, NULL);
  +    /* Do not close the socket */
  +    ap_proxy_release_connection(scheme, backend, r->server);
  +    return status;
   }
   
   static void ap_proxy_http_register_hook(apr_pool_t *p)
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to