I was thinking along the lines of the following patch. The mod_proxy_ftp
developer should be able to do a much better job
as I am not a coder. It seems to work alright for anonymous and authenticated
ftp traversal and is a good proof of concept.
I can supply a patch for 2.2.3 if required but I need to upgrade my test proxy
first, plus I need sleep now.
Regards,
Jon
--- /dev/httpd-2.2.0/modules/proxy/mod_proxy_ftp.c.dist 2006-08-22
20:21:33.000000000 +1000
+++ /dev/httpd-2.2.0/modules/proxy/mod_proxy_ftp.c.new 2006-08-23
04:39:19.000000000 +1000
@@ -292,13 +292,15 @@
apr_status_t rv;
register int n;
- char *dir, *path, *reldir, *site, *str, *type;
+ char *dir, *path, *reldir, *site, *str, *type, *location_header;
const char *pwd = apr_table_get(r->notes, "Directory-PWD");
const char *readme = apr_table_get(r->notes, "Directory-README");
+ const char *location = apr_table_get(r->notes, "Redirect-REQ");
proxy_dir_ctx_t *ctx = f->ctx;
+
if (!ctx) {
f->ctx = ctx = apr_pcalloc(p, sizeof(*ctx));
ctx->in = apr_brigade_create(p, c->bucket_alloc);
@@ -398,24 +400,54 @@
APR_BRIGADE_INSERT_TAIL(out, apr_bucket_pool_create(str, strlen(str),
p,
c->bucket_alloc));
- /* print README */
- if (readme) {
+ /* Do we need a location header ( redirect ) ? */
+ if ( location )
+ {
+
+ /* Set a temporary redirect */
+ r->status_line = "302 Found";
+
+ /* Concatenate the domain and url then set the Location header*/
+ location_header = apr_pstrcat(p, site, path, NULL);
+ apr_table_setn(r->headers_out, "Location", ap_escape_uri(p,
location_header));
+
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+ "FTP REDIRECT: %s", ap_escape_uri(p, ap_escape_uri(p,
location_header)));
+
+ /* Add the typical redirect content */
+ str = apr_psprintf(p, "The document has moved
<a.href=\"%s\">here\n</a></pre><pre>\n", ap_escape_uri(p, location_header));
+
+ APR_BRIGADE_INSERT_TAIL(out, apr_bucket_pool_create(str,
+ strlen(str), p,
+ c->bucket_alloc));
+
+ /* No need to return a body although we did get a listing */
+ ctx->state = FOOTER;
+
+ }
+ else {
+ /* print README */
+ if (readme) {
str = apr_psprintf(p, "%s\n</pre>\n\n<hr />\n\n<pre>\n",
ap_escape_html(p, readme));
APR_BRIGADE_INSERT_TAIL(out, apr_bucket_pool_create(str,
strlen(str), p,
c->bucket_alloc));
- }
+ }
+
+ ctx->state = BODY;
+
+ }
/* make sure page intro gets sent out */
APR_BRIGADE_INSERT_TAIL(out, apr_bucket_flush_create(c->bucket_alloc));
if (APR_SUCCESS != (rv = ap_pass_brigade(f->next, out))) {
- return rv;
- }
- apr_brigade_cleanup(out);
+ return rv;
- ctx->state = BODY;
+
+ apr_brigade_cleanup(out);
+ }
}
/* loop through each line of directory */
@@ -1481,6 +1513,9 @@
rc = proxy_ftp_command(apr_pstrcat(p, "CWD ",
ftp_escape_globbingchars(p, path), CRLF, NULL),
r, origin, bb, &ftpmessage);
+
+ apr_table_set(r->notes, "Redirect-REQ", "true");
+
/* possible results: 250, 421, 500, 501, 502, 530, 550 */
/* 250 Requested file action okay, completed. */
/* 421 Service not available, closing control connection. */