diff options
Diffstat (limited to 'lib/http.c')
-rw-r--r-- | lib/http.c | 114 |
1 files changed, 65 insertions, 49 deletions
diff --git a/lib/http.c b/lib/http.c index 1ee8b4519..7d3507ce4 100644 --- a/lib/http.c +++ b/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 |