I am using libcurl for a RESTful library. I am having two problems with a PUT message, I am just trying to send a small content like "hello" via put.
My READFUNCTION for PUT's blocks for a very large amount of time (minutes) when I follow the manual at curl.haxx.se and return a 0 indicating I have finished the content. (on os X) When I return something > 0 this succeeds much faster (< 1 sec)
When I run this on my linux machine (ubuntu 10.4) this blocking event appears to NEVER return when I return 0, if I change the behavior to return the size written libcurl appends all the data in the http body sending way more data and it fails with a "too much data" message from the server. my readfunction is below, any help would be greatly appreciated. I am using libcurl 7.20.1
typedef struct{
void *data;
int body_size;
int bytes_remaining;
int bytes_written;
} postdata;
size_t readfunc(void *ptr, size_t siz开发者_运维问答e, size_t nmemb, void *stream) {
if(stream) {
postdata *ud = (postdata*)stream;
if(ud->bytes_remaining) {
if(ud->body_size > size*nmemb) {
memcpy(ptr, ud->data+ud->bytes_written, size*nmemb);
ud->bytes_written+=size+nmemb;
ud->bytes_remaining = ud->body_size-size*nmemb;
return size*nmemb;
} else {
memcpy(ptr, ud->data+ud->bytes_written, ud->bytes_remaining);
ud->bytes_remaining=0;
return 0;
}
}
from the manpage (man curl_easy_setopt):
CURLOPT_READFUNCTION
Function pointer that should match the following prototype: size_t function( void *ptr, size_t size, size_t nmemb, void *stream); This function gets called by libcurl as soon as
it needs to read data in order to send it to the peer. The data area pointed at by the pointer ptr may be filled with at most size multiplied with nmemb number of bytes. Your
function must return the actual number of bytes that you stored in that memory area. Returning 0 will signal end-of-file to the library and cause it to stop the current trans-
fer.
If you stop the current transfer by returning 0 "pre-maturely" (i.e before the server expected it, like when you've told you will upload N bytes and you upload less than N
bytes), you may experience that the server "hangs" waiting for the rest of the data that won't come.
The read callback may return CURL_READFUNC_ABORT to stop the current operation immediately, resulting in a CURLE_ABORTED_BY_CALLBACK error code from the transfer (Added in
7.12.1)
If you set the callback pointer to NULL, or doesn't set it at all, the default internal read function will be used. It is simply doing an fread() on the FILE * stream set with
CURLOPT_READDATA.
so return CURL_READFUNC_ABORT to stop the operation
typedef struct{
void *data;
int body_size;
int bytes_remaining;
int bytes_written;
} postdata;
size_t readfunc(void *ptr, size_t size, size_t nmemb, void *stream) {
if(stream) {
postdata *ud = (postdata*)stream;
if(ud->bytes_remaining) {
if(ud->bytes_remaining > size*nmemb) {
memcpy(ptr, ud->data+ud->bytes_written, size*nmemb);
ud->bytes_written+=size+nmemb;
ud->bytes_remaining -= size*nmemb;
return size*nmemb;
} else {
memcpy(ptr, ud->data+ud->bytes_written, ud->bytes_remaining);
ud->bytes_remaining=0;
return 0;
}
}
I think it's more reasonable
精彩评论