You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by pq...@apache.org on 2005/12/18 06:42:44 UTC

svn commit: r357444 - in /httpd/httpd/branches/fcgi-proxy-dev/modules/proxy: config.m4 mod_proxy_fcgi.c

Author: pquerna
Date: Sat Dec 17 21:42:38 2005
New Revision: 357444

URL: http://svn.apache.org/viewcvs?rev=357444&view=rev
Log:
Create a templte for a FastCGI proxy backend.  It does not actually do much yet, but is the base for more development.  I hope to work on this more tomorrow.

Added:
    httpd/httpd/branches/fcgi-proxy-dev/modules/proxy/mod_proxy_fcgi.c   (with props)
Modified:
    httpd/httpd/branches/fcgi-proxy-dev/modules/proxy/config.m4

Modified: httpd/httpd/branches/fcgi-proxy-dev/modules/proxy/config.m4
URL: http://svn.apache.org/viewcvs/httpd/httpd/branches/fcgi-proxy-dev/modules/proxy/config.m4?rev=357444&r1=357443&r2=357444&view=diff
==============================================================================
--- httpd/httpd/branches/fcgi-proxy-dev/modules/proxy/config.m4 (original)
+++ httpd/httpd/branches/fcgi-proxy-dev/modules/proxy/config.m4 Sat Dec 17 21:42:38 2005
@@ -16,6 +16,7 @@
 proxy_connect_objs="mod_proxy_connect.lo"
 proxy_ftp_objs="mod_proxy_ftp.lo"
 proxy_http_objs="mod_proxy_http.lo"
+proxy_fcgi_objs="mod_proxy_fcgi.lo"
 proxy_ajp_objs="mod_proxy_ajp.lo ajp_header.lo ajp_link.lo ajp_msg.lo"
 proxy_balancer_objs="mod_proxy_balancer.lo"
 
@@ -26,6 +27,7 @@
     proxy_connect_objs="$proxy_connect_objs mod_proxy.la"
     proxy_ftp_objs="$proxy_ftp_objs mod_proxy.la"
     proxy_http_objs="$proxy_http_objs mod_proxy.la"
+    proxy_fcgi_objs="$proxy_fcgi_objs mod_proxy.la"
     proxy_ajp_objs="$proxy_ajp_objs mod_proxy.la"
     proxy_balancer_objs="$proxy_balancer_objs mod_proxy.la"
     ;;
@@ -34,6 +36,7 @@
 APACHE_MODULE(proxy_connect, Apache proxy CONNECT module, $proxy_connect_objs, , $proxy_mods_enable)
 APACHE_MODULE(proxy_ftp, Apache proxy FTP module, $proxy_ftp_objs, , $proxy_mods_enable)
 APACHE_MODULE(proxy_http, Apache proxy HTTP module, $proxy_http_objs, , $proxy_mods_enable)
+APACHE_MODULE(proxy_fcgi, Apache proxy FastCGI module, $proxy_fcgi_objs, , $proxy_mods_enable)
 APACHE_MODULE(proxy_ajp, Apache proxy AJP module, $proxy_ajp_objs, , $proxy_mods_enable)
 APACHE_MODULE(proxy_balancer, Apache proxy BALANCER module, $proxy_balancer_objs, , $proxy_mods_enable)
 

