aboutsummaryrefslogtreecommitdiff
path: root/lib/http.c
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2005-05-11 09:52:59 +0000
committerDaniel Stenberg <daniel@haxx.se>2005-05-11 09:52:59 +0000
commit5d9fc28fa760e1b0b7f68fce7ae845f4e659e0fd (patch)
tree776211f61e9bf552fe8158d0ec8b1c4abc3035c5 /lib/http.c
parente5ec5c284fa47fa7c001c2971a810a7f0305ca56 (diff)
Modified the default HTTP headers used by libcurl:
A) Normal non-proxy HTTP: - no more "Pragma: no-cache" (this only makes sense to proxies) B) Non-CONNECT HTTP request over proxy: - "Pragma: no-cache" is used (like before) - "Proxy-Connection: Keep-alive" (for older style 1.0-proxies) C) CONNECT HTTP request over proxy: - "Host: [name]:[port]" - "Proxy-Connection: Keep-alive"
Diffstat (limited to 'lib/http.c')
-rw-r--r--lib/http.c209
1 files changed, 143 insertions, 66 deletions
diff --git a/lib/http.c b/lib/http.c
index f61ce42c4..84f357a9c 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -811,6 +811,8 @@ struct send_buffer {
};
typedef struct send_buffer send_buffer;
+static CURLcode add_custom_headers(struct connectdata *conn,
+ send_buffer *req_buffer);
static CURLcode
add_buffer(send_buffer *in, const void *inptr, size_t size);
@@ -885,34 +887,47 @@ CURLcode add_buffer_send(send_buffer *in,
*bytes_written += amount;
- if((size_t)amount != size) {
- /* The whole request could not be sent in one system call. We must queue
- it up and send it later when we get the chance. We must not loop here
- and wait until it might work again. */
+ if(http) {
+ if((size_t)amount != size) {
+ /* The whole request could not be sent in one system call. We must
+ queue it up and send it later when we get the chance. We must not
+ loop here and wait until it might work again. */
- size -= amount;
+ size -= amount;
- ptr = in->buffer + amount;
+ ptr = in->buffer + amount;
- /* backup the currently set pointers */
- http->backup.fread = conn->fread;
- http->backup.fread_in = conn->fread_in;
- http->backup.postdata = http->postdata;
- http->backup.postsize = http->postsize;
+ /* backup the currently set pointers */
+ http->backup.fread = conn->fread;
+ http->backup.fread_in = conn->fread_in;
+ http->backup.postdata = http->postdata;
+ http->backup.postsize = http->postsize;
- /* set the new pointers for the request-sending */
- conn->fread = (curl_read_callback)readmoredata;
- conn->fread_in = (void *)conn;
- http->postdata = ptr;
- http->postsize = (curl_off_t)size;
+ /* set the new pointers for the request-sending */
+ conn->fread = (curl_read_callback)readmoredata;
+ conn->fread_in = (void *)conn;
+ http->postdata = ptr;
+ http->postsize = (curl_off_t)size;
- http->send_buffer = in;
- http->sending = HTTPSEND_REQUEST;
+ http->send_buffer = in;
+ http->sending = HTTPSEND_REQUEST;
- return CURLE_OK;
+ return CURLE_OK;
+ }
+ http->sending = HTTPSEND_BODY;
+ /* the full buffer was sent, clean up and return */
+ }
+ else {
+ if((size_t)amount != size)
+ /* We have no continue-send mechanism now, fail. This can only happen
+ when this function is used from the CONNECT sending function. We
+ currently (stupidly) assume that the whole request is always sent
+ away in the first single chunk.
+
+ This needs FIXing.
+ */
+ return CURLE_SEND_ERROR;
}
- http->sending = HTTPSEND_BODY;
- /* the full buffer was sent, clean up and return */
}
if(in->buffer)
free(in->buffer);
@@ -1038,9 +1053,15 @@ 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.
+ * 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.
+ *
+ * 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
+ * function only remains here like this for now since the rewrite is a bit too
+ * much work to do at the moment.
*/
CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
@@ -1063,6 +1084,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
char *line_start;
char *host_port;
curl_socket_t tunnelsocket = conn->sock[sockindex];
+ send_buffer *req_buffer;
#define SELECT_OK 0
#define SELECT_ERROR 1
@@ -1080,26 +1102,66 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
conn->newurl = NULL;
}
+ /* initialize a dynamic send-buffer */
+ req_buffer = add_buffer_init();
+
+ if(!req_buffer)
+ return CURLE_OUT_OF_MEMORY;
+
host_port = aprintf("%s:%d", hostname, remote_port);
if(!host_port)
return CURLE_OUT_OF_MEMORY;
/* Setup the proxy-authorization header, if any */
result = Curl_http_output_auth(conn, (char *)"CONNECT", host_port, TRUE);
+
if(CURLE_OK == result) {
+ char *host=(char *)"";
+ const char *proxyconn="";
+ char *ptr;
+
+ ptr = checkheaders(data, "Host:");
+ if(!ptr) {
+ host = aprintf("Host: %s\r\n", host_port);
+ if(!host)
+ result = CURLE_OUT_OF_MEMORY;
+ }
+ ptr = checkheaders(data, "Proxy-Connection:");
+ if(!ptr)
+ proxyconn = "Proxy-Connection: Keep-Alive\r\n";
- /* OK, now send the connect request to the proxy */
- result =
- Curl_sendf(tunnelsocket, conn,
- "CONNECT %s:%d HTTP/1.0\015\012"
- "%s"
- "%s"
- "\r\n",
- hostname, remote_port,
- conn->allocptr.proxyuserpwd?
- conn->allocptr.proxyuserpwd:"",
- data->set.useragent?conn->allocptr.uagent:""
- );
+ if(CURLE_OK == result) {
+ /* Send the connect request to the proxy */
+ /* BLOCKING */
+ result =
+ add_bufferf(req_buffer,
+ "CONNECT %s:%d HTTP/1.0\r\n"
+ "%s" /* Host: */
+ "%s" /* Proxy-Authorization */
+ "%s" /* User-Agent */
+ "%s", /* Proxy-Connection */
+ hostname, remote_port,
+ host,
+ conn->allocptr.proxyuserpwd?
+ conn->allocptr.proxyuserpwd:"",
+ data->set.useragent?conn->allocptr.uagent:"",
+ proxyconn);
+
+ if(CURLE_OK == result)
+ result = add_custom_headers(conn, req_buffer);
+
+ if(host && *host)
+ free(host);
+
+ if(CURLE_OK == result)
+ /* CRLF terminate the request */
+ result = add_bufferf(req_buffer, "\r\n");
+
+ if(CURLE_OK == result)
+ /* Now send off the request */
+ result = add_buffer_send(req_buffer, conn,
+ &data->info.request_size);
+ }
if(result)
failf(data, "Failed sending CONNECT to proxy");
}
@@ -1367,7 +1429,42 @@ static CURLcode expect100(struct SessionHandle *data,
return result;
}
+static CURLcode add_custom_headers(struct connectdata *conn,
+ send_buffer *req_buffer)
+{
+ CURLcode result = CURLE_OK;
+ char *ptr;
+ struct curl_slist *headers=conn->data->set.headers;
+
+ while(headers) {
+ ptr = strchr(headers->data, ':');
+ if(ptr) {
+ /* we require a colon for this to be a true header */
+
+ ptr++; /* pass the colon */
+ while(*ptr && isspace((int)*ptr))
+ ptr++;
+ if(*ptr) {
+ /* only send this if the contents was non-blank */
+
+ if(conn->allocptr.host &&
+ /* a Host: header was sent already, don't pass on any custom Host:
+ header as that will produce *two* in the same request! */
+ curl_strnequal("Host:", headers->data, 5))
+ ;
+ else {
+
+ result = add_bufferf(req_buffer, "%s\r\n", headers->data);
+ if(result)
+ return result;
+ }
+ }
+ }
+ headers = headers->next;
+ }
+ return result;
+}
/*
* Curl_http() gets called from the generic Curl_do() function when a HTTP
@@ -1620,8 +1717,10 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
}
- if(!checkheaders(data, "Pragma:"))
- http->p_pragma = "Pragma: no-cache\r\n";
+ http->p_pragma =
+ (!checkheaders(data, "Pragma:") &&
+ (conn->bits.httpproxy && !conn->bits.tunnel_proxy) )?
+ "Pragma: no-cache\r\n":NULL;
if(!checkheaders(data, "Accept:"))
http->p_accept = "Accept: */*\r\n";
@@ -1727,7 +1826,6 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
data->set.httpversion==CURL_HTTP_VERSION_1_0?"1.0":"1.1";
send_buffer *req_buffer;
- struct curl_slist *headers=data->set.headers;
curl_off_t postsize; /* off_t type to be able to hold a large file size */
/* initialize a dynamic send-buffer */
@@ -1750,6 +1848,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
"%s" /* accept */
"%s" /* accept-encoding */
"%s" /* referer */
+ "%s" /* Proxy-Connection */
"%s",/* transfer-encoding */
request,
@@ -1768,6 +1867,8 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
(data->set.encoding && *data->set.encoding && conn->allocptr.accept_encoding)?
conn->allocptr.accept_encoding:"",
(data->change.referer && conn->allocptr.ref)?conn->allocptr.ref:"" /* Referer: <data> */,
+ (conn->bits.httpproxy && !conn->bits.tunnel_proxy)?
+ "Proxy-Connection: Keep-Alive\r\n":"",
te
);
@@ -1874,33 +1975,9 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
return result;
}
- while(headers) {
- ptr = strchr(headers->data, ':');
- if(ptr) {
- /* we require a colon for this to be a true header */
-
- ptr++; /* pass the colon */
- while(*ptr && isspace((int)*ptr))
- ptr++;
-
- if(*ptr) {
- /* only send this if the contents was non-blank */
-
- if(conn->allocptr.host &&
- /* a Host: header was sent already, don't pass on any custom Host:
- header as that will produce *two* in the same request! */
- curl_strnequal("Host:", headers->data, 5))
- ;
- else {
-
- result = add_bufferf(req_buffer, "%s\r\n", headers->data);
- if(result)
- return result;
- }
- }
- }
- headers = headers->next;
- }
+ result = add_custom_headers(conn, req_buffer);
+ if(result)
+ return result;
http->postdata = NULL; /* nothing to post at this point */
Curl_pgrsSetUploadSize(data, 0); /* upload size is 0 atm */