mirror of
https://github.com/curl/curl.git
synced 2026-07-28 17:23:06 +03:00
introduced 'tunnel through http proxy' for ftp
This commit is contained in:
parent
be8b2a1e30
commit
86ff2c46b7
5 changed files with 93 additions and 53 deletions
114
lib/http.c
114
lib/http.c
|
|
@ -134,9 +134,57 @@ bool static checkheaders(struct UrlData *data, char *thisheader)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* GetHTTPProxyTunnel() requires that we're connected to a HTTP proxy. This
|
||||
* 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.
|
||||
*/
|
||||
|
||||
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 */
|
||||
sendf(tunnelsocket, data,
|
||||
"CONNECT %s:%d HTTP/1.0\015\012"
|
||||
"%s"
|
||||
"%s"
|
||||
"\r\n",
|
||||
data->hostname, data->remote_port,
|
||||
(data->bits.proxy_user_passwd)?data->ptr_proxyuserpwd:"",
|
||||
(data->useragent?data->ptr_uagent:"")
|
||||
);
|
||||
|
||||
/* wait for the proxy to send us a HTTP/1.0 200 OK header */
|
||||
while(GetLine(tunnelsocket, data->buffer, data)) {
|
||||
if('\r' == data->buffer[0])
|
||||
break; /* end of headers */
|
||||
if(2 == sscanf(data->buffer, "HTTP/1.%d %d",
|
||||
&subversion,
|
||||
&httperror)) {
|
||||
;
|
||||
}
|
||||
}
|
||||
if(200 != httperror) {
|
||||
if(407 == httperror)
|
||||
/* Added Nov 6 1998 */
|
||||
failf(data, "Proxy requires authorization!");
|
||||
else
|
||||
failf(data, "Received error code %d from proxy", httperror);
|
||||
return CURLE_READ_ERROR;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
|
@ -146,59 +194,27 @@ CURLcode http_connect(struct connectdata *conn)
|
|||
* 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) {
|
||||
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;
|
||||
}
|
||||
|
||||
/* OK, now send the connect statment */
|
||||
sendf(data->firstsocket, data,
|
||||
"CONNECT %s:%d HTTP/1.0\015\012"
|
||||
"%s"
|
||||
"%s"
|
||||
"\r\n",
|
||||
data->hostname, data->remote_port,
|
||||
(data->bits.proxy_user_passwd)?data->ptr_proxyuserpwd:"",
|
||||
(data->useragent?data->ptr_uagent:"")
|
||||
);
|
||||
|
||||
/* 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 */
|
||||
{
|
||||
int httperror=0;
|
||||
int subversion=0;
|
||||
while(GetLine(data->firstsocket, data->buffer, data)) {
|
||||
if('\r' == data->buffer[0])
|
||||
break; /* end of headers */
|
||||
if(2 == sscanf(data->buffer, "HTTP/1.%d %d",
|
||||
&subversion,
|
||||
&httperror)) {
|
||||
;
|
||||
}
|
||||
}
|
||||
if(200 != httperror) {
|
||||
if(407 == httperror)
|
||||
/* Added Nov 6 1998 */
|
||||
failf(data, "Proxy requires authorization!");
|
||||
else
|
||||
failf(data, "Received error code %d from proxy", httperror);
|
||||
return CURLE_READ_ERROR;
|
||||
}
|
||||
}
|
||||
infof (data, "Proxy has replied to CONNECT request\n");
|
||||
}
|
||||
|
||||
/* now, perform the SSL initialization for this socket */
|
||||
if(UrgSSLConnect (data)) {
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
/* now, perform the SSL initialization for this socket */
|
||||
if(UrgSSLConnect (data)) {
|
||||
return CURLE_SSL_CONNECT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if(data->bits.user_passwd && !data->bits.this_is_a_follow) {
|
||||
/* Authorization: is requested, this is not a followed location, get the
|
||||
original host name */
|
||||
data->auth_host = strdup(data->hostname);
|
||||
}
|
||||
if(data->bits.user_passwd && !data->bits.this_is_a_follow) {
|
||||
/* Authorization: is requested, this is not a followed location, get the
|
||||
original host name */
|
||||
data->auth_host = strdup(data->hostname);
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* called from curl_close() when this struct is about to get wasted, free
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue