aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2001-11-12 09:47:09 +0000
committerDaniel Stenberg <daniel@haxx.se>2001-11-12 09:47:09 +0000
commit1affbff8f92b98ca01d42ff3b9a1606ef3b51c82 (patch)
tree7fc2a39da7358a801923607d99d2d4cc31f18858
parentc55d0bb80435aef2e06a34c006da410b47982d92 (diff)
new Curl_ConnectHTTPProxyTunnel() function, needs a **lot** of testing!!!
-rw-r--r--lib/http.c146
1 files changed, 113 insertions, 33 deletions
diff --git a/lib/http.c b/lib/http.c
index 9526e5188..2fe8e08dd 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -205,28 +205,6 @@ CURLcode add_buffer(send_buffer *in, const void *inptr, size_t size)
/* ------------------------------------------------------------------------- */
/*
- * 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
* header (prefix).
*/
@@ -258,6 +236,22 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
struct SessionHandle *data=conn->data;
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);
/* OK, now send the connect request to the proxy */
@@ -276,19 +270,105 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
return result;
}
- /* wait for the proxy to send us a HTTP/1.0 200 OK header */
- 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",
- &subversion,
- &httperror)) {
- ;
+ /* Now, read the full reply we get from the proxy */
+
+
+ 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,
+ &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(407 == httperror)
/* Added Nov 6 1998 */