* because it has the lifetime of the connection. The other allocations
* are temporary and can be tossed away any time.
*/
- user = ap_getword_nulls (r->pool, &password, ':');
+ user = ap_getword_nulls (r->connection->pool, &password, ':');
r->ap_auth_type = "Basic";
r->user = r->parsed_uri.user = user;
}
#ifndef _OSD_POSIX /* BS2000 has this option "always on" */
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
"proxy: error setting reuseaddr option: setsockopt(SO_REUSEADDR)");
- apr_socket_close(sock);
return HTTP_INTERNAL_SERVER_ERROR;
#endif /*_OSD_POSIX*/
}
/* handle a permanent error from the above loop */
if (failed) {
- apr_socket_close(sock);
return ap_proxyerror(r, HTTP_BAD_GATEWAY, apr_psprintf(r->pool,
"Could not connect to remote machine: %s port %d",
connectname, connectport));
* closed the socket */
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
"proxy: an error occurred creating a new connection to %pI (%s)", connect_addr, connectname);
- apr_socket_close(sock);
return HTTP_INTERNAL_SERVER_ERROR;
}
- conf->id = r->connection->id;
- /* allocate this out of the connection pool - the check on r->connection->id makes
- * sure that this string does not live past the connection lifetime */
- conf->connectname = apr_pstrdup(r->connection->pool, connectname);
- conf->connectport = connectport;
/* if a keepalive connection is floating around, close it first! */
/* we might support ftp keepalives later, but not now... */
- if (conf->client_socket) {
- apr_socket_close(conf->client_socket);
- conf->client_socket = NULL;
+ if ((conf->id == r->connection->id) && conf->connection) {
+ apr_socket_close(conf->connection->client_socket);
+ conf->connection = NULL;
}
+ conf->id = r->connection->id;
+ /* allocate this out of the connection pool - the check on r->connection->id makes
+ * sure that this string does not get accessed past the connection lifetime */
+ conf->connectname = apr_pstrdup(r->connection->pool, connectname);
+ conf->connectport = connectport;
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
"proxy: connection complete");
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
"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");
}
#if 0
* Retry-After = "Retry-After" ":" ( HTTP-date | delta-seconds )
*/
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) {
- apr_socket_close(sock);
return ap_proxyerror(r, HTTP_BAD_GATEWAY, buffer);
}
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
"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 == 530) {
- apr_socket_close(sock);
return ftp_unauthorized (r, 1); /* log it: user name guessing attempt? */
}
if (i != 230 && i != 331) {
- apr_socket_close(sock);
return ap_proxyerror(r, HTTP_BAD_GATEWAY, buffer);
}
if (i == 331) { /* send password */
if (password == NULL) {
- apr_socket_close(sock);
return ftp_unauthorized (r, 0);
}
buf = apr_pstrcat(p, "PASS ", password, CRLF, NULL);
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
"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) {
- apr_socket_close(sock);
return ftp_unauthorized (r, 1); /* log it: passwd guessing attempt? */
}
if (i != 230 && i != 202) {
- apr_socket_close(sock);
return ap_proxyerror(r, HTTP_BAD_GATEWAY, 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 == 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);
}
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 */
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 != 227 && i != 502) {
- apr_socket_close(sock);
return ap_proxyerror(r, HTTP_BAD_GATEWAY, buffer);
}
else if (i == 227) {
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;
}
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,
if ((apr_socket_create(&local_sock, APR_INET, SOCK_STREAM, r->pool)) != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
"proxy: FTP: error creating local socket");
- apr_socket_close(sock);
return HTTP_INTERNAL_SERVER_ERROR;
}
- apr_socket_addr_get(&local_addr, APR_LOCAL, sock);
+ apr_socket_addr_get(&local_addr, APR_LOCAL, local_sock);
apr_sockaddr_port_get(&local_port, local_addr);
apr_sockaddr_ip_get(&local_ip, local_addr);
#ifndef _OSD_POSIX /* BS2000 has this option "always on" */
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
"proxy: FTP: error setting reuseaddr option");
- apr_socket_close(local_sock);
- apr_socket_close(sock);
return HTTP_INTERNAL_SERVER_ERROR;
#endif /*_OSD_POSIX*/
}
local_port, 0, r->pool) != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
"proxy: FTP: error creating local socket address");
- apr_socket_close(sock);
return HTTP_INTERNAL_SERVER_ERROR;
}
if (apr_bind(local_sock, local_addr) != APR_SUCCESS) {
- char buff[22];
-
- apr_snprintf(buff, sizeof(buff), "%s:%d", local_ip, local_port);
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "proxy: FTP: error binding to ftp data socket %s", buff);
- apr_socket_close(remote_sock);
- apr_socket_close(sock);
+ "proxy: FTP: error binding to ftp data socket %s:%d", local_ip, local_port);
return HTTP_INTERNAL_SERVER_ERROR;
}
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 == 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 = "";
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
"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) {
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
"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");
}
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
"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) {
- 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);
}
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
"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) {
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, NULL,
"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 != 125 && rc != 150 && rc != 226 && rc != 250) {
- apr_socket_close(sock);
return ap_proxyerror(r, HTTP_BAD_GATEWAY, buffer);
}
default:
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
"proxy: FTP: failed to accept data connection");
- apr_socket_close(local_sock);
return HTTP_BAD_GATEWAY;
}
}
* closed the socket */
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
"proxy: FTP: an error occurred creating the transfer connection");
- apr_socket_close(remote_sock);
- apr_socket_close(local_sock);
return HTTP_INTERNAL_SERVER_ERROR;
}
ap_proxy_pre_http_connection(remote, NULL);
/* XXX temporary end here while testing */
-/*apr_socket_close(sock);*/
/*return HTTP_NOT_IMPLEMENTED;*/
/*
"proxy: FTP: QUIT: status %d", i);
apr_brigade_destroy(bb);
- apr_socket_close(sock);
return OK;
}
* 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->pool;
+ apr_pool_t *p = r->connection->pool;
conn_rec *c = r->connection;
apr_bucket *e;
apr_bucket_brigade *bb = apr_brigade_create(p);
/* do a DNS lookup for the destination host */
/* see memory note above */
- err = apr_sockaddr_info_get(&uri_addr, uri.hostname, APR_UNSPEC, uri.port, 0, c->pool);
+ err = apr_sockaddr_info_get(&uri_addr, apr_pstrdup(c->pool, uri.hostname), APR_UNSPEC, uri.port, 0, c->pool);
+ /* allocate these out of the connection pool - the check on r->connection->id makes
+ * sure that this string does not get accessed past the connection lifetime */
/* are we connecting directly, or via a proxy? */
if (proxyname) {
- connectname = proxyname;
+ connectname = apr_pstrdup(c->pool,proxyname);
connectport = proxyport;
/* see memory note above */
- err = apr_sockaddr_info_get(&connect_addr, proxyname, APR_UNSPEC, proxyport, 0, c->pool);
+ err = apr_sockaddr_info_get(&connect_addr, connectname, APR_UNSPEC, connectport, 0, c->pool);
}
else {
- connectname = uri.hostname;
+ connectname = apr_pstrdup(c->pool, uri.hostname);
connectport = uri.port;
connect_addr = uri_addr;
url = apr_pstrcat(p, uri.path, uri.query ? "?" : "",
* open, or whether it should be closed and a new socket created.
*/
/* see memory note above */
- if (conf->client_socket) {
+ if (conf->connection) {
if ((conf->id == c->id) &&
(conf->connectport == connectport) &&
(conf->connectname) &&
}
else {
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
- "proxy: keepalive address mismatch (close old socket (%s/%s, %d/%d))", connectname, conf->connectname, connectport, conf->connectport);
- apr_socket_close(conf->client_socket);
- conf->client_socket = NULL;
+ "proxy: keepalive address mismatch / connection has"
+ " changed (close old socket (%s/%s, %d/%d))",
+ connectname, conf->connectname,
+ connectport, conf->connectport);
+ apr_socket_close(conf->connection->client_socket);
+ conf->connection = NULL;
}
}
/* get a socket - either a keepalive one, or a new one */
new = 1;
- if ((conf->id == c->id) && (conf->client_socket)) {
+ if ((conf->id == c->id) && (conf->connection)) {
/* use previous keepalive socket */
- sock = conf->client_socket;
+ sock = conf->connection->client_socket;
+ origin = conf->connection;
new = 0;
/* XXX FIXME: If the socket has since closed, change new to 1 so
if (new) {
/* create a new socket */
- conf->client_socket = NULL;
+ conf->connection = NULL;
/* see memory note above */
if ((apr_socket_create(&sock, APR_INET, SOCK_STREAM, c->pool)) != APR_SUCCESS) {
/* if an error occurred, loop round and try again */
if (err != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_ERR, err, r->server,
- "proxy: attempt to connect to %pI (%s) failed", connect_addr, connectname);
+ "proxy: attempt to connect to %pI (%s) failed",
+ connect_addr, connectname);
connect_addr = connect_addr->next;
continue;
}
return HTTP_BAD_GATEWAY;
}
}
- }
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
- "proxy: socket is connected");
+ ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
+ "proxy: socket is connected");
+
+ /* the socket is now open, create a new downstream connection */
+ origin = ap_new_connection(c->pool, r->server, sock, r->connection->id);
+ if (!origin) {
+ /* 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 to %pI (%s)", connect_addr, connectname);
+ apr_socket_close(sock);
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+ conf->id = r->connection->id;
+ conf->connectname = connectname;
+ conf->connectport = connectport;
+ conf->connection = origin;
- /* the socket is now open, create a new downstream connection */
- origin = ap_new_connection(p, r->server, sock, r->connection->id);
- if (!origin) {
- /* 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 to %pI (%s)", connect_addr, connectname);
- apr_socket_close(sock);
- return HTTP_INTERNAL_SERVER_ERROR;
- }
- conf->id = r->connection->id;
- /* allocate this out of the config pool */
- conf->connectname = apr_pstrdup(r->server->process->pconf, connectname);
- conf->connectport = connectport;
- conf->client_socket = sock;
+ "proxy: connection complete");
- ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
- "proxy: connection complete");
+ /* set up the connection filters */
+ ap_proxy_pre_http_connection(origin, NULL);
+ }
/*
* Send the HTTP/1.1 request to the remote server
*/
- /* set up the connection filters */
- ap_proxy_pre_http_connection(origin, NULL);
/* strip connection listed hop-by-hop headers from the request */
/* even though in theory a connection: close coming from the client
if (APR_SUCCESS != (rv = ap_proxy_string_read(origin, bb, buffer, sizeof(buffer)))) {
apr_socket_close(sock);
- conf->client_socket = NULL;
+ conf->connection = NULL;
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
"proxy: error reading status line from remote server %s",
connectname);
/* If not an HTTP/1 message or if the status line was > 8192 bytes */
else if ((buffer[5] != '1') || (len >= sizeof(buffer)-1)) {
apr_socket_close(sock);
- conf->client_socket = NULL;
+ conf->connection = NULL;
return ap_proxyerror(r, HTTP_BAD_GATEWAY,
apr_pstrcat(p, "Corrupt status line returned by remote server: ", buffer, NULL));
}
/* munge the Location and URI response headers according to ProxyPassReverse */
{
const char *buf;
+/* XXX FIXME: this isn't working */
if ((buf = apr_table_get(r->headers_out, "Location")) != NULL)
apr_table_set(r->headers_out, "Location", ap_proxy_location_reverse_map(r, buf));
if ((buf = apr_table_get(r->headers_out, "Content-Location")) != NULL)
*/
if (close || (r->proto_num < HTTP_VERSION(1,1))) {
apr_socket_close(sock);
- conf->client_socket = NULL;
+ conf->connection = NULL;
}
return OK;