cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: Problem with CURLOPT_RESUME_FROM and CURLOPT_APPEND

From: Daniele Pianu <muogoro_at_gmail.com>
Date: Thu, 28 Aug 2008 10:47:22 +0200

Here my simple test program code:

/*
  Simple test to check the problem described at
  http://curl.haxx.se/mail/lib-2008-08/0426.html

  Curl version: 7.18.2

  Tested in a linux x86_64 Fedora 8 machine.

  Run like this:
  ./curl_ftp ftp://my_ftp_server_address/pub/foo.txt

 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>

#define SEND_ME "Send me!!!"
#define SEND_ME_AGAIN "Send me again!!!"

/* buffer_t structure: store information about data and size-offset of data */
typedef struct buffer_t{

  void *data;
  size_t offset;
  size_t size;

} buffer_t;

size_t read_callback( void *ptr, size_t size, size_t nmemb, void *data ){

  buffer_t *buffer = (buffer_t*)data;
  size_t nBytes = size * nmemb;
  size_t toReadBytes = 0;
  size_t remainBuffBytes = buffer->size - buffer->offset;

  if ( buffer->offset < buffer->size ){

    toReadBytes = ( nBytes < remainBuffBytes ) ? nBytes : remainBuffBytes;
    memcpy( ptr, (char*)buffer->data + buffer->offset, toReadBytes );

    /* Update buffer offset */
    buffer->offset += toReadBytes;
    return toReadBytes;

  }

  return 0;
}

/* Avoid seeks inside the buffer data */
int noop_seek_callback( void *instream, curl_off_t offset, int origin ){

  /* Nothing to do */
  return 0;

}

int main( int argc, char *argv[] ){

  CURL *handle;
  buffer_t buffer;

  if( argc != 2){
    return 1;
  }

  /* Init Curl library */
  curl_global_init( CURL_GLOBAL_ALL );
  handle = curl_easy_init();

  /* Verbose mode */
  curl_easy_setopt( handle, CURLOPT_VERBOSE, 1L );

  /* Set URL */
  curl_easy_setopt( handle, CURLOPT_URL, argv[1] );

  /* Set Callbacks */
  curl_easy_setopt( handle, CURLOPT_READFUNCTION, read_callback );
  curl_easy_setopt( handle, CURLOPT_READDATA, &buffer );
  curl_easy_setopt( handle, CURLOPT_SEEKFUNCTION, noop_seek_callback );
  curl_easy_setopt( handle, CURLOPT_SEEKDATA, NULL );

  /* Set up buffer */
  buffer.data = SEND_ME;
  buffer.offset = 0;
  buffer.size = strlen( SEND_ME );

  /* Do first upload */
  curl_easy_setopt( handle, CURLOPT_UPLOAD, 1L );
  curl_easy_perform( handle );

  /* Set buffer again */
  buffer.data = SEND_ME_AGAIN;
  buffer.offset = 0;
  buffer.size = strlen( SEND_ME_AGAIN );

  /* Seek back to 4-th bytes
     ( I think it might be translated in a REST 4 ftp command ...) */
  curl_easy_setopt( handle, CURLOPT_RESUME_FROM, 4 );

  /* Do second upload.
   Here the error: the CURLOPT_RESUME_FROM is translated in an APPE ftp command
   and not in a REST command.*/
  curl_easy_perform( handle );

  /* Now my output file appear like this:

     Send me!!!Send me again!!!

     and not like this:

     SendSend me againg!!!

  */

  /* Cleanup Curl library */
  curl_easy_cleanup( handle );
  curl_global_cleanup();

  return 0;

}

No error check is done. The program simply uploads a first string,
then trys to upload a second string starting from the middle of the
firstly uploaded string.

Daniele

2008/8/27 Daniel Stenberg <daniel_at_haxx.se>
>
> On Wed, 27 Aug 2008, Daniele Pianu wrote:
>
>> seek ( and, so, resume) operations are ignored: if I enable verbose mode I see the every write operation is resolved to a APPEND command (except for the first write).
>
> Indeed, I consider this a bug. The code assumes resume == appending, which of course isn't necessarily the case.
>
> It'll help if you can provide a full source code to a (small) app that does this so that we can get onto debugging/fixing this faster.
>
> --
>
> / daniel.haxx.se
Received on 2008-08-28