From: Graham Leggett Date: Fri, 6 Apr 2001 10:44:08 +0000 (+0000) Subject: Converted send_dir() to ap_proxy_send_dir_filter() in proxy_ftp.c. X-Git-Tag: 2.0.17~109 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5dd4149bc0c66c318ef6f1acaf0a3a3bd99f6a29;p=apache Converted send_dir() to ap_proxy_send_dir_filter() in proxy_ftp.c. Fixed up the header files PR: Obtained from: Submitted by: Reviewed by: git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@88739 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c index e53ccc3541..b95e787467 100644 --- a/modules/proxy/mod_proxy.c +++ b/modules/proxy/mod_proxy.c @@ -58,29 +58,6 @@ #include "mod_proxy.h" -#define CORE_PRIVATE - -#include "http_log.h" -#include "http_vhost.h" -#include "http_request.h" -#include "util_date.h" -#include "mod_core.h" - -/* Some WWW schemes and their default ports; this is basically /etc/services */ -/* This will become global when the protocol abstraction comes */ -static struct proxy_services defports[] = -{ - {"http", DEFAULT_HTTP_PORT}, - {"ftp", DEFAULT_FTP_PORT}, - {"https", DEFAULT_HTTPS_PORT}, - {"gopher", DEFAULT_GOPHER_PORT}, - {"nntp", DEFAULT_NNTP_PORT}, - {"wais", DEFAULT_WAIS_PORT}, - {"snews", DEFAULT_SNEWS_PORT}, - {"prospero", DEFAULT_PROSPERO_PORT}, - {NULL, -1} /* unknown port */ -}; - /* * A Web proxy module. Stages: * @@ -476,14 +453,19 @@ static const char * (proxy_server_conf *) ap_get_module_config(s->module_config, &proxy_module); struct proxy_remote *new; char *p, *q; - char *r, *f; + char *r, *f, *scheme; int port; r = apr_pstrdup(cmd->pool, r1); + scheme = apr_pstrdup(cmd->pool, r1); f = apr_pstrdup(cmd->pool, f1); p = strchr(r, ':'); - if (p == NULL || p[1] != '/' || p[2] != '/' || p[3] == '\0') + if (p == NULL || p[1] != '/' || p[2] != '/' || p[3] == '\0') { return "ProxyRemote: Bad syntax for a remote proxy server"; + } + else { + scheme[p-r] = 0; + } q = strchr(p + 3, ':'); if (q != NULL) { if (sscanf(q + 1, "%u", &port) != 1 || port > 65535) @@ -498,11 +480,7 @@ static const char * ap_str_tolower(p + 3); /* lowercase hostname */ if (port == -1) { - int i; - for (i = 0; defports[i].scheme != NULL; i++) - if (strcasecmp(defports[i].scheme, r) == 0) - break; - port = defports[i].port; + port = ap_default_port_for_scheme(scheme); } new = apr_array_push(conf->proxies); @@ -743,6 +721,10 @@ static void register_hooks(apr_pool_t *p) ap_hook_handler(proxy_handler, NULL, NULL, APR_HOOK_FIRST); /* filename-to-URI translation */ ap_hook_translate_name(proxy_trans, NULL, NULL, APR_HOOK_FIRST); +#ifdef FTP + /* filters */ + ap_register_output_filter("PROXY_SEND_DIR", ap_proxy_send_dir_filter, AP_FTYPE_CONNECTION); +#endif /* fixups */ ap_hook_fixups(proxy_fixup, NULL, NULL, APR_HOOK_FIRST); /* post read_request handling */ diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h index 885b46cb5e..1435a2982d 100644 --- a/modules/proxy/mod_proxy.h +++ b/modules/proxy/mod_proxy.h @@ -65,12 +65,8 @@ /* - Note that the Explain() stuff is not yet complete. Also note numerous FIXMEs and CHECKMEs which should be eliminated. - If TESTING is set, then garbage collection doesn't delete ... probably a good - idea when hacking. - This code is once again experimental! Things to do: @@ -83,12 +79,32 @@ */ -#define TESTING 0 -#undef EXPLAIN +#define CORE_PRIVATE +#include "apr.h" #include "apr_compat.h" #include "apr_lib.h" #include "apr_strings.h" +#include "apr_buckets.h" +#include "apr_md5.h" +#include "apr_pools.h" +#include "apr_strings.h" + +#include "util_filter.h" +#include "util_date.h" +#include "util_uri.h" +#include "httpd.h" +#include "http_config.h" +#include "http_protocol.h" +#include "ap_config.h" +#include "http_log.h" +#include "http_main.h" +#include "http_core.h" +#include "http_connection.h" +#include "http_vhost.h" +#include "http_request.h" +#include "mod_core.h" + #if APR_HAVE_NETDB_H #include @@ -103,10 +119,6 @@ #include #endif -#include "httpd.h" -#include "http_config.h" -#include "http_protocol.h" - extern module AP_MODULE_DECLARE_DATA proxy_module; @@ -116,15 +128,13 @@ enum enctype { enc_path, enc_search, enc_user, enc_fpath, enc_parm }; -#define HDR_APP (0) /* append header, for proxy_add_header() */ -#define HDR_REP (1) /* replace header, for proxy_add_header() */ - #if APR_CHARSET_EBCDIC #define CRLF "\r\n" #else /*APR_CHARSET_EBCDIC*/ #define CRLF "\015\012" #endif /*APR_CHARSET_EBCDIC*/ +#if 0 #define DEFAULT_FTP_DATA_PORT 20 #define DEFAULT_FTP_PORT 21 #define DEFAULT_GOPHER_PORT 70 @@ -135,11 +145,15 @@ enum enctype { #define DEFAULT_PROSPERO_PORT 1525 /* WARNING: conflict w/Oracle */ #define DEFAULT_CACHE_COMPLETION (0.9) +#endif + +#if 0 /* Some WWW schemes and their default ports; this is basically /etc/services */ struct proxy_services { const char *scheme; int port; }; +#endif /* static information about a remote proxy */ struct proxy_remote { @@ -212,10 +226,9 @@ int ap_proxy_connect_handler(request_rec *r, char *url, /* proxy_ftp.c */ -#if FTP int ap_proxy_ftp_canon(request_rec *r, char *url); -int ap_proxy_ftp_handler(request_rec *r, ap_cache_el *c, char *url); -#endif +int ap_proxy_ftp_handler(request_rec *r, char *url); +apr_status_t ap_proxy_send_dir_filter(ap_filter_t *f, apr_bucket_brigade *bb, ap_input_mode_t mode); /* proxy_http.c */ diff --git a/modules/proxy/proxy_connect.c b/modules/proxy/proxy_connect.c index 35f6ae74e3..f3f915245e 100644 --- a/modules/proxy/proxy_connect.c +++ b/modules/proxy/proxy_connect.c @@ -59,13 +59,12 @@ /* CONNECT method for Apache proxy */ #include "mod_proxy.h" -#include "http_log.h" -#include "http_main.h" -#include "apr_strings.h" +#if 0 #ifdef HAVE_BSTRING_H #include /* for IRIX, FD_SET calls bzero() */ #endif +#endif /* * This handles Netscape CONNECT method secure proxy requests. @@ -79,13 +78,6 @@ * If proxyhost and proxyport are set, we send a CONNECT to * the specified proxy.. * - * FIXME: this is bad, because it does its own socket I/O - * instead of using the I/O in buff.c. However, - * the I/O in buff.c blocks on reads, and because - * this function doesn't know how much data will - * be sent either way (or when) it can't use blocking - * I/O. This may be very implementation-specific - * (to Linux). Any suggestions? * FIXME: this doesn't log the number of bytes sent, but * that may be okay, since the data is supposed to * be transparent. In fact, this doesn't log at all diff --git a/modules/proxy/proxy_ftp.c b/modules/proxy/proxy_ftp.c index 5c10cd7e7a..a172ab4981 100644 --- a/modules/proxy/proxy_ftp.c +++ b/modules/proxy/proxy_ftp.c @@ -58,23 +58,10 @@ /* FTP routines for Apache proxy */ -#define CORE_PRIVATE - #include "mod_proxy.h" -#include "apr_strings.h" -#include "apr_buckets.h" -#include "util_filter.h" -#include "ap_config.h" -#include "http_log.h" -#include "http_main.h" -#include "http_core.h" -#include "http_connection.h" -#include "util_date.h" #define AUTODETECT_PWD -int ap_proxy_ftp_canon(request_rec *r, char *url); -int ap_proxy_ftp_handler(request_rec *r, char *url); /* * Decodes a '%' escaped string, and returns the number of characters @@ -252,33 +239,41 @@ static int ftp_getrc_msg(conn_rec *c, char *msgbuf, int msglen) return status; } -/* this piece needs some serious overhauling */ -#if 0 -static long int send_dir(BUFF *f, request_rec *r, ap_cache_el *c, char *cwd) +/* this is a filter that turns a raw ASCII directory listing into pretty HTML */ + +/* ideally, mod_proxy should simply send the raw directory list up the filter + * stack to mod_autoindex, which in theory should turn the raw ascii into + * pretty html along with all the bells and whistles it provides... + * + * all in good time...! :) + */ + +apr_status_t ap_proxy_send_dir_filter(ap_filter_t *f, apr_bucket_brigade *bb, ap_input_mode_t mode) { - char buf[IOBUFSIZE]; - char buf2[IOBUFSIZE]; + conn_rec *c = f->r->connection; + apr_pool_t *p = f->r->pool; + apr_bucket *e; + char buf[MAX_STRING_LEN]; + char buf2[MAX_STRING_LEN]; + char *filename; int searchidx = 0; char *searchptr = NULL; int firstfile = 1; - apr_ssize_t cntr; - unsigned long total_bytes_sent = 0; - register int n, o, w; - conn_rec *con = r->connection; + register int n; char *dir, *path, *reldir, *site; - apr_file_t *cachefp = NULL; - if(c) ap_cache_el_data(c, &cachefp); - + char *cwd = NULL; + + /* Save "scheme://site" prefix without password */ - site = ap_unparse_uri_components(r->pool, &r->parsed_uri, UNP_OMITPASSWORD|UNP_OMITPATHINFO); + site = ap_unparse_uri_components(p, &f->r->parsed_uri, UNP_OMITPASSWORD|UNP_OMITPATHINFO); /* ... and path without query args */ - path = ap_unparse_uri_components(r->pool, &r->parsed_uri, UNP_OMITSITEPART|UNP_OMITQUERY); + path = ap_unparse_uri_components(p, &f->r->parsed_uri, UNP_OMITSITEPART|UNP_OMITQUERY); (void)decodeenc(path); /* Copy path, strip (all except the last) trailing slashes */ - path = dir = apr_pstrcat(r->pool, path, "/", NULL); + path = dir = apr_pstrcat(p, path, "/", NULL); while ((n = strlen(path)) > 1 && path[n-1] == '/' && path[n-2] == '/') path[n-1] = '\0'; @@ -289,7 +284,9 @@ static long int send_dir(BUFF *f, request_rec *r, ap_cache_el *c, char *cwd) "

