ASF Bugzilla – Attachment 20692 Details for
Bug 41676
Refactor mod_proxy_ftp
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
mod_proxy_ftp.c refactoring patch (removes redundant functions)
patch.ftp (text/plain), 11.25 KB, created by
rahul
on 2007-08-23 07:58:03 UTC
(
hide
)
Description:
mod_proxy_ftp.c refactoring patch (removes redundant functions)
Filename:
MIME Type:
Creator:
rahul
Created:
2007-08-23 07:58:03 UTC
Size:
11.25 KB
patch
obsolete
>Index: mod_proxy_ftp.c >=================================================================== >--- mod_proxy_ftp.c (revision 568557) >+++ mod_proxy_ftp.c (working copy) >@@ -37,6 +37,8 @@ > > module AP_MODULE_DECLARE_DATA proxy_ftp_module; > >+const char *proxy_function = "FTP"; >+ > /* > * Decodes a '%' escaped string, and returns the number of characters > */ >@@ -744,33 +746,31 @@ > proxy_ftp_cleanup(r, conn); > return ap_proxyerror(r, statuscode, message); > } >-/* >- * Handles direct access of ftp:// URLs >- * Original (Non-PASV) version from >- * Troy Morrison <spiffnet@zoom.com> >- * PASV added by Chuck >- * Filters by [Graham Leggett <minfrin@sharp.fm>] >- */ >-static int proxy_ftp_handler(request_rec *r, proxy_worker *worker, >- proxy_server_conf *conf, char *url, >- const char *proxyhost, apr_port_t proxyport) >+ >+static >+apr_status_t ap_proxy_ftp_cleanup(request_rec *r, >+ proxy_conn_rec *backend) > { >- apr_pool_t *p = r->pool; >- conn_rec *c = r->connection; >- proxy_conn_rec *backend; >+ ap_proxy_release_connection(proxy_function, backend, r->server); >+ return OK; >+} >+ >+static int ap_proxy_ftp_request(apr_pool_t* p, request_rec *r, >+ proxy_conn_rec *backend, conn_rec *c, >+ proxy_server_conf *conf, >+ apr_uri_t *uri, >+ char *url, char *server_portstr) >+{ > apr_socket_t *sock, *local_sock, *data_sock = NULL; >- apr_sockaddr_t *connect_addr = NULL; >+ apr_sockaddr_t *connect_addr = backend->addr; > apr_status_t rv; > conn_rec *origin, *data = NULL; > apr_status_t err = APR_SUCCESS; >- apr_status_t uerr = APR_SUCCESS; > apr_bucket_brigade *bb = apr_brigade_create(p, c->bucket_alloc); >- char *buf, *connectname; >- apr_port_t connectport; >+ char *buf; > char buffer[MAX_STRING_LEN]; > char *ftpmessage = NULL; > char *path, *strp, *type_suffix, *cwd = NULL; >- apr_uri_t uri; > char *user = NULL; > /* char *account = NULL; how to supply an account in a URL? */ > const char *password = NULL; >@@ -787,53 +787,13 @@ > int connect = 0, use_port = 0; > char dates[APR_RFC822_DATE_LEN]; > int status; >- apr_pool_t *address_pool; > >- /* is this for us? */ >- if (proxyhost) { >- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, >- "proxy: FTP: declining URL %s - proxyhost %s specified:", url, proxyhost); >- return DECLINED; /* proxy connections are via HTTP */ >- } >- if (strncasecmp(url, "ftp:", 4)) { >- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, >- "proxy: FTP: declining URL %s - not ftp:", url); >- return DECLINED; /* only interested in FTP */ >- } >- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, >- "proxy: FTP: serving URL %s", url); >+ path = apr_pstrdup(p, uri->path); > >- >- /* >- * I: Who Do I Connect To? ----------------------- >- * >- * Break up the URL to determine the host to connect to >- */ >- >- /* we only support GET and HEAD */ >- if (r->method_number != M_GET) >- return HTTP_NOT_IMPLEMENTED; >- >- /* We break the URL into host, port, path-search */ >- if (r->parsed_uri.hostname == NULL) { >- if (APR_SUCCESS != apr_uri_parse(p, url, &uri)) { >- return ap_proxyerror(r, HTTP_BAD_REQUEST, >- apr_psprintf(p, "URI cannot be parsed: %s", url)); >- } >- connectname = uri.hostname; >- connectport = uri.port; >- path = apr_pstrdup(p, uri.path); >+ if (uri->port == 0) { >+ uri->port = apr_uri_port_of_scheme("ftp"); > } >- else { >- connectname = r->parsed_uri.hostname; >- connectport = r->parsed_uri.port; >- path = apr_pstrdup(p, r->parsed_uri.path); >- } >- if (connectport == 0) { >- connectport = apr_uri_port_of_scheme("ftp"); >- } > path = (path != NULL && path[0] != '\0') ? &path[1] : ""; >- > type_suffix = strchr(path, ';'); > if (type_suffix != NULL) > *(type_suffix++) = '\0'; >@@ -893,91 +853,14 @@ > } > > ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, >- "proxy: FTP: connecting %s to %s:%d", url, connectname, connectport); >+ "proxy: FTP: connecting %s to %s:%d", url, uri->hostname, uri->port); > >- if (worker->is_address_reusable) { >- if (!worker->cp->addr) { >- if ((err = PROXY_THREAD_LOCK(worker)) != APR_SUCCESS) { >- ap_log_error(APLOG_MARK, APLOG_ERR, err, r->server, >- "proxy: FTP: lock"); >- return HTTP_INTERNAL_SERVER_ERROR; >- } >- } >- connect_addr = worker->cp->addr; >- address_pool = worker->cp->pool; >- } >- else >- address_pool = r->pool; >- >- /* do a DNS lookup for the destination host */ >- if (!connect_addr) >- err = apr_sockaddr_info_get(&(connect_addr), >- connectname, APR_UNSPEC, >- connectport, 0, >- address_pool); >- if (worker->is_address_reusable && !worker->cp->addr) { >- worker->cp->addr = connect_addr; >- if ((uerr = PROXY_THREAD_UNLOCK(worker)) != APR_SUCCESS) { >- ap_log_error(APLOG_MARK, APLOG_ERR, uerr, r->server, >- "proxy: FTP: unlock"); >- } >- } >- /* >- * get all the possible IP addresses for the destname and loop through >- * them until we get a successful connection >- */ > if (APR_SUCCESS != err) { > return ap_proxyerror(r, HTTP_BAD_GATEWAY, apr_pstrcat(p, > "DNS lookup failure for: ", >- connectname, NULL)); >+ uri->hostname, NULL)); > } > >- /* check if ProxyBlock directive on this host */ >- if (OK != ap_proxy_checkproxyblock(r, conf, connect_addr)) { >- return ap_proxyerror(r, HTTP_FORBIDDEN, >- "Connect to remote machine blocked"); >- } >- >- /* create space for state information */ >- backend = (proxy_conn_rec *) ap_get_module_config(c->conn_config, &proxy_ftp_module); >- if (!backend) { >- status = ap_proxy_acquire_connection("FTP", &backend, worker, r->server); >- if (status != OK) { >- if (backend) { >- backend->close = 1; >- ap_proxy_release_connection("FTP", backend, r->server); >- } >- return status; >- } >- /* TODO: see if ftp could use determine_connection */ >- backend->addr = connect_addr; >- ap_set_module_config(c->conn_config, &proxy_ftp_module, backend); >- } >- >- >- /* >- * II: Make the Connection ----------------------- >- * >- * We have determined who to connect to. Now make the connection. >- */ >- >- >- if (ap_proxy_connect_backend("FTP", backend, worker, r->server)) { >- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, >- "proxy: FTP: an error occurred creating a new connection to %pI (%s)", >- connect_addr, connectname); >- proxy_ftp_cleanup(r, backend); >- return HTTP_SERVICE_UNAVAILABLE; >- } >- >- if (!backend->connection) { >- status = ap_proxy_connection_create("FTP", backend, c, r->server); >- if (status != OK) { >- proxy_ftp_cleanup(r, backend); >- return status; >- } >- } >- > /* Use old naming */ > origin = backend->connection; > sock = backend->sock; >@@ -1886,6 +1769,107 @@ > return OK; > } > >+/* >+ * Handles direct access of ftp:// URLs >+ * Original (Non-PASV) version from >+ * Troy Morrison <spiffnet@zoom.com> >+ * PASV added by Chuck >+ * Filters by [Graham Leggett <minfrin@sharp.fm>] >+ */ >+static int proxy_ftp_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]; >+ char *scheme; >+ const char *u; >+ proxy_conn_rec *backend = NULL; >+ >+ /* Note: Memory pool allocation. >+ * A downstream keepalive connection is always connected to the existence >+ * (or not) of an upstream keepalive connection. If this is not done then >+ * load balancing against multiple backend servers breaks (one backend >+ * server ends up taking 100% of the load), and the risk is run of >+ * downstream keepalive connections being kept open unnecessarily. This >+ * keeps webservers busy and ties up resources. >+ * >+ * As a result, we allocate all sockets out of the upstream connection >+ * pool, and when we want to reuse a socket, we check first whether the >+ * connection ID of the current upstream connection is the same as that >+ * of the connection when the socket was opened. >+ */ >+ apr_pool_t *p = r->connection->pool; >+ conn_rec *c = r->connection; >+ apr_uri_t *uri = apr_palloc(r->connection->pool, sizeof(*uri)); >+ >+ /* find the scheme */ >+ u = strchr(url, ':'); >+ if (u == NULL || u[1] != '/' || u[2] != '/' || u[3] == '\0') >+ return DECLINED; >+ scheme = apr_pstrndup(c->pool, url, u - url); >+ /* scheme is lowercase */ >+ ap_str_tolower(scheme); >+ /* is it for us? */ >+ if (strcmp(scheme, "ftp") || proxyname) { >+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, >+ "proxy: FTP: declining URL %s", url); >+ return DECLINED; /* only interested in direct FTP */ >+ } >+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, >+ "proxy: FTP: serving URL %s", url); >+ >+ /* we only support GET and HEAD -- this should go away.FTP has mappings >+ * for all HTTP methods. */ >+ if (r->method_number != M_GET) >+ return HTTP_NOT_IMPLEMENTED; >+ >+ /* create space for state information */ >+ if ((status = ap_proxy_acquire_connection(proxy_function, &backend, >+ worker, r->server)) != OK) >+ goto cleanup; >+ >+ >+ /* Step One: Determine Who To Connect To */ >+ if ((status = ap_proxy_determine_connection(p, r, conf, worker, backend, >+ uri, &url, 0, >+ 0, server_portstr, >+ sizeof(server_portstr))) != OK) >+ goto cleanup; >+ >+ /* Step Two: Make the Connection */ >+ if (ap_proxy_connect_backend(proxy_function, backend, worker, r->server)) { >+ status = HTTP_SERVICE_UNAVAILABLE; >+ goto cleanup; >+ } >+ >+ /* Step Three: Create conn_rec */ >+ if (!backend->connection) { >+ if ((status = ap_proxy_connection_create(proxy_function, backend, >+ c, r->server)) != OK) >+ goto cleanup; >+ } >+ >+ /* Step Four: Initiate Ftp Request */ >+ if ((status = ap_proxy_ftp_request(p, r, backend, backend->connection, >+ conf, uri, url, server_portstr)) != OK) >+ goto cleanup; >+ >+ /* Step Five: Receive the Response -- is included in previous step */ >+ >+ /* Step Six: Clean Up */ >+ >+cleanup: >+ if (backend) { >+ if (status != OK) >+ backend->close = 1; >+ ap_proxy_ftp_cleanup(r, backend); >+ } >+ return status; >+ >+} >+ > static void ap_proxy_ftp_register_hook(apr_pool_t *p) > { > /* hooks */
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 41676
:
19624
| 20692