cURL / Mailing Lists / curl-library / Single Mail

curl-library

[PATCH] Addition of trailer headers in HTTP requests generated by libcurl

From: Chrysovaladis Datsios <cdatsios_at_gmail.com>
Date: Thu, 17 Jan 2013 14:35:12 +0200

Hi,
this is a patch for the feature request as described in
http://sourceforge.net/p/curl/feature-requests/67/
the feature is a standard in
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.40

One can also refer at Chris Shiflett's Book "HTTP: Developer's
Handbook" from SAMS page 97.
http://books.google.gr/books?isbn=0672324547

Example case: Chunked PUT request with Trailer headers.

PUT /myfile HTTP/1.1
Host: 10.8.60.209
Accept: /
Transfer-Encoding: chunked
Trailer: mytrailerheader
Expect: 100-continue

53
....first chunk of data......

53
.....second chunk of data.....

0
mytrailerheader: myvalue

----------------------------------
The feature is implemented as another in curl_easy_setopt() function.
This new option is named CURLOPT_HTTPTRAILERHEADER and adds the trailer headers
appended on a curl_slist.

Example code snippet using the new feature:

struct curl_slist *trailer_http_hdrs;
trailer_http_hdrs = curl_slist_append(trailer_http_hdrs,
"mytrailerheader: myvalue");
curl_easy_setopt(curl, CURLOPT_HTTPTRAILERHEADER, trailer_http_hdrs);

----------------------------------
This are the diffs from the original library: curl-7.28.1
I hope it makes it to be included in a future verson.

diff -ur curl_orig/include/curl/curl.h curl_new/include/curl/curl.h
--- curl_orig/include/curl/curl.h 2012-09-26 12:46:15.000000000 +0300
+++ curl_new/include/curl/curl.h 2013-01-17 12:31:24.000460704 +0200
@@ -1536,6 +1536,9 @@
   /* set the SMTP auth originator */
   CINIT(MAIL_AUTH, OBJECTPOINT, 217),

+ /* points to a linked list of trailer headers, struct curl_slist kind */
+ CINIT(HTTPTRAILERHEADER, OBJECTPOINT, 218),
+
   CURLOPT_LASTENTRY /* the last unused */
 } CURLoption;

diff -ur curl_orig/lib/http.c curl_new/lib/http.c
--- curl_orig/lib/http.c 2012-11-13 23:02:16.000000000 +0200
+++ curl_new/lib/http.c 2013-01-17 12:33:20.817372849 +0200
@@ -1524,6 +1524,9 @@
   char *ptr;
   struct curl_slist *headers=conn->data->set.headers;

+ char *tptr;
+ struct curl_slist *trailer_headers=conn->data->set.trailer_headers;
+
   while(headers) {
     ptr = strchr(headers->data, ':');
     if(ptr) {
@@ -1590,6 +1593,31 @@
     }
     headers = headers->next;
   }
+
+ while(trailer_headers) {
+ ptr = strchr(trailer_headers->data, ':');
+ if(ptr) {
+ tptr = --ptr; /* the point where the trailer header field ends */
+ ptr++; /* pass the colon */
+ while(*ptr && ISSPACE(*ptr))
+ ptr++;
+
+ if(*ptr) {
+ /* only send this if the contents was non-blank */
+
+ char tfield[CURL_MAX_HTTP_HEADER];
+ strncpy(tfield, trailer_headers->data, tptr-trailer_headers->data+1);
+ tfield[tptr-trailer_headers->data+1] = '\0';
+ CURLcode result = Curl_add_bufferf(req_buffer, "Trailer: %s\r\n",
+ tfield);
+ tptr = NULL;
+ if(result)
+ return result;
+ }
+ }
+ trailer_headers = trailer_headers->next;
+ }
+
   return CURLE_OK;
 }

diff -ur curl_orig/lib/transfer.c curl_new/lib/transfer.c
--- curl_orig/lib/transfer.c 2012-11-13 23:02:16.000000000 +0200
+++ curl_new/lib/transfer.c 2013-01-17 12:33:40.002719777 +0200
@@ -929,6 +929,34 @@
          that instead of reading more data */
     }

