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

Reply via email to