You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by mi...@apache.org on 2001/04/09 23:49:18 UTC
cvs commit: httpd-proxy/module-2.0 mod_proxy.h proxy_ftp.c
minfrin 01/04/09 14:49:18
Modified: . CHANGES
module-2.0 mod_proxy.h proxy_ftp.c
Log:
*) PASV FTP works now.
*) Reworked the line-at-a-time read from the control connection to
workaround a stray empty bucket returned by the HTTP_IN filter.
Revision Changes Path
1.20 +7 -0 httpd-proxy/CHANGES
Index: CHANGES
===================================================================
RCS file: /home/cvs/httpd-proxy/CHANGES,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- CHANGES 2001/04/08 22:18:29 1.19
+++ CHANGES 2001/04/09 21:49:17 1.20
@@ -1,6 +1,13 @@
mod_proxy changes for 2.0.15 current
+ *) PASV FTP works now.
+ [Graham Leggett <mi...@sharp.fm>]
+
+ *) Reworked the line-at-a-time read from the control connection to
+ workaround a stray empty bucket returned by the HTTP_IN filter.
+ [Graham Leggett <mi...@sharp.fm>]
+
*) Stopped the CORE filter from sending off an HTTP response when a
CONNECT tunnel was closed.
[Graham Leggett <mi...@sharp.fm>]
1.40 +2 -0 httpd-proxy/module-2.0/mod_proxy.h
Index: mod_proxy.h
===================================================================
RCS file: /home/cvs/httpd-proxy/module-2.0/mod_proxy.h,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -r1.39 -r1.40
--- mod_proxy.h 2001/04/08 22:26:45 1.39
+++ mod_proxy.h 2001/04/09 21:49:17 1.40
@@ -210,6 +210,8 @@
int ap_proxy_ftp_canon(request_rec *r, char *url);
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);
+apr_status_t ap_proxy_string_read(conn_rec *c, apr_bucket_brigade *bb, char *buff, size_t bufflen);
+
/* proxy_http.c */
1.38 +269 -221 httpd-proxy/module-2.0/proxy_ftp.c
Index: proxy_ftp.c
===================================================================
RCS file: /home/cvs/httpd-proxy/module-2.0/proxy_ftp.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -r1.37 -r1.38
--- proxy_ftp.c 2001/04/08 22:18:31 1.37
+++ proxy_ftp.c 2001/04/09 21:49:17 1.38
@@ -183,9 +183,61 @@
return OK;
}
+apr_status_t ap_proxy_string_read(conn_rec *c, apr_bucket_brigade *bb, char *buff, size_t bufflen);
+/* converts a series of buckets into a string */
+apr_status_t ap_proxy_string_read(conn_rec *c, apr_bucket_brigade *bb, char *buff, size_t bufflen)
+{
+ apr_bucket *e;
+ apr_status_t rv;
+ char *pos = buff;
+ char *response;
+ int found = 0;
+ size_t len;
+
+ /* start with an empty string */
+ buff[0] = 0;
+
+ /* get line-at-a-time */
+ c->remain = 0;
+ /* loop through each brigade */
+ while (!found) {
+ /* get brigade from network */
+ if (APR_SUCCESS != (rv = ap_get_brigade(c->input_filters, bb, AP_MODE_BLOCKING))) {
+ return rv;
+ }
+
+ /* loop through each bucket */
+ while (!found && !APR_BRIGADE_EMPTY(bb)) {
+ e = APR_BRIGADE_FIRST(bb);
+ if (APR_SUCCESS != apr_bucket_read(e, (const char **)&response, &len, APR_BLOCK_READ)) {
+ return rv;
+ }
+ /* is string LF terminated? */
+ if (memchr(response, APR_ASCII_LF, len)) {
+ found = 1;
+ }
+ /* concat strings until buff is full - then throw the data away */
+ if (len > ((bufflen-1)-(pos-buff))) {
+ len = (bufflen-1)-(pos-buff);
+ }
+ if (len > 0) {
+ pos = apr_cpystrn(pos, response, len);
+ }
+ APR_BUCKET_REMOVE(e);
+ apr_bucket_destroy(e);
+ }
+ }
+
+ return APR_SUCCESS;
+
+}
+
+/* we chop lines longer than 80 characters */
+#define MAX_LINE_LEN 80
+
/*
* Reads response lines, returns both the ftp status code and
* remembers the response message in the supplied buffer
@@ -193,27 +245,17 @@
static int ftp_getrc_msg(conn_rec *c, apr_bucket_brigade *bb, char *msgbuf, int msglen)
{
int len = 0, status;
- char *response;
+ char response[MAX_LINE_LEN];
char buff[5];
char *mb = msgbuf,
*me = &msgbuf[msglen];
- apr_bucket *e;
-
+ apr_status_t rv;
- /* Tell http_filter to grab the data one line at a time. */
- c->remain = 0;
- ap_get_brigade(c->input_filters, bb, AP_MODE_BLOCKING);
- e = APR_BRIGADE_FIRST(bb);
- apr_bucket_read(e, (const char **)&response, &len, APR_BLOCK_READ);
- if (len == -1) {
+ if (APR_SUCCESS != (rv = ap_proxy_string_read(c, bb, response, sizeof(response)))) {
return -1;
- }
- if (len == 0) {
- msgbuf[0] = 0;
- return 0;
}
- if (len < 5 || !apr_isdigit(response[0]) || !apr_isdigit(response[1]) ||
+ if (!apr_isdigit(response[0]) || !apr_isdigit(response[1]) ||
!apr_isdigit(response[2]) || (response[3] != ' ' && response[3] != '-'))
status = 0;
else
@@ -221,26 +263,34 @@
mb = apr_cpystrn(mb, response+4, me - mb);
-/* FIXME: If the line was too long, read till LF */
+ ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, c->base_server,
+ "proxy: FTP: line [%s]", response);
if (response[3] == '-') {
memcpy(buff, response, 3);
buff[3] = ' ';
do {
- ap_get_brigade(c->input_filters, bb, AP_MODE_BLOCKING);
- apr_bucket_read(e, (const char **)&response, &len, APR_BLOCK_READ);
- if (len == -1)
+
+ if (APR_SUCCESS != (rv = ap_proxy_string_read(c, bb, response, sizeof(response)))) {
+ return -1;
+ }
+ len = strlen(response);
+ if (len == 0) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, rv, c->base_server,
+ "proxy: FTP: apr_bucket_read() returned zero data [%s]", response);
return -1;
+ }
+ else if ((len < 4) && (' ' != response[0])) {
+ return -1;
+ }
-/* FIXME: If the line was too long, read till LF */
+ ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, c->base_server,
+ "proxy: FTP: line [%s]", response);
mb = apr_cpystrn(mb, response + (' ' == response[0] ? 1 : 4), me - mb);
} while (memcmp(response, buff, 4) != 0);
}
- APR_BUCKET_REMOVE(e);
- apr_bucket_destroy(e);
-
return status;
}
@@ -428,6 +478,7 @@
return HTTP_UNAUTHORIZED;
}
+
/*
* Handles direct access of ftp:// URLs
* Original (Non-PASV) version from
@@ -440,6 +491,7 @@
apr_pool_t *p = r->pool;
apr_socket_t *sock, *local_sock, *remote_sock;
apr_sockaddr_t *connect_addr;
+ apr_status_t rv;
conn_rec *origin, *remote;
int err;
apr_bucket *e;
@@ -667,7 +719,7 @@
/* 421 Service not available, closing control connection. */
i = ftp_getrc_msg(origin, cbb, buffer, sizeof(buffer));
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
- "FTP: initial connect returned status %d", i);
+ "proxy: FTP: initial connect returned status %d", i);
if (i == -1) {
apr_socket_close(sock);
return ap_proxyerror(r, HTTP_BAD_GATEWAY, "Error reading from remote server");
@@ -684,8 +736,9 @@
* after the time of the response.
* Retry-After = "Retry-After" ":" ( HTTP-date | delta-seconds )
*/
- ap_set_header("Retry-After", apr_psprintf(p, "%u", 60*wait_mins);
- return ap_proxyerror(r, HTTP_SERVICE_UNAVAILABLE, resp);
+ ap_table_add(r->headers_out, "Retry-After", apr_psprintf(p, "%u", 60*wait_mins);
+ apr_socket_close(sock);
+ return ap_proxyerror(r, HTTP_SERVICE_UNAVAILABLE, buffer);
}
#endif
if (i != 220) {
@@ -694,18 +747,16 @@
}
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
- "FTP: connected.");
+ "proxy: FTP: connected.");
buf = apr_pstrcat(p, "USER ", user, CRLF, NULL);
- bb = apr_brigade_create(p);
e = apr_bucket_pool_create(buf, strlen(buf), p);
APR_BRIGADE_INSERT_TAIL(bb, e);
e = apr_bucket_flush_create();
APR_BRIGADE_INSERT_TAIL(bb, e);
ap_pass_brigade(origin->output_filters, bb);
- apr_brigade_destroy(bb);
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
- "FTP: USER %s", user);
+ "proxy: FTP: USER %s", user);
/* possible results; 230, 331, 332, 421, 500, 501, 530 */
/* states: 1 - error, 2 - success; 3 - send password, 4,5 fail */
@@ -719,7 +770,7 @@
/* 530 Not logged in. */
i = ftp_getrc_msg(origin, cbb, buffer, sizeof(buffer));
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
- "FTP: returned status %d", i);
+ "proxy: FTP: returned status %d", i);
if (i == -1) {
apr_socket_close(sock);
return ap_proxyerror(r, HTTP_BAD_GATEWAY, "Error reading from remote server");
@@ -732,25 +783,20 @@
apr_socket_close(sock);
return ap_proxyerror(r, HTTP_BAD_GATEWAY, buffer);
}
-/* XXX temporary end here while testing */
-apr_socket_close(sock);
-return HTTP_NOT_IMPLEMENTED;
if (i == 331) { /* send password */
if (password == NULL) {
-/* FIXME: Insert clean disconnect */
+ apr_socket_close(sock);
return ftp_unauthorized (r, 0);
}
buf = apr_pstrcat(p, "PASS ", password, CRLF, NULL);
- bb = apr_brigade_create(p);
e = apr_bucket_pool_create(buf, strlen(buf), p);
APR_BRIGADE_INSERT_TAIL(bb, e);
e = apr_bucket_flush_create();
APR_BRIGADE_INSERT_TAIL(bb, e);
ap_pass_brigade(origin->output_filters, bb);
- apr_brigade_destroy(bb);
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
- "FTP: PASS %s", password);
+ "proxy: FTP: PASS %s", password);
/* possible results 202, 230, 332, 421, 500, 501, 503, 530 */
/* 230 User logged in, proceed. */
@@ -762,22 +808,25 @@
/* 530 Not logged in. */
i = ftp_getrc_msg(origin, cbb, buffer, sizeof(buffer));
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "FTP: returned status %d", i);
+ "proxy: FTP: returned status %d [%s]", i, buffer);
if (i == -1) {
+ apr_socket_close(sock);
return ap_proxyerror(r, HTTP_BAD_GATEWAY,
"Error reading from remote server");
}
if (i == 332) {
+ apr_socket_close(sock);
return ap_proxyerror(r, HTTP_UNAUTHORIZED,
apr_pstrcat(p, "Need account for login: ", buffer, NULL));
}
/* @@@ questionable -- we might as well return a 403 Forbidden here */
if (i == 530) {
-/* FIXME: Insert clean disconnect */
+ apr_socket_close(sock);
return ftp_unauthorized (r, 1); /* log it: passwd guessing attempt? */
}
if (i != 230 && i != 202) {
- return HTTP_BAD_GATEWAY;
+ apr_socket_close(sock);
+ return ap_proxyerror(r, HTTP_BAD_GATEWAY, buffer);
}
}
@@ -793,15 +842,13 @@
len = decodeenc(path);
buf = apr_pstrcat(p, "CWD ", path, CRLF, NULL);
- bb = apr_brigade_create(p);
e = apr_bucket_pool_create(buf, strlen(buf), p);
APR_BRIGADE_INSERT_TAIL(bb, e);
e = apr_bucket_flush_create();
APR_BRIGADE_INSERT_TAIL(bb, e);
ap_pass_brigade(origin->output_filters, bb);
- apr_brigade_destroy(bb);
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "FTP: CWD %s", path);
+ ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
+ "proxy: FTP: CWD %s", path);
*strp = '/';
/* responses: 250, 421, 500, 501, 502, 530, 550 */
/* 250 Requested file action okay, completed. */
@@ -813,65 +860,64 @@
/* 550 Requested action not taken. */
i = ftp_getrc_msg(origin, cbb, buffer, sizeof(buffer));
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "FTP: returned status %d", i);
+ "proxy: FTP: returned status %d", i);
if (i == -1) {
+ apr_socket_close(sock);
return ap_proxyerror(r, HTTP_BAD_GATEWAY,
"Error reading from remote server");
}
if (i == 550) {
+ apr_socket_close(sock);
return ap_proxyerror(r, HTTP_NOT_FOUND, buffer);
}
if (i != 250) {
+ apr_socket_close(sock);
return ap_proxyerror(r, HTTP_BAD_GATEWAY, buffer);
}
path = strp + 1;
}
- if (parms != NULL && strncmp(parms, "type=", 5) == 0) {
- parms += 5;
- if ((parms[0] != 'd' && parms[0] != 'a' && parms[0] != 'i') ||
- parms[1] != '\0')
- parms = "";
+ if (parms != NULL && strncasecmp(parms, "type=a", 6) == 0) {
+ parms = "A";
}
- else
- parms = "";
+ else {
+ parms = "I";
+ }
/* changed to make binary transfers the default */
-
- if (parms[0] != 'a') {
- /* set type to image */
- buf = apr_pstrcat(p, "TYPE I", CRLF, NULL);
- bb = apr_brigade_create(p);
- e = apr_bucket_pool_create(buf, strlen(buf), p);
- APR_BRIGADE_INSERT_TAIL(bb, e);
- e = apr_bucket_flush_create();
- APR_BRIGADE_INSERT_TAIL(bb, e);
- ap_pass_brigade(origin->output_filters, bb);
- apr_brigade_destroy(bb);
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "FTP: TYPE I");
- /* responses: 200, 421, 500, 501, 504, 530 */
- /* 200 Command okay. */
- /* 421 Service not available, closing control connection. */
- /* 500 Syntax error, command unrecognized. */
- /* 501 Syntax error in parameters or arguments. */
- /* 504 Command not implemented for that parameter. */
- /* 530 Not logged in. */
- i = ftp_getrc_msg(origin, cbb, buffer, sizeof(buffer));
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "FTP: returned status %d", i);
- if (i == -1) {
- return ap_proxyerror(r, HTTP_BAD_GATEWAY,
- "Error reading from remote server");
- }
- if (i != 200 && i != 504) {
- return ap_proxyerror(r, HTTP_BAD_GATEWAY, buffer);
- }
- /* Allow not implemented */
- if (i == 504)
- parms[0] = '\0';
+ /* set type to binary */
+ buf = apr_pstrcat(p, "TYPE ", parms, CRLF, NULL);
+ e = apr_bucket_pool_create(buf, strlen(buf), p);
+ APR_BRIGADE_INSERT_TAIL(bb, e);
+ e = apr_bucket_flush_create();
+ APR_BRIGADE_INSERT_TAIL(bb, e);
+ ap_pass_brigade(origin->output_filters, bb);
+ ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
+ "proxy: FTP: TYPE I");
+ /* responses: 200, 421, 500, 501, 504, 530 */
+ /* 200 Command okay. */
+ /* 421 Service not available, closing control connection. */
+ /* 500 Syntax error, command unrecognized. */
+ /* 501 Syntax error in parameters or arguments. */
+ /* 504 Command not implemented for that parameter. */
+ /* 530 Not logged in. */
+ i = ftp_getrc_msg(origin, cbb, buffer, sizeof(buffer));
+ ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
+ "proxy: FTP: returned status %d", i);
+ if (i == -1) {
+ apr_socket_close(sock);
+ return ap_proxyerror(r, HTTP_BAD_GATEWAY,
+ "Error reading from remote server");
}
+ if (i != 200 && i != 504) {
+ apr_socket_close(sock);
+ return ap_proxyerror(r, HTTP_BAD_GATEWAY, buffer);
+ }
+ /* Allow not implemented */
+ if (i == 504) {
+ parms[0] = '\0';
+ }
/*
@@ -880,32 +926,17 @@
*
* Try PASV, if that fails try normally.
*/
+/*goto bypass;*/
/* try to set up PASV data connection first */
- if ((apr_socket_create(&remote_sock, APR_INET, SOCK_STREAM, r->pool)) != APR_SUCCESS) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "proxy: error creating PASV socket");
- return HTTP_INTERNAL_SERVER_ERROR;
- }
-
-#if !defined (TPF) && !defined(BEOS)
- if (conf->recv_buffer_size > 0 && apr_setsocketopt(remote_sock, APR_SO_RCVBUF,
- conf->recv_buffer_size)) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "setsockopt(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default");
- }
-#endif
-
- bb = apr_brigade_create(p);
buf = apr_pstrcat(p, "PASV", CRLF, NULL);
e = apr_bucket_pool_create(buf, strlen(buf), p);
APR_BRIGADE_INSERT_TAIL(bb, e);
e = apr_bucket_flush_create();
APR_BRIGADE_INSERT_TAIL(bb, e);
ap_pass_brigade(origin->output_filters, bb);
- apr_brigade_destroy(bb);
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "FTP: PASV command issued");
+ "proxy: FTP: PASV");
/* possible results: 227, 421, 500, 501, 502, 530 */
/* 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2). */
/* 421 Service not available, closing control connection. */
@@ -913,56 +944,69 @@
/* 501 Syntax error in parameters or arguments. */
/* 502 Command not implemented. */
/* 530 Not logged in. */
- bb = apr_brigade_create(p);
- origin->remain = 0;
- ap_get_brigade(origin->input_filters, bb, AP_MODE_BLOCKING);
- e = APR_BRIGADE_FIRST(bb);
- apr_bucket_read(e, (const char **)&buf, &len, APR_BLOCK_READ);
- if (len < 5) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, r,
- "PASV: control connection is toast");
- apr_socket_close(remote_sock);
- return HTTP_BAD_GATEWAY;
+ i = ftp_getrc_msg(origin, cbb, buffer, sizeof(buffer));
+ ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
+ "proxy: FTP: returned status %d", i);
+ if (i == -1) {
+ apr_socket_close(sock);
+ return ap_proxyerror(r, HTTP_BAD_GATEWAY,
+ "Error reading from remote server");
}
- else {
+ if (i != 227 && i != 502) {
+ apr_socket_close(sock);
+ return ap_proxyerror(r, HTTP_BAD_GATEWAY, buffer);
+ }
+ else if (i == 227) {
unsigned int presult, h0, h1, h2, h3, p0, p1;
char *pstr;
- pasv = apr_pstrdup(p, buf);
- pasv[len - 1] = '\0';
- pstr = strtok(pasv, " "); /* separate result code */
+ pstr = apr_pstrdup(p, buffer);
+ pstr = strtok(pstr, " "); /* separate result code */
if (pstr != NULL) {
- presult = atoi(pstr);
- if (*(pstr + strlen(pstr) + 1) == '=')
+ if (*(pstr + strlen(pstr) + 1) == '=') {
pstr += strlen(pstr) + 2;
- else
- {
+ }
+ else {
pstr = strtok(NULL, "("); /* separate address & port params */
if (pstr != NULL)
pstr = strtok(NULL, ")");
}
}
- else
- presult = atoi(pasv);
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "FTP: PASV returned status %d", presult);
/* FIXME: Only supports IPV4 */
- if (presult == 227 && pstr != NULL && (sscanf(pstr,
+ if (pstr != NULL && (sscanf(pstr,
"%d,%d,%d,%d,%d,%d", &h3, &h2, &h1, &h0, &p1, &p0) == 6)) {
apr_sockaddr_t *pasv_addr;
int pasvport = (p1 << 8) + p0;
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "FTP: PASV contacting host %d.%d.%d.%d:%d",
+ ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
+ "proxy: FTP: PASV contacting host %d.%d.%d.%d:%d",
h3, h2, h1, h0, pasvport);
+ if ((rv = apr_socket_create(&remote_sock, APR_INET, SOCK_STREAM, r->pool)) != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
+ "proxy: error creating PASV socket");
+ apr_socket_close(sock);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+#if !defined (TPF) && !defined(BEOS)
+ if (conf->recv_buffer_size > 0 && (rv = apr_setsocketopt(remote_sock, APR_SO_RCVBUF,
+ conf->recv_buffer_size))) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
+ "setsockopt(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default");
+ }
+#endif
+
/* make the connection */
- apr_sockaddr_info_get(&pasv_addr, apr_psprintf(p, "%d.%d.%d.%d", h3, h2, h1, h0), APR_UNSPEC, pasvport, 0, p);
- err = apr_connect(sock, pasv_addr);
- if (err != APR_SUCCESS) {
+ apr_sockaddr_info_get(&pasv_addr, apr_psprintf(p, "%d.%d.%d.%d", h3, h2, h1, h0), APR_INET, pasvport, 0, p);
+ rv = apr_connect(remote_sock, pasv_addr);
+ if (rv != APR_SUCCESS) {
+ apr_socket_close(sock);
+ apr_socket_close(remote_sock);
+ ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,
+ "proxy: FTP: PASV error creating socket");
return ap_proxyerror(r, HTTP_BAD_GATEWAY, apr_psprintf(r->pool,
"PASV attempt to connect to %pI failed - firewall/NAT?", pasv_addr));
}
@@ -974,8 +1018,7 @@
/* and try the regular way */
apr_socket_close(remote_sock);
}
- APR_BUCKET_REMOVE(e);
- apr_bucket_destroy(e);
+bypass:
/* set up data connection */
if (!pasvmode) {
@@ -985,7 +1028,8 @@
if ((apr_socket_create(&local_sock, APR_INET, SOCK_STREAM, r->pool)) != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "proxy: error creating socket");
+ "proxy: FTP: error creating local socket");
+ apr_socket_close(sock);
return HTTP_INTERNAL_SERVER_ERROR;
}
apr_socket_addr_get(&local_addr, APR_LOCAL, sock);
@@ -995,8 +1039,9 @@
if (apr_setsocketopt(local_sock, APR_SO_REUSEADDR, one) != APR_SUCCESS) {
#ifndef _OSD_POSIX /* BS2000 has this option "always on" */
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "proxy: error setting reuseaddr option");
+ "proxy: FTP: error setting reuseaddr option");
apr_socket_close(local_sock);
+ apr_socket_close(sock);
return HTTP_INTERNAL_SERVER_ERROR;
#endif /*_OSD_POSIX*/
}
@@ -1004,7 +1049,8 @@
if (apr_sockaddr_info_get(&local_addr, local_ip, APR_INET,
local_port, 0, r->pool) != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "proxy: error creating local socket address");
+ "proxy: FTP: error creating local socket address");
+ apr_socket_close(sock);
return HTTP_INTERNAL_SERVER_ERROR;
}
@@ -1013,8 +1059,9 @@
apr_snprintf(buff, sizeof(buff), "%s:%d", local_ip, local_port);
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "proxy: error binding to ftp data socket %s", buff);
+ "proxy: FTP: error binding to ftp data socket %s", buff);
apr_socket_close(remote_sock);
+ apr_socket_close(sock);
return HTTP_INTERNAL_SERVER_ERROR;
}
@@ -1039,34 +1086,30 @@
parms = "d";
}
else {
- bb = apr_brigade_create(p);
buf = apr_pstrcat(p, "SIZE ", path, CRLF, NULL);
e = apr_bucket_pool_create(buf, strlen(buf), p);
APR_BRIGADE_INSERT_TAIL(bb, e);
e = apr_bucket_flush_create();
APR_BRIGADE_INSERT_TAIL(bb, e);
ap_pass_brigade(origin->output_filters, bb);
- apr_brigade_destroy(bb);
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "FTP: SIZE %s", path);
+ ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
+ "proxy: FTP: SIZE %s", path);
i = ftp_getrc_msg(origin, cbb, buffer, sizeof buffer);
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "FTP: returned status %d with response %s", i, buffer);
+ "proxy: FTP: returned status %d with response %s", i, buffer);
if (i != 500) { /* Size command not recognized */
if (i == 550) { /* Not a regular file */
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "FTP: SIZE shows this is a directory");
+ ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
+ "proxy: FTP: SIZE shows this is a directory");
parms = "d";
- bb = apr_brigade_create(p);
buf = apr_pstrcat(p, "CWD ", path, CRLF, NULL);
e = apr_bucket_pool_create(buf, strlen(buf), p);
APR_BRIGADE_INSERT_TAIL(bb, e);
e = apr_bucket_flush_create();
APR_BRIGADE_INSERT_TAIL(bb, e);
ap_pass_brigade(origin->output_filters, bb);
- apr_brigade_destroy(bb);
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "FTP: CWD %s", path);
+ ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
+ "proxy: FTP: CWD %s", path);
i = ftp_getrc_msg(origin, cbb, buffer, sizeof(buffer));
/* possible results: 250, 421, 500, 501, 502, 530, 550 */
/* 250 Requested file action okay, completed. */
@@ -1077,15 +1120,18 @@
/* 530 Not logged in. */
/* 550 Requested action not taken. */
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "FTP: returned status %d", i);
+ "proxy: FTP: returned status %d", i);
if (i == -1) {
+ apr_socket_close(sock);
return ap_proxyerror(r, HTTP_BAD_GATEWAY,
"Error reading from remote server");
}
if (i == 550) {
+ apr_socket_close(sock);
return ap_proxyerror(r, HTTP_NOT_FOUND, buffer);
}
if (i != 250) {
+ apr_socket_close(sock);
return ap_proxyerror(r, HTTP_BAD_GATEWAY, buffer);
}
path = "";
@@ -1100,17 +1146,17 @@
}
}
+
+
#ifdef AUTODETECT_PWD
- bb = apr_brigade_create(p);
buf = apr_pstrcat(p, "PWD", CRLF, NULL);
e = apr_bucket_pool_create(buf, strlen(buf), p);
APR_BRIGADE_INSERT_TAIL(bb, e);
e = apr_bucket_flush_create();
APR_BRIGADE_INSERT_TAIL(bb, e);
ap_pass_brigade(origin->output_filters, bb);
- apr_brigade_destroy(bb);
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "FTP: PWD");
+ ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
+ "proxy: FTP: PWD");
/* responses: 257, 500, 501, 502, 421, 550 */
/* 257 "<directory-name>" <commentary> */
/* 421 Service not available, closing control connection. */
@@ -1120,12 +1166,14 @@
/* 550 Requested action not taken. */
i = ftp_getrc_msg(origin, cbb, buffer, sizeof(buffer));
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "FTP: PWD returned status %d", i);
+ "proxy: FTP: PWD returned status %d", i);
if (i == -1 || i == 421) {
+ apr_socket_close(sock);
return ap_proxyerror(r, HTTP_BAD_GATEWAY,
"Error reading from remote server");
}
if (i == 550) {
+ apr_socket_close(sock);
return ap_proxyerror(r, HTTP_NOT_FOUND, buffer);
}
if (i == 257) {
@@ -1135,25 +1183,23 @@
#endif /*AUTODETECT_PWD*/
if (parms[0] == 'd') {
- if (len != 0)
- buf = apr_pstrcat(p, "LIST ", path, CRLF, NULL);
- else
- buf = apr_pstrcat(p, "LIST -lag", CRLF, NULL);
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "FTP: LIST %s", (len == 0 ? "-lag" : path));
+ if (len != 0)
+ buf = apr_pstrcat(p, "LIST ", path, CRLF, NULL);
+ else
+ buf = apr_pstrcat(p, "LIST -lag", CRLF, NULL);
+ ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
+ "proxy: FTP: LIST %s", (len == 0 ? "-lag" : path));
}
else {
- buf = apr_pstrcat(p, "RETR ", path, CRLF, NULL);
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "FTP: RETR %s", path);
+ buf = apr_pstrcat(p, "RETR ", path, CRLF, NULL);
+ ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
+ "proxy: FTP: RETR %s", path);
}
- bb = apr_brigade_create(p);
e = apr_bucket_pool_create(buf, strlen(buf), p);
APR_BRIGADE_INSERT_TAIL(bb, e);
e = apr_bucket_flush_create();
APR_BRIGADE_INSERT_TAIL(bb, e);
ap_pass_brigade(origin->output_filters, bb);
- apr_brigade_destroy(bb);
/* RETR: 110, 125, 150, 226, 250, 421, 425, 426, 450, 451, 500, 501, 530, 550
* NLST: 125, 150, 226, 250, 421, 425, 426, 450, 451, 500, 501, 502, 530 */
/* 110 Restart marker reply. */
@@ -1172,73 +1218,75 @@
/* 550 Requested action not taken. */
rc = ftp_getrc_msg(origin, cbb, buffer, sizeof(buffer));
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "FTP: returned status %d", rc);
+ "proxy: FTP: returned status %d", rc);
if (rc == -1) {
+ apr_socket_close(sock);
return ap_proxyerror(r, HTTP_BAD_GATEWAY,
"Error reading from remote server");
}
if (rc == 550) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "FTP: RETR failed, trying LIST instead");
+ ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
+ "proxy: FTP: RETR failed, trying LIST instead");
parms = "d";
- bb = apr_brigade_create(p);
buf = apr_pstrcat(p, "CWD ", path, CRLF, NULL);
e = apr_bucket_pool_create(buf, strlen(buf), p);
APR_BRIGADE_INSERT_TAIL(bb, e);
e = apr_bucket_flush_create();
APR_BRIGADE_INSERT_TAIL(bb, e);
ap_pass_brigade(origin->output_filters, bb);
- apr_brigade_destroy(bb);
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "FTP: CWD %s", path);
+ ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
+ "proxy: FTP: CWD %s", path);
/* possible results: 250, 421, 500, 501, 502, 530, 550 */
- /* 250 Requested file action okay, completed. */
- /* 421 Service not available, closing control connection. */
- /* 500 Syntax error, command unrecognized. */
- /* 501 Syntax error in parameters or arguments. */
- /* 502 Command not implemented. */
- /* 530 Not logged in. */
- /* 550 Requested action not taken. */
+ /* 250 Requested file action okay, completed. */
+ /* 421 Service not available, closing control connection. */
+ /* 500 Syntax error, command unrecognized. */
+ /* 501 Syntax error in parameters or arguments. */
+ /* 502 Command not implemented. */
+ /* 530 Not logged in. */
+ /* 550 Requested action not taken. */
rc = ftp_getrc_msg(origin, cbb, buffer, sizeof(buffer));
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "FTP: returned status %d", rc);
+ "proxy: FTP: returned status %d", rc);
if (rc == -1) {
+ apr_socket_close(sock);
return ap_proxyerror(r, HTTP_BAD_GATEWAY,
- "Error reading from remote server");
+ "Error reading from remote server");
}
if (rc == 550) {
+ apr_socket_close(sock);
return ap_proxyerror(r, HTTP_NOT_FOUND, buffer);
}
if (rc != 250) {
+ apr_socket_close(sock);
return ap_proxyerror(r, HTTP_BAD_GATEWAY, buffer);
}
#ifdef AUTODETECT_PWD
- bb = apr_brigade_create(p);
buf = apr_pstrcat(p, "PWD ", CRLF, NULL);
e = apr_bucket_pool_create(buf, strlen(buf), p);
APR_BRIGADE_INSERT_TAIL(bb, e);
e = apr_bucket_flush_create();
APR_BRIGADE_INSERT_TAIL(bb, e);
ap_pass_brigade(origin->output_filters, bb);
- apr_brigade_destroy(bb);
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "FTP: PWD");
-/* responses: 257, 500, 501, 502, 421, 550 */
- /* 257 "<directory-name>" <commentary> */
- /* 421 Service not available, closing control connection. */
- /* 500 Syntax error, command unrecognized. */
- /* 501 Syntax error in parameters or arguments. */
- /* 502 Command not implemented. */
- /* 550 Requested action not taken. */
+ ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
+ "proxy: FTP: PWD");
+ /* responses: 257, 500, 501, 502, 421, 550 */
+ /* 257 "<directory-name>" <commentary> */
+ /* 421 Service not available, closing control connection. */
+ /* 500 Syntax error, command unrecognized. */
+ /* 501 Syntax error in parameters or arguments. */
+ /* 502 Command not implemented. */
+ /* 550 Requested action not taken. */
i = ftp_getrc_msg(origin, cbb, buffer, sizeof(buffer));
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "FTP: PWD returned status %d", i);
+ "proxy: FTP: PWD returned status %d", i);
if (i == -1 || i == 421) {
+ apr_socket_close(sock);
return ap_proxyerror(r, HTTP_BAD_GATEWAY,
- "Error reading from remote server");
+ "Error reading from remote server");
}
if (i == 550) {
+ apr_socket_close(sock);
return ap_proxyerror(r, HTTP_NOT_FOUND, buffer);
}
if (i == 257) {
@@ -1247,24 +1295,24 @@
}
#endif /*AUTODETECT_PWD*/
- bb = apr_brigade_create(p);
buf = apr_pstrcat(p, "LIST -lag", CRLF, NULL);
e = apr_bucket_pool_create(buf, strlen(buf), p);
APR_BRIGADE_INSERT_TAIL(bb, e);
e = apr_bucket_flush_create();
APR_BRIGADE_INSERT_TAIL(bb, e);
ap_pass_brigade(origin->output_filters, bb);
- apr_brigade_destroy(bb);
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "FTP: LIST -lag");
+ "proxy: FTP: LIST -lag");
rc = ftp_getrc_msg(origin, cbb, buffer, sizeof(buffer));
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "FTP: returned status %d", rc);
+ "proxy: FTP: returned status %d", rc);
if (rc == -1)
+ apr_socket_close(sock);
return ap_proxyerror(r, HTTP_BAD_GATEWAY,
- "Error reading from remote server");
+ "Error reading from remote server");
}
if (rc != 125 && rc != 150 && rc != 226 && rc != 250) {
+ apr_socket_close(sock);
return ap_proxyerror(r, HTTP_BAD_GATEWAY, buffer);
}
@@ -1276,12 +1324,12 @@
apr_table_setn(r->headers_out, "Server", ap_get_server_version());
if (parms[0] == 'd')
- apr_table_setn(r->headers_out, "Content-Type", "text/html");
+ apr_table_setn(r->headers_out, "Content-Type", "text/plain");
else {
if (r->content_type != NULL) {
apr_table_setn(r->headers_out, "Content-Type", r->content_type);
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "FTP: Content-Type set to %s", r->content_type);
+ ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
+ "proxy: FTP: Content-Type set to %s", r->content_type);
}
else {
apr_table_setn(r->headers_out, "Content-Type", ap_default_type(r));
@@ -1289,13 +1337,13 @@
if (parms[0] != 'a' && size != NULL) {
/* We "trust" the ftp server to really serve (size) bytes... */
apr_table_setn(r->headers_out, "Content-Length", size);
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "FTP: Content-Length set to %s", size);
+ ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
+ "proxy: FTP: Content-Length set to %s", size);
}
}
if (r->content_encoding != NULL && r->content_encoding[0] != '\0') {
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "FTP: Content-Encoding set to %s", r->content_encoding);
+ "proxy: FTP: Content-Encoding set to %s", r->content_encoding);
apr_table_setn(r->headers_out, "Content-Encoding", r->content_encoding);
}
@@ -1311,7 +1359,7 @@
break;
default:
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "proxy: failed to accept data connection");
+ "proxy: FTP: failed to accept data connection");
apr_socket_close(local_sock);
return HTTP_BAD_GATEWAY;
}
@@ -1324,7 +1372,7 @@
/* the peer reset the connection already; ap_new_connection()
* closed the socket */
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
- "proxy: an error occurred creating a new connection");
+ "proxy: FTP: an error occurred creating the transfer connection");
apr_socket_close(remote_sock);
apr_socket_close(local_sock);
return HTTP_INTERNAL_SERVER_ERROR;
@@ -1333,6 +1381,9 @@
/* set up the connection filters */
ap_proxy_pre_http_connection(remote, NULL);
+/* XXX temporary end here while testing */
+/*apr_socket_close(sock);*/
+/*return HTTP_NOT_IMPLEMENTED;*/
/*
* VI: Receive the Response
@@ -1356,19 +1407,18 @@
if (!r->header_only) {
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
- "proxy: FTP start body send");
+ "proxy: FTP: start body send");
/* read the body, pass it to the output filters */
- bb = apr_brigade_create(p);
while (ap_get_brigade(remote->input_filters, bb, AP_MODE_BLOCKING) == APR_SUCCESS) {
if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb))) {
ap_pass_brigade(r->output_filters, bb);
break;
}
ap_pass_brigade(r->output_filters, bb);
- apr_brigade_destroy(bb);
- bb = apr_brigade_create(p);
+ apr_brigade_cleanup(bb);
}
+ apr_brigade_cleanup(bb);
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
"proxy: FTP end body send");
@@ -1377,16 +1427,14 @@
else {
/* abort the transfer */
- bb = apr_brigade_create(p);
buf = apr_pstrcat(p, "ABOR", CRLF, NULL);
e = apr_bucket_pool_create(buf, strlen(buf), p);
APR_BRIGADE_INSERT_TAIL(bb, e);
e = apr_bucket_flush_create();
APR_BRIGADE_INSERT_TAIL(bb, e);
ap_pass_brigade(origin->output_filters, bb);
- apr_brigade_destroy(bb);
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "FTP: ABOR");
+ ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
+ "proxy: FTP: ABOR");
/* responses: 225, 226, 421, 500, 501, 502 */
/* 225 Data connection open; no transfer in progress. */
/* 226 Closing data connection. */
@@ -1396,7 +1444,7 @@
/* 502 Command not implemented. */
i = ftp_getrc_msg(origin, cbb, buffer, sizeof(buffer));
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "FTP: returned status %d", i);
+ "proxy: FTP: returned status %d", i);
}
@@ -1409,22 +1457,22 @@
*/
/* finish */
- bb = apr_brigade_create(p);
buf = apr_pstrcat(p, "QUIT", CRLF, NULL);
e = apr_bucket_pool_create(buf, strlen(buf), p);
APR_BRIGADE_INSERT_TAIL(bb, e);
e = apr_bucket_flush_create();
APR_BRIGADE_INSERT_TAIL(bb, e);
ap_pass_brigade(origin->output_filters, bb);
- apr_brigade_destroy(bb);
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "FTP: QUIT");
+ ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
+ "proxy: FTP: QUIT");
/* responses: 221, 500 */
/* 221 Service closing control connection. */
/* 500 Syntax error, command unrecognized. */
i = ftp_getrc_msg(origin, cbb, buffer, sizeof(buffer));
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
- "FTP: QUIT: status %d", i);
+ "proxy: FTP: QUIT: status %d", i);
+ apr_brigade_destroy(bb);
+ apr_socket_close(sock);
return OK;
}