+ /* The last chunk has zero size of data i.e. 0\r\n*/
+ if(k->upload_chunky == true && data->req.upload_present == 5 &&
+ !strncmp(data->req.upload_fromhere, "0\r\n", 3) ) {
+
+ Curl_send_buffer *trailer_buffer = Curl_add_buffer_init();
+ result = Curl_add_bufferf(trailer_buffer, "0\r\n");
+ if(result)
+ return result;
+
+ char *ptr;
+ struct curl_slist *trailer_headers=conn->data->set.trailer_headers;
+ while(trailer_headers) {
+ ptr = strchr(trailer_headers->data, ':');
+ if(ptr) {
+ result = Curl_add_bufferf(trailer_buffer, "%s\r\n",
+ trailer_headers->data);
+ if(result)
+ return result;
+ }
+ trailer_headers = trailer_headers->next;
+ }
+ result = Curl_add_bufferf(trailer_buffer, "\r\n");
+ if(result)
+ return result;
+ data->req.upload_fromhere = trailer_buffer->buffer;
+ data->req.upload_present = trailer_buffer->size_used;
+ }
+
     /* write to socket (send away data) */
     result = Curl_write(conn,
                         conn->writesockfd, /* socket to send to */
diff -ur curl_orig/lib/url.c curl_new/lib/url.c
--- curl_orig/lib/url.c 2012-11-18 16:08:45.000000000 +0200
+++ curl_new/lib/url.c 2013-01-17 12:32:59.583027669 +0200
@@ -1261,6 +1261,13 @@
     data->set.headers = va_arg(param, struct curl_slist *);
     break;

+ case CURLOPT_HTTPTRAILERHEADER:
+ /*
+ * Set a list with HTTP trailer headers to use
+ */
+ data->set.trailer_headers = va_arg(param, struct curl_slist *);
+ break;
+
   case CURLOPT_HTTP200ALIASES:
     /*
      * Set a list of aliases for HTTP 200 in response header
diff -ur curl_orig/lib/urldata.h curl_new/lib/urldata.h
--- curl_orig/lib/urldata.h 2012-11-13 23:02:16.000000000 +0200
+++ curl_new/lib/urldata.h 2013-01-17 12:33:07.634950493 +0200
@@ -1466,6 +1466,7 @@
                                 download */
   curl_off_t set_resume_from; /* continue [ftp] transfer from here */
   struct curl_slist *headers; /* linked list of extra headers */
+ struct curl_slist *trailer_headers; /* linked list of trailer headers */
   struct curl_httppost *httppost; /* linked list of POST data */
   bool cookiesession; /* new cookie session? */
   bool crlf; /* convert crlf on ftp upload(?) */
diff -ur curl_orig/src/tool_cfgable.h curl_new/src/tool_cfgable.h
--- curl_orig/src/tool_cfgable.h 2012-08-08 23:45:18.000000000 +0300
+++ curl_new/src/tool_cfgable.h 2013-01-17 12:32:19.411456442 +0200
@@ -150,6 +150,7 @@
   curl_TimeCond timecond;
   time_t condtime;
   struct curl_slist *headers;
+ struct curl_slist *trailer_headers;
   struct curl_httppost *httppost;
   struct curl_httppost *last_post;
   struct curl_slist *telnet_options;
diff -ur curl_orig/src/tool_operate.c curl_new/src/tool_operate.c
--- curl_orig/src/tool_operate.c 2012-11-13 23:02:16.000000000 +0200
+++ curl_new/src/tool_operate.c 2013-01-17 12:32:35.467278692 +0200
@@ -978,6 +978,7 @@
           my_setopt(curl, CURLOPT_AUTOREFERER, config->autoreferer);
           my_setopt_str(curl, CURLOPT_USERAGENT, config->useragent);
           my_setopt_slist(curl, CURLOPT_HTTPHEADER, config->headers);
+ my_setopt_slist(curl, CURLOPT_HTTPTRAILERHEADER, config->headers);

           /* new in libcurl 7.5 */
           my_setopt(curl, CURLOPT_MAXREDIRS, config->maxredirs);
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2013-01-17