cURL / Mailing Lists / curl-library / Single Mail


Re: Read and write on the same cURL handle

From: Richard W.M. Jones <>
Date: Thu, 26 Jun 2014 14:50:57 +0100

On Thu, Jun 26, 2014 at 05:08:22AM +0200, Daniel Stenberg wrote:
> On Mon, 23 Jun 2014, Richard W.M. Jones wrote:
> (had to handicraft the reply due to unimportant stuff, so this reply
> may not be threaded as nicely as it should've been)
> >On Mon, Jun 23, 2014 at 10:44:17AM +0100, Richard W.M. Jones wrote:
> >>Can a single cURL handle be "switched" between reading and uploading?
> >>And if so, how do you do that?
> >>
> >>Or should the plugin open two handles (one for reading, one for
> >>writing)?
> >
> >Or a third option: Should the plugin open a new cURL handle for every
> >request?
> >
> >Or a fourth: Keep open a collection of cURL handles? (And if so, what
> >policy to use to decide when to open a new handle or close an old one?)
> >
> >Note that NBD pread & pwrite requests are generally quite small,
> >frequent, and of course unpredictable in both size, frequency and
> >order.
> A curl handle can be re-used for any amount of requests so a read
> (download) request can very well be followed by a write (upload)
> request. But they are then two subsequent requests and you can't
> just switch at will at a random point in time.

Sorry, I'm confused by this paragraph. The sentences seem
contradictory. I can or I cannot switch between download and upload
on the same handle?

Maybe the confusion is that I'm using the "easy" API, and in each call
I'm using curl_easy_perform in a loop until the read or write is
finished. See:

> As I don't really know what you'd use the writing and reading for, I
> don't think I can advice very good here.

Basically the plugin gets pread() and pwrite() calls from an NBD
client. The client can make these calls in any order, with any size
and offset. They are serialized -- calls do not happen at the same
time from different threads.

For example, this could be a pattern of calls that we have to deal
with, with each call happening serially and being completely finished
before the next call is handled, and everything happening in a single

  pread (offset=0, count=512)
  pread (offset=512, count=1024)
  pwrite (offset=0, count=512)
  pread (offset=1024, count=512)
  pwrite (offset=0, count=512)
  pwrite (offset=1024, count=512)
  pread (offset=512, count=2048)

The question is, how best to turn that lot into cURL API requests?

Also what actual API calls do I need to use to switch the cURL handle
into download and upload modes (assuming this is allowed)?

My initial patch used this to switch to download mode:

  curl_easy_setopt (h->c, CURLOPT_NOBODY, 0);
  curl_easy_setopt (h->c, CURLOPT_HTTPGET, 1);

and this to switch to upload mode:

  curl_easy_setopt (h->c, CURLOPT_UPLOAD, 1);

Is that correct?



Richard Jones, Virtualization Group, Red Hat
Read my programming and virtualization blog:
virt-df lists disk usage of guests without needing to install any
software inside the virtual machine.  Supports Linux and Windows.
List admin:
Received on 2014-06-26