Directory of " "%s/", site, path, site, path, site); - total_bytes_sent += ap_proxy_bputs2(buf, con->client_socket, c); + + e = apr_bucket_pool_create(buf, n, p); + APR_BRIGADE_INSERT_TAIL(bb, e); while ((dir = strchr(dir+1, '/')) != NULL) { @@ -299,31 +296,32 @@ static long int send_dir(BUFF *f, request_rec *r, ap_cache_el *c, char *cwd) else ++reldir; /* print "path/" component */ - apr_snprintf(buf, sizeof(buf), "%s/", path+1, reldir); - total_bytes_sent += ap_proxy_bputs2(buf, con->client_socket, c); + n = apr_snprintf(buf, sizeof(buf), "%s/", path+1, reldir); + e = apr_bucket_pool_create(buf, n, p); + APR_BRIGADE_INSERT_TAIL(bb, e); *dir = '/'; } /* If the caller has determined the current directory, and it differs */ /* from what the client requested, then show the real name */ if (cwd == NULL || strncmp (cwd, path, strlen(cwd)) == 0) { - apr_snprintf(buf, sizeof(buf), "

\n
");
+	n = apr_snprintf(buf, sizeof(buf), "\n
");
     } else {
-	apr_snprintf(buf, sizeof(buf), "\n(%s)\n
", cwd);
+	n = apr_snprintf(buf, sizeof(buf), "\n(%s)\n
", cwd);
     }
-    total_bytes_sent += ap_proxy_bputs2(buf, con->client_socket, c);
+    e = apr_bucket_pool_create(buf, n, p);
+    APR_BRIGADE_INSERT_TAIL(bb, e);
+
+    e = apr_bucket_flush_create();
+    APR_BRIGADE_INSERT_TAIL(bb, e);
 
-    while (!con->aborted) {
-	n = ap_bgets(buf, sizeof buf, f);
+    while (!c->aborted) {
+	n = ap_getline(buf, sizeof(buf), f->r, 0);
 	if (n == -1) {		/* input error */
-	    if (c != NULL) {
-		ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
-		  "proxy: error reading from cache");
-		  ap_proxy_cache_error(&c);
-	    }
 	    break;
 	}
-	if (n == 0)
+	if (n == 0) {
 	    break;		/* EOF */
+	}
 	if (buf[0] == 'l' && (filename=strstr(buf, " -> ")) != NULL) {
 	    char *link_ptr = filename;
 
@@ -375,38 +373,27 @@ static long int send_dir(BUFF *f, request_rec *r, ap_cache_el  *c, char *cwd)
 	    n = strlen(buf);
 	}
 
-	o = 0;
-	total_bytes_sent += n;
-
-        cntr = n;
-	if (cachefp && apr_file_write(cachefp, buf, &cntr) != APR_SUCCESS) {
-	   ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
-	  "proxy: error writing to cache");
-	   ap_proxy_cache_error(&c);
-	   cachefp = NULL;
-	}
+	e = apr_bucket_pool_create(buf, n, p);
+	APR_BRIGADE_INSERT_TAIL(bb, e);
+	e = apr_bucket_flush_create();
+	APR_BRIGADE_INSERT_TAIL(bb, e);
 
-	while (n && !r->connection->aborted) {
-            cntr = n;
-	    w = apr_send(con->client_socket, &buf[o], &cntr);
-	    if (w <= 0)
-		break;
-	    n -= w;
-	    o += w;
-	}
     }
 
-    total_bytes_sent += ap_proxy_bputs2("

\n", con->client_socket, c); - total_bytes_sent += ap_proxy_bputs2(ap_psignature("", r), con->client_socket, c); - total_bytes_sent += ap_proxy_bputs2("\n", con->client_socket, c); + n = apr_snprintf(buf, sizeof(buf), "

\n%s\n", ap_psignature("", f->r)); + e = apr_bucket_pool_create(buf, n, p); + APR_BRIGADE_INSERT_TAIL(bb, e); + + e = apr_bucket_eos_create(); + APR_BRIGADE_INSERT_TAIL(bb, e); -/* Flushing the actual socket doesn't make much sense, because we don't - * buffer it yet. - ap_flush(con->client); +/* probably not necessary */ +/* e = apr_bucket_flush_create(); + APR_BRIGADE_INSERT_TAIL(bb, e); */ - return total_bytes_sent; + + return APR_SUCCESS; } -#endif /* Common routine for failed authorization (i.e., missing or wrong password) * to an ftp service. This causes most browsers to retry the request @@ -485,6 +472,7 @@ int ap_proxy_ftp_handler(request_rec *r, char *url) if (r->method_number != M_GET) return HTTP_NOT_IMPLEMENTED; + /* We break the URL into host, port, path-search */ connectname = r->parsed_uri.hostname; connectport = (r->parsed_uri.port != 0) @@ -542,6 +530,7 @@ int ap_proxy_ftp_handler(request_rec *r, char *url) "Connect to remote machine blocked"); } +//return HTTP_NOT_IMPLEMENTED; /* * II: Make the Connection @@ -1346,10 +1335,9 @@ int ap_proxy_ftp_handler(request_rec *r, char *url) if (parms[0] == 'd') { /* insert directory filter */ -/* send_dir(data, r, c, cwd); */ + ap_add_output_filter("PROXY_SEND_DIR", NULL, r, r->connection); } - /* send body */ if (!r->header_only) { diff --git a/modules/proxy/proxy_http.c b/modules/proxy/proxy_http.c index 4fdaede991..36bd77d164 100644 --- a/modules/proxy/proxy_http.c +++ b/modules/proxy/proxy_http.c @@ -58,18 +58,7 @@ /* HTTP routines for Apache proxy */ -#define CORE_PRIVATE - #include "mod_proxy.h" -#include "apr_strings.h" -#include "apr_buckets.h" -#include "util_filter.h" -#include "ap_config.h" -#include "http_log.h" -#include "http_main.h" -#include "http_core.h" -#include "http_connection.h" -#include "util_date.h" /* * Canonicalise http-like URLs. diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c index d9d6f7fa5d..2a87f98d6b 100644 --- a/modules/proxy/proxy_util.c +++ b/modules/proxy/proxy_util.c @@ -56,18 +56,9 @@ * University of Illinois, Urbana-Champaign. */ -#define CORE_PRIVATE - /* Utility routines for Apache proxy */ #include "mod_proxy.h" -#include "http_core.h" -#include "http_main.h" -#include "http_log.h" -#include "util_uri.h" -#include "util_date.h" /* get ap_checkmask() decl. */ -#include "apr_md5.h" -#include "apr_pools.h" -#include "apr_strings.h" + static int proxy_match_ipaddr(struct dirconn_entry *This, request_rec *r); static int proxy_match_domainname(struct dirconn_entry *This, request_rec *r);