curl-library
Re: [PATCH] Addition of trailer headers in HTTP requests generated by libcurl
Date: Thu, 21 Feb 2013 10:23:46 +0200
Hi,
I'm sending you a new version of the patch. It is attached.
> 0 - you didn't really follow our code style when it comes to indenting. A
> minor nit, but still...
I tried to keep it, but the mail formater wash it off :)
>
> 1 - Can you think of a good reason why the callback would need to get the
> struct curl_slist * as its second argument? Won't that always just be
> NULL?
No. Now it is removed.
>
> 2 - since the trailer headers now are set by a return code from a callback,
> I don't think they should be part of the 'struct UserDefined' anymore.
> In fact, is there a point to have it stored within the SessionHandle
> struct at all?
I moved it at the connectdata struct.
>
> 3 - the memcpy() functions invoked after the callback has returned its list
> of headers are not checking that the destination is big enough. It
> uses the data set by the callback which risk overflowing the upload
> buffer...
You're right, now I allocate specific space for the list of headers
>
> 4 - I asked you before, but why is_trailerheaders_set? You can just as well
> save 5 lines of code and some memory by checking 'trailerheaders_func'
> instead!
Removed it.
>
> 5 - you modified a file in src/ without purpose.
Removed. Sorry for the dead code.
Following are a small documentation & an example code using it.
+------------------------------+
| documentation |
+------------------------------+
curl_easy_setopt() option: CURLOPT_TRAILERFUNCTION
Pass a pointer to a function that matches the following prototype:
struct curl_slist* function(CURL *handle, void *userdata); This
function gets called by libcurl when it is to send the last chunk of
(zero payload)data to the peer. Chunked transfer-encoding must be
used. The trailer header names have to be set in advance as custom
headers using the CURLOPT_HTTPHEADER option with "Trailer" as "header
name_field" and the actual header name as "header value_field". Inside
the callback function a linked list of type struct curl_slist that
will contain the trailer headers have to be created using the
curl_slist_append(3) function. The callback function returns a pointer
to the trailer_headers list. The user also can pass in a custom
pointer to the callback, this is done by the associated
CURLOPT_TRAILERDATA option.
curl_easy_setopt() option: CURLOPT_TRAILERDATA
Data pointer to pass to the trailer function. If you use the
CURLOPT_TRAILERFUNCTION option, this is the pointer you'll get as
input.
+----------------------------------------------+
| code example: |
| PUT request with trailer header |
+----------------------------------------------+
#include <stdio.h>
#include <curl/curl.h>
#include <sys/stat.h>
#include <fcntl.h>
/* trailer header setting callback function */
struct curl_slist * trailerheader_callback(CURL *handle, void *userdata) {
int *code = (int *)userdata;
struct curl_slist *trailer_headers;
if(!(*code))
trailer_headers = curl_slist_append(trailer_headers, "mytrailer: EOF");
else
trailer_headers = curl_slist_append(trailer_headers, "mytrailer: error");
return trailer_headers;
}
int main(void)
{
CURL *curl;
CURLcode res;
int filecode;
FILE *fd;
struct curl_slist *custom_http_hdrs=NULL;
fd = fopen("video_0000", "rb"); /* open file to upload */
if(!fd) {
return 1; /* can't continue */
}
/* Read callback function */
size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream) {
size_t retcode;
retcode = fread(ptr, size, nmemb, stream);
if(!retcode) {
if(ferror(stream))
filecode = 1;
if(feof(stream))
filecode = 0;
}
return retcode;
}
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "http://10.8.60.209/myfile");
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
curl_easy_setopt(curl, CURLOPT_READDATA, fd);
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
custom_http_hdrs = curl_slist_append(custom_http_hdrs,
"Transfer-Encoding: chunked");
custom_http_hdrs = curl_slist_append(custom_http_hdrs, "Trailer:
mytrailer");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, custom_http_hdrs);
curl_easy_setopt(curl, CURLOPT_TRAILERFUNCTION, trailerheader_callback);
curl_easy_setopt(curl, CURLOPT_TRAILERDATA, &filecode);
res = curl_easy_perform(curl);
if(res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
}
fclose(fd);
curl_slist_free_all(custom_http_hdrs);
curl_easy_cleanup(curl);
}
return 0;
}
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
- application/octet-stream attachment: CURLOPT_TRAILERFUNCTION-support-chunked-encoding-req.diff