new Curl_ConnectHTTPProxyTunnel() function, needs a **lot** of testing!!!
This commit is contained in:
parent
c55d0bb804
commit
1affbff8f9
138
lib/http.c
138
lib/http.c
@ -204,28 +204,6 @@ CURLcode add_buffer(send_buffer *in, const void *inptr, size_t size)
|
|||||||
/* end of the add_buffer functions */
|
/* end of the add_buffer functions */
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/*
|
|
||||||
* Read everything until a newline.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static
|
|
||||||
int GetLine(int sockfd, char *ptr, struct connectdata *conn)
|
|
||||||
{
|
|
||||||
ssize_t nread;
|
|
||||||
|
|
||||||
/* get us a full line, terminated with a newline */
|
|
||||||
for(nread=0; (nread<BUFSIZE); nread++, ptr++) {
|
|
||||||
if((CURLE_OK != Curl_read(conn, sockfd, ptr, 1, &nread)) ||
|
|
||||||
(nread <= 0) || (*ptr == '\n'))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*ptr=0; /* zero terminate */
|
|
||||||
|
|
||||||
return nread>0?nread:0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function checks the linked list of custom HTTP headers for a particular
|
* This function checks the linked list of custom HTTP headers for a particular
|
||||||
* header (prefix).
|
* header (prefix).
|
||||||
@ -258,6 +236,22 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
|
|||||||
struct SessionHandle *data=conn->data;
|
struct SessionHandle *data=conn->data;
|
||||||
CURLcode result;
|
CURLcode result;
|
||||||
|
|
||||||
|
int nread; /* total size read */
|
||||||
|
int perline; /* count bytes per line */
|
||||||
|
bool keepon=TRUE;
|
||||||
|
ssize_t gotbytes;
|
||||||
|
char *ptr;
|
||||||
|
int timeout = 3600; /* default timeout in seconds */
|
||||||
|
struct timeval interval;
|
||||||
|
fd_set rkeepfd;
|
||||||
|
fd_set readfd;
|
||||||
|
char *line_start;
|
||||||
|
|
||||||
|
#define SELECT_OK 0
|
||||||
|
#define SELECT_ERROR 1
|
||||||
|
#define SELECT_TIMEOUT 2
|
||||||
|
int error = SELECT_OK;
|
||||||
|
|
||||||
infof(data, "Establish HTTP proxy tunnel to %s:%d\n", hostname, remote_port);
|
infof(data, "Establish HTTP proxy tunnel to %s:%d\n", hostname, remote_port);
|
||||||
|
|
||||||
/* OK, now send the connect request to the proxy */
|
/* OK, now send the connect request to the proxy */
|
||||||
@ -276,19 +270,105 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* wait for the proxy to send us a HTTP/1.0 200 OK header */
|
/* Now, read the full reply we get from the proxy */
|
||||||
while(GetLine(tunnelsocket, data->state.buffer, conn)) {
|
|
||||||
if('\r' == data->state.buffer[0])
|
|
||||||
break; /* end of headers */
|
|
||||||
if(data->set.verbose)
|
|
||||||
fprintf(data->set.err, "< %s\n", data->state.buffer);
|
|
||||||
|
|
||||||
if(2 == sscanf(data->state.buffer, "HTTP/1.%d %d",
|
|
||||||
|
if(data->set.timeout) {
|
||||||
|
/* if timeout is requested, find out how much remaining time we have */
|
||||||
|
timeout = data->set.timeout - /* timeout time */
|
||||||
|
Curl_tvdiff(Curl_tvnow(), conn->now)/1000; /* spent time */
|
||||||
|
if(timeout <=0 ) {
|
||||||
|
failf(data, "Transfer aborted due to timeout");
|
||||||
|
return -SELECT_TIMEOUT; /* already too little time */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FD_ZERO (&readfd); /* clear it */
|
||||||
|
FD_SET (tunnelsocket, &readfd); /* read socket */
|
||||||
|
|
||||||
|
/* get this in a backup variable to be able to restore it on each lap in the
|
||||||
|
select() loop */
|
||||||
|
rkeepfd = readfd;
|
||||||
|
|
||||||
|
ptr=data->state.buffer;
|
||||||
|
line_start = ptr;
|
||||||
|
|
||||||
|
nread=0;
|
||||||
|
perline=0;
|
||||||
|
keepon=TRUE;
|
||||||
|
|
||||||
|
while((nread<BUFSIZE) && (keepon && !error)) {
|
||||||
|
readfd = rkeepfd; /* set every lap */
|
||||||
|
interval.tv_sec = timeout;
|
||||||
|
interval.tv_usec = 0;
|
||||||
|
|
||||||
|
switch (select (tunnelsocket+1, &readfd, NULL, NULL, &interval)) {
|
||||||
|
case -1: /* select() error, stop reading */
|
||||||
|
error = SELECT_ERROR;
|
||||||
|
failf(data, "Transfer aborted due to select() error");
|
||||||
|
break;
|
||||||
|
case 0: /* timeout */
|
||||||
|
error = SELECT_TIMEOUT;
|
||||||
|
failf(data, "Transfer aborted due to timeout");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/*
|
||||||
|
* This code previously didn't use the kerberos sec_read() code
|
||||||
|
* to read, but when we use Curl_read() it may do so. Do confirm
|
||||||
|
* that this is still ok and then remove this comment!
|
||||||
|
*/
|
||||||
|
if(CURLE_OK != Curl_read(conn, tunnelsocket, ptr, BUFSIZE-nread,
|
||||||
|
&gotbytes))
|
||||||
|
keepon = FALSE;
|
||||||
|
else if(gotbytes <= 0) {
|
||||||
|
keepon = FALSE;
|
||||||
|
error = SELECT_ERROR;
|
||||||
|
failf(data, "Connection aborted");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* we got a whole chunk of data, which can be anything from one
|
||||||
|
* byte to a set of lines and possibly just a piece of the last
|
||||||
|
* line */
|
||||||
|
int i;
|
||||||
|
|
||||||
|
nread += gotbytes;
|
||||||
|
for(i = 0; i < gotbytes; ptr++, i++) {
|
||||||
|
perline++; /* amount of bytes in this line so far */
|
||||||
|
if(*ptr=='\n') {
|
||||||
|
/* a newline is CRLF in ftp-talk, so the CR is ignored as
|
||||||
|
the line isn't really terminated until the LF comes */
|
||||||
|
|
||||||
|
/* output debug output if that is requested */
|
||||||
|
if(data->set.verbose) {
|
||||||
|
fputs("< ", data->set.err);
|
||||||
|
fwrite(line_start, perline, 1, data->set.err);
|
||||||
|
/* no need to output LF here, it is part of the data */
|
||||||
|
}
|
||||||
|
|
||||||
|
if('\r' == line_start[0]) {
|
||||||
|
/* end of headers */
|
||||||
|
keepon=FALSE;
|
||||||
|
break; /* breaks out of loop, not switch */
|
||||||
|
}
|
||||||
|
|
||||||
|
if(2 == sscanf(line_start, "HTTP/1.%d %d",
|
||||||
&subversion,
|
&subversion,
|
||||||
&httperror)) {
|
&httperror)) {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
perline=0; /* line starts over here */
|
||||||
|
line_start = ptr+1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} /* switch */
|
||||||
|
} /* while there's buffer left and loop is requested */
|
||||||
|
|
||||||
|
if(error)
|
||||||
|
return CURLE_READ_ERROR;
|
||||||
|
|
||||||
if(200 != httperror) {
|
if(200 != httperror) {
|
||||||
if(407 == httperror)
|
if(407 == httperror)
|
||||||
/* Added Nov 6 1998 */
|
/* Added Nov 6 1998 */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user