introduced 'tunnel through http proxy' for ftp

This commit is contained in:
Daniel Stenberg 2000-09-14 14:05:01 +00:00
Родитель be8b2a1e30
Коммит 86ff2c46b7
5 изменённых файлов: 93 добавлений и 53 удалений

Просмотреть файл

@ -372,6 +372,7 @@ CURLcode ftp_connect(struct connectdata *conn)
struct UrlData *data=conn->data; struct UrlData *data=conn->data;
char *buf = data->buffer; /* this is our buffer */ char *buf = data->buffer; /* this is our buffer */
struct FTP *ftp; struct FTP *ftp;
CURLcode result;
myalarm(0); /* switch off the alarm stuff */ myalarm(0); /* switch off the alarm stuff */
@ -387,6 +388,13 @@ CURLcode ftp_connect(struct connectdata *conn)
ftp->user = data->user; ftp->user = data->user;
ftp->passwd = data->passwd; ftp->passwd = data->passwd;
if (data->bits.tunnel_thru_httpproxy) {
/* We want "seamless" FTP operations through HTTP proxy tunnel */
result = GetHTTPProxyTunnel(data, data->firstsocket);
if(CURLE_OK != result)
return result;
}
/* The first thing we do is wait for the "220*" line: */ /* The first thing we do is wait for the "220*" line: */
nread = GetLastResponse(data->firstsocket, buf, conn); nread = GetLastResponse(data->firstsocket, buf, conn);
if(nread < 0) if(nread < 0)
@ -860,11 +868,17 @@ CURLcode _ftp(struct connectdata *conn)
} }
return CURLE_FTP_CANT_RECONNECT; return CURLE_FTP_CANT_RECONNECT;
} }
}
if (data->bits.tunnel_thru_httpproxy) {
/* We want "seamless" FTP operations through HTTP proxy tunnel */
result = GetHTTPProxyTunnel(data, data->secondarysocket);
if(CURLE_OK != result)
return result;
}
}
} }
/* we have the (new) data connection ready */ /* we have the (new) data connection ready */
infof(data, "Connected!\n"); infof(data, "Connected the data stream!\n");
if(data->bits.upload) { if(data->bits.upload) {

Просмотреть файл

@ -134,23 +134,21 @@ bool static checkheaders(struct UrlData *data, char *thisheader)
return FALSE; return FALSE;
} }
CURLcode http_connect(struct connectdata *conn) /*
{ * GetHTTPProxyTunnel() requires that we're connected to a HTTP proxy. This
struct UrlData *data; * function will issue the necessary commands to get a seamless tunnel through
* this proxy. After that, the socket can be used just as a normal socket.
data=conn->data;
/* If we are not using a proxy and we want a secure connection,
* perform SSL initialization & connection now.
* If using a proxy with https, then we must tell the proxy to CONNECT
* us to the host we want to talk to. Only after the connect
* has occured, can we start talking SSL
*/ */
if (conn->protocol & PROT_HTTPS) {
if (data->bits.httpproxy) { CURLcode GetHTTPProxyTunnel(struct UrlData *data, int tunnelsocket)
{
int httperror=0;
int subversion=0;
infof(data, "Establish HTTP proxy tunnel\n");
/* OK, now send the connect statment */ /* OK, now send the connect statment */
sendf(data->firstsocket, data, sendf(tunnelsocket, data,
"CONNECT %s:%d HTTP/1.0\015\012" "CONNECT %s:%d HTTP/1.0\015\012"
"%s" "%s"
"%s" "%s"
@ -161,11 +159,7 @@ CURLcode http_connect(struct connectdata *conn)
); );
/* wait for the proxy to send us a HTTP/1.0 200 OK header */ /* wait for the proxy to send us a HTTP/1.0 200 OK header */
/* Daniel rewrote this part Nov 5 1998 to make it more obvious */ while(GetLine(tunnelsocket, data->buffer, data)) {
{
int httperror=0;
int subversion=0;
while(GetLine(data->firstsocket, data->buffer, data)) {
if('\r' == data->buffer[0]) if('\r' == data->buffer[0])
break; /* end of headers */ break; /* end of headers */
if(2 == sscanf(data->buffer, "HTTP/1.%d %d", if(2 == sscanf(data->buffer, "HTTP/1.%d %d",
@ -182,8 +176,30 @@ CURLcode http_connect(struct connectdata *conn)
failf(data, "Received error code %d from proxy", httperror); failf(data, "Received error code %d from proxy", httperror);
return CURLE_READ_ERROR; return CURLE_READ_ERROR;
} }
}
infof (data, "Proxy has replied to CONNECT request\n"); infof (data, "Proxy replied to CONNECT request\n");
return CURLE_OK;
}
CURLcode http_connect(struct connectdata *conn)
{
struct UrlData *data;
CURLcode result;
data=conn->data;
/* If we are not using a proxy and we want a secure connection,
* perform SSL initialization & connection now.
* If using a proxy with https, then we must tell the proxy to CONNECT
* us to the host we want to talk to. Only after the connect
* has occured, can we start talking SSL
*/
if (conn->protocol & PROT_HTTPS) {
if (data->bits.httpproxy) {
/* HTTPS through a proxy can only be done with a tunnel */
result = GetHTTPProxyTunnel(data, data->firstsocket);
if(CURLE_OK != result)
return result;
} }
/* now, perform the SSL initialization for this socket */ /* now, perform the SSL initialization for this socket */

Просмотреть файл

@ -41,8 +41,10 @@
* ------------------------------------------------------------ * ------------------------------------------------------------
****************************************************************************/ ****************************************************************************/
/* protocol-specific functions set up to be called by the main engine */ /* ftp can use this as well */
CURLcode GetHTTPProxyTunnel(struct UrlData *data, int tunnelsocket);
/* protocol-specific functions set up to be called by the main engine */
CURLcode http(struct connectdata *conn); CURLcode http(struct connectdata *conn);
CURLcode http_done(struct connectdata *conn); CURLcode http_done(struct connectdata *conn);
CURLcode http_connect(struct connectdata *conn); CURLcode http_connect(struct connectdata *conn);

Просмотреть файл

@ -437,6 +437,9 @@ CURLcode curl_setopt(CURL *curl, CURLoption option, ...)
data->proxy = va_arg(param, char *); data->proxy = va_arg(param, char *);
data->bits.httpproxy = data->proxy?1:0; data->bits.httpproxy = data->proxy?1:0;
break; break;
case CURLOPT_HTTPPROXYTUNNEL:
data->bits.tunnel_thru_httpproxy = va_arg(param, long)?TRUE:FALSE;
break;
case CURLOPT_PROXYPORT: case CURLOPT_PROXYPORT:
data->proxyport = va_arg(param, long); data->proxyport = va_arg(param, long);
break; break;
@ -619,6 +622,7 @@ CURLcode curl_disconnect(CURLconnect *c_connect)
return CURLE_OK; return CURLE_OK;
} }
/* /*
* NAME curl_connect() * NAME curl_connect()
* *
@ -948,7 +952,10 @@ CURLcode curl_connect(CURL *curl, CURLconnect **in_connect)
data->remote_port = PORT_FTP; data->remote_port = PORT_FTP;
conn->protocol |= PROT_FTP; conn->protocol |= PROT_FTP;
if(data->bits.httpproxy) { if(data->bits.httpproxy &&
!data->bits.tunnel_thru_httpproxy) {
/* Unless we have asked to tunnel ftp operations through the proxy, we
switch and use HTTP operations only */
conn->curl_do = http; conn->curl_do = http;
conn->curl_done = http_done; conn->curl_done = http_done;
conn->curl_close = http_close; conn->curl_close = http_close;

Просмотреть файл

@ -245,6 +245,7 @@ struct FTP {
}; };
struct Configbits { struct Configbits {
bool tunnel_thru_httpproxy;
bool ftp_append; bool ftp_append;
bool ftp_ascii; bool ftp_ascii;
bool ftp_list_only; bool ftp_list_only;