aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/ftp.c7
-rw-r--r--lib/http.c52
-rw-r--r--lib/http.h6
3 files changed, 45 insertions, 20 deletions
diff --git a/lib/ftp.c b/lib/ftp.c
index f941fea37..d37f9dc40 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -1670,8 +1670,7 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn,
/* BLOCKING */
/* We want "seamless" FTP operations through HTTP proxy tunnel */
- result = Curl_ConnectHTTPProxyTunnel(conn, SECONDARYSOCKET,
- newhost, newport);
+ result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, newhost, newport);
if(CURLE_OK != result)
return result;
}
@@ -2745,8 +2744,8 @@ CURLcode Curl_ftp_connect(struct connectdata *conn,
if (conn->bits.tunnel_proxy) {
/* BLOCKING */
/* We want "seamless" FTP operations through HTTP proxy tunnel */
- result = Curl_ConnectHTTPProxyTunnel(conn, FIRSTSOCKET,
- conn->host.name, conn->remote_port);
+ result = Curl_proxyCONNECT(conn, FIRSTSOCKET,
+ conn->host.name, conn->remote_port);
if(CURLE_OK != result)
return result;
}
diff --git a/lib/http.c b/lib/http.c
index 84f357a9c..9d9bb3e42 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -96,6 +96,7 @@
#include "memory.h"
#include "select.h"
#include "parsedate.h" /* for the week day and month names */
+#include "strtoofft.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
@@ -1053,10 +1054,9 @@ Curl_compareheader(char *headerline, /* line to check */
}
/*
- * ConnectHTTPProxyTunnel() 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.
+ * Curl_proxyCONNECT() 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.
*
* This badly needs to be rewritten. CONNECT should be sent and dealt with
* like any ordinary HTTP request, and not specially crafted like this. This
@@ -1064,10 +1064,10 @@ Curl_compareheader(char *headerline, /* line to check */
* much work to do at the moment.
*/
-CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
- int sockindex,
- char *hostname,
- int remote_port)
+CURLcode Curl_proxyCONNECT(struct connectdata *conn,
+ int sockindex,
+ char *hostname,
+ int remote_port)
{
int subversion=0;
struct SessionHandle *data=conn->data;
@@ -1076,7 +1076,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
int res;
size_t nread; /* total size read */
int perline; /* count bytes per line */
- bool keepon=TRUE;
+ int keepon=TRUE;
ssize_t gotbytes;
char *ptr;
long timeout =
@@ -1085,6 +1085,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
char *host_port;
curl_socket_t tunnelsocket = conn->sock[sockindex];
send_buffer *req_buffer;
+ curl_off_t cl=0;
#define SELECT_OK 0
#define SELECT_ERROR 1
@@ -1215,6 +1216,13 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
int i;
nread += gotbytes;
+
+ if(keepon > TRUE) {
+ cl -= gotbytes;
+ if(!cl)
+ break;
+ }
+ else
for(i = 0; i < gotbytes; ptr++, i++) {
perline++; /* amount of bytes in this line so far */
if(*ptr=='\n') {
@@ -1242,7 +1250,21 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
if(('\r' == line_start[0]) ||
('\n' == line_start[0])) {
/* end of response-headers from the proxy */
- keepon=FALSE;
+ if(cl && (407 == k->httpcode) && !data->state.authproblem) {
+ /* If we get a 407 response code with content length when we
+ * have no auth problem, we must ignore the whole
+ * response-body */
+ keepon = 2;
+ infof(data, "Ignore %" FORMAT_OFF_T
+ " bytes of response-body\n", cl);
+ cl -= (gotbytes - i);/* remove the remaining chunk of what
+ we already read */
+ if(cl<=0)
+ /* if the whole thing was already read, we are done! */
+ keepon=FALSE;
+ }
+ else
+ keepon = FALSE;
break; /* breaks out of for-loop, not switch() */
}
@@ -1257,6 +1279,10 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
if(result)
return result;
}
+ else if(checkprefix("Content-Length:", line_start)) {
+ cl = curlx_strtoofft(line_start + strlen("Content-Length:"),
+ NULL, 10);
+ }
else if(2 == sscanf(line_start, "HTTP/1.%d %d",
&subversion,
&k->httpcode)) {
@@ -1323,9 +1349,9 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
if(conn->bits.tunnel_proxy) {
/* either SSL over proxy, or explicitly asked for */
- result = Curl_ConnectHTTPProxyTunnel(conn, FIRSTSOCKET,
- conn->host.name,
- conn->remote_port);
+ result = Curl_proxyCONNECT(conn, FIRSTSOCKET,
+ conn->host.name,
+ conn->remote_port);
if(CURLE_OK != result)
return result;
}
diff --git a/lib/http.h b/lib/http.h
index 23afc9115..599d067c0 100644
--- a/lib/http.h
+++ b/lib/http.h
@@ -29,9 +29,9 @@ bool Curl_compareheader(char *headerline, /* line to check */
const char *content); /* content string to find */
/* ftp can use this as well */
-CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
- int tunnelsocket,
- char *hostname, int remote_port);
+CURLcode Curl_proxyCONNECT(struct connectdata *conn,
+ int tunnelsocket,
+ char *hostname, int remote_port);
/* protocol-specific functions set up to be called by the main engine */
CURLcode Curl_http(struct connectdata *conn, bool *done);