summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Querna <pquerna@apache.org>2005-12-18 05:42:38 +0000
committerPaul Querna <pquerna@apache.org>2005-12-18 05:42:38 +0000
commitd29585bc588298a72c76caa36d9e8fd2cd8e2909 (patch)
tree04450fef6c14222eab61b40052819d4c79faeacd
parent06e0a0078d02c054ec88a82dc687a94e8c7b8c2b (diff)
downloadhttpd-d29585bc588298a72c76caa36d9e8fd2cd8e2909.tar.gz
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.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/fcgi-proxy-dev@357444 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--modules/proxy/config.m43
-rw-r--r--modules/proxy/mod_proxy_fcgi.c219
2 files changed, 222 insertions, 0 deletions
diff --git a/modules/proxy/config.m4 b/modules/proxy/config.m4
index f131ee6611..7746b09569 100644
--- a/modules/proxy/config.m4
+++ b/modules/proxy/config.m4
@@ -16,6 +16,7 @@ APACHE_MODULE(proxy, Apache proxy module, $proxy_objs, , $proxy_mods_enable)
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 @@ case "$host" in
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 @@ esac
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)
diff --git a/modules/proxy/mod_proxy_fcgi.c b/modules/proxy/mod_proxy_fcgi.c
new file mode 100644
index 0000000000..fbaf60f9c7
--- /dev/null
+++ b/modules/proxy/mod_proxy_fcgi.c
@@ -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 */
+};
+