Added: httpd/httpd/branches/fcgi-proxy-dev/modules/proxy/mod_proxy_fcgi.c
URL: http://svn.apache.org/viewcvs/httpd/httpd/branches/fcgi-proxy-dev/modules/proxy/mod_proxy_fcgi.c?rev=357444&view=auto
==============================================================================
--- httpd/httpd/branches/fcgi-proxy-dev/modules/proxy/mod_proxy_fcgi.c (added)
+++ httpd/httpd/branches/fcgi-proxy-dev/modules/proxy/mod_proxy_fcgi.c Sat Dec 17 21:42:38 2005
@@ -0,0 +1,219 @@
+/* Copyright 2005 The Apache Software Foundation or its licensors, as
+ * applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mod_proxy.h"
+
+module AP_MODULE_DECLARE_DATA proxy_fcgi_module;
+
+/*
+ * Canonicalise http-like URLs.
+ * scheme is the scheme for the URL
+ * url is the URL starting with the first '/'
+ * def_port is the default port for this scheme.
+ */
+static int proxy_fcgi_canon(request_rec *r, char *url)
+{
+    char *host, *path, *search, sport[7];
+    const char *err;
+    apr_port_t port = 8000;
+
+    if (strncasecmp(url, "fcgi:", 5) == 0) {
+        url += 5;
+    }
+    else {
+        return DECLINED;
+    }
+    
+    if (strncmp(url, "tcp://", 6) == 0) {
+        url += 6;
+    }
+    else if (strncmp(url, "local:", 6) == 0) {
+        url += 6;
+    }
+    else {
+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
+             "proxy: FCGI: mallformed destination: %s", url);
+        return HTTP_INTERNAL_SERVER_ERROR;
+    }
+
+
+    /*
+     * do syntactic check.
+     * We break the URL into host, port, path, search
+     */
+    err = ap_proxy_canon_netloc(r->pool, &url, NULL, NULL, &host, &port);
+    if (err) {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+                      "error parsing URL %s: %s",
+                      url, err);
+        return HTTP_BAD_REQUEST;
+    }
+
+    /*
+     * now parse path/search args, according to rfc1738
+     *
+     * N.B. if this isn't a true proxy request, then the URL _path_
+     * has already been decoded.  True proxy requests have
+     * r->uri == r->unparsed_uri, and no others have that property.
+     */
+    if (r->uri == r->unparsed_uri) {
+        search = strchr(url, '?');
+        if (search != NULL)
+            *(search++) = '\0';
+    }
+    else {
+        search = r->args;
+    }
+
+    /* process path */
+    path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0,
+                             r->proxyreq);
+    if (path == NULL) {
+        return HTTP_BAD_REQUEST;
+    }
+
+    apr_snprintf(sport, sizeof(sport), ":%d", port);
+
+    if (ap_strchr_c(host, ':')) {
+        /* if literal IPv6 address */
+        host = apr_pstrcat(r->pool, "[", host, "]", NULL);
+    }
+    r->filename = apr_pstrcat(r->pool, "proxy:ajp://", host, sport,
+                              "/", path, (search) ? "?" : "",
+                              (search) ? search : "", NULL);
+    return OK;
+}
+
+/*
+ * process the request and write the response.
+ */
+static int fcgi_do_request(apr_pool_t *p, request_rec *r,
+                            proxy_conn_rec *conn,
+                            conn_rec *origin,
+                            proxy_dir_conf *conf,
+                            apr_uri_t *uri,
+                            char *url, char *server_portstr)
+{
+    /* TODO: Talk to a FastCGI Backend */
+    return HTTP_SERVICE_UNAVAILABLE;
+}
+
+/*
+ * This handles fcgi:(type):(dest) URLs
+ */
+static int proxy_fcgi_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;
+    const char *scheme;
+    proxy_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
+                                                 &proxy_module);
+
+    apr_pool_t *p = r->pool;
+
+    apr_uri_t *uri = apr_palloc(r->pool, sizeof(*uri));
+
+
+    if (strncasecmp(url, "fcgi:", 5) == 0) {
+        url += 5;
+    }
+    else {
+        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+                     "proxy: FCGI: declining URL %s", url);
+        return DECLINED;
+    }
+    
+    if (strncmp(url, "tcp://", 6) == 0) {
+        scheme = "FCGI_TCP";
+    }
+    else if (strncmpp(url, "local:", 6) == 0) {
+        scheme = "FCGI_LOCAL";
+    }
+    else {
+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
+             "proxy: FCGI: mallformed destination: %s", url);
+        return HTTP_INTERNAL_SERVER_ERROR;
+    }
+
+    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+                 "proxy: FCGI: serving URL %s via %s", url, scheme);
+
+    /* create space for state information */
+    if (!backend) {
+        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;
+        }
+    }
+
+    backend->is_ssl = 0;
+    backend->close_on_recycle = 0;
+
+    /* Step One: Determine Who To Connect To */
+    status = ap_proxy_determine_connection(p, r, conf, worker, backend,
+                                           uri, &url, proxyname, proxyport,
+                                           server_portstr,
+                                           sizeof(server_portstr));
+
+    if (status != OK) {
+        goto cleanup;
+    }
+
+    /* Step Two: Make the Connection */
+    if (ap_proxy_connect_backend(scheme, backend, worker, r->server)) {
+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
+                     "proxy: FCGI: failed to make connection to backend: %s",
+                     backend->hostname);
+        status = HTTP_SERVICE_UNAVAILABLE;
+        goto cleanup;
+    }
+
+    /* Step Three: Process the Request */
+    status = fcgi_do_request(p, r, backend, origin, dconf, uri, url,
+                             server_portstr);
+
+cleanup:
+    /* Do not close the socket */
+    ap_proxy_release_connection(scheme, backend, r->server);
+    return status;
+}
+
+static void register_hooks(apr_pool_t *p)
+{
+    proxy_hook_scheme_handler(proxy_fcgi_handler, NULL, NULL, APR_HOOK_FIRST);
+    proxy_hook_canon_handler(proxy_fcgi_canon, NULL, NULL, APR_HOOK_FIRST);
+}
+
+module AP_MODULE_DECLARE_DATA proxy_fcgi_module = {
+    STANDARD20_MODULE_STUFF,
+    NULL,                       /* create per-directory config structure */
+    NULL,                       /* merge per-directory config structures */
+    NULL,                       /* create per-server config structure */
+    NULL,                       /* merge per-server config structures */
+    NULL,                       /* command apr_table_t */
+    register_hooks              /* register hooks */
+};
+

Propchange: httpd/httpd/branches/fcgi-proxy-dev/modules/proxy/mod_proxy_fcgi.c
------------------------------------------------------------------------------
    svn:eol-style = native