All of lore.kernel.org
 help / color / mirror / Atom feed
From: John Snow <jsnow@redhat.com>
To: Boris Schrijver <boris@pcextreme.nl>,
	qemu-devel@nongnu.org, kwolf@redhat.com, jcody@redhat.com,
	qemu-block@nongnu.org
Cc: Wido Hollander <wido@pcextreme.nl>
Subject: Re: [Qemu-devel] [Qemu-block] [PATCH] qemu-img / curl: When fetching Content-Size use GET instead of HEAD.
Date: Thu, 10 Dec 2015 16:26:07 -0500	[thread overview]
Message-ID: <5669EDEF.5010501@redhat.com> (raw)
In-Reply-To: <757302946.4200.de5ac8a5-69d1-4f59-9540-4a679771a547.open-xchange@ox.pcextreme.nl>



On 12/08/2015 03:49 PM, Boris Schrijver wrote:
> See inline! Thanks for your response!
> 
> -- 
> 
> Met vriendelijke groet / Kind regards,
> 
> Boris Schrijver
> 
> PCextreme B.V.
> 
> http://www.pcextreme.nl/contact
> Tel direct: +31 (0) 118 700 215
> 
>> On December 8, 2015 at 8:40 PM John Snow <jsnow@redhat.com> wrote:
>>
>>
>>
>>
>> On 12/07/2015 04:23 PM, Boris Schrijver wrote:
>>> Hi all,
>>>
>>
>> Hi!
>>
>>> I was testing out the "qemu-img info/convert" options in combination with
>>> "http/https" when I stumbled upon this issue. When "qemu-img info/convert"
>>> tries
>>> to collect the file info it will first try to fetch the Content-Size of the
>>> remote file. It does a HEAD request and after a GET request for the correct
>>> range.
>>>
>>> The HEAD request is an issue. Because when you've got a pre-signed url, for
>>> example from S3, which INCLUDES the REQUEST METHOD in it's signature, you'll
>>> get
>>> a 403 Forbidden.
>>>
>>> It's is therefore better to use only the GET request method, and discard the
>>> body at the first call.
>>>
>>
>> How big is the body? Won't this introduce a really large overhead?
> 
> The body is "worst-case" the size of the Ethernet v2 frame, around 1500 bytes.
> 
>>
>>> Please review! I'll be ready for answers!
>>>
>>
>> Please use the git format-patch format for sending patch emails; see
>> http://qemu-project.org/Contribute/SubmitAPatch#Use_git_format-patch --
>> and remember to include a Signed-off-by line.
>>
> 
> Ok, will do!
> 
>>> [PATCH] qemu-img / curl: When fetching Content-Size use GET instead of HEAD.
>>>
>>> A server can respond different to both methods, or can block one of the two.
>>> ---
>>>  block/curl.c | 4 ++--
>>>  1 file changed, 2 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/block/curl.c b/block/curl.c
>>> index 8994182..2e74c32 100644
>>> --- a/block/curl.c
>>> +++ b/block/curl.c
>>> @@ -594,11 +594,11 @@ static int curl_open(BlockDriverState *bs, QDict
>>> *options,
>>> int flags,
>>>      // Get file size
>>>  
>>>      s->accept_range = false;
>>> -    curl_easy_setopt(state->curl, CURLOPT_NOBODY, 1);
>>> +    curl_easy_setopt(state->curl, CURLOPT_HTTPGET, 1);
>>>      curl_easy_setopt(state->curl, CURLOPT_HEADERFUNCTION,
>>>                       curl_header_cb);
>>>      curl_easy_setopt(state->curl, CURLOPT_HEADERDATA, s);
>>> -    if (curl_easy_perform(state->curl))
>>> +    if (curl_easy_perform(state->curl) != 23)
>>
>> We go from making sure there were no errors to enforcing that we *do*
>> get CURLE_WRITE_ERROR? Can you explain why this change doesn't break
>> error handling scenarios for all other cases?
>>
> 
> We're enforcing the CURLE_WRITE_ERROR here. We receive data, but don't want to
> save it anywhere -> We only want the header. CURLE_WRITE_ERROR implicitly means
> the connection is successful, because we received a response body! Any other
> error will not be CURLE_WRITE_ERROR and thus fail.
> 
> Please run the following command: curl -v -X GET -I http://qemu.org/
> It will at the last line read:
> 
> * Excess found in a non pipelined read: excess = 279 url = / (zero-length body)
> 
> That is the body we're discarding.
> 
> Libcurl basically doesn't provide a nice way to handle this. That's why I've
> implemented in this fashion.
> 
> 

Hm... I suppose this works, though it leaves a slightly bad taste in my
mouth. Can you replace 23 by a definition (CURLE_WRITE_ERROR?) and
include a little blurb about why this quirk works?

Please send the follow-up patch as a new thread, with a "v2" tag so
others (particularly Jeff Cody) can see it -- he might have a different
opinion here.

Thanks!
--js

>>>          goto out;
>>>      curl_easy_getinfo(state->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &d);
>>>      if (d)
>>>
> 
> [PATCH]
> 
> commit ec8d3ef01eaca9264d97e9ad757fe536e0dc037b
> Author: Boris Schrijver <boris@pcextreme.nl>
> Date:   Mon Dec 7 22:01:59 2015 +0100
> 
>     qemu-img / curl: When fetching Content-Size use GET instead of HEAD.
>     
>     A server can respond different to both methods, or can block one of the two.
>     
>     Signed-off-by: Boris Schrijver <boris@pcextreme.nl>
> 
> diff --git a/block/curl.c b/block/curl.c
> index 8994182..2e74c32 100644
> --- a/block/curl.c
> +++ b/block/curl.c
> @@ -594,11 +594,11 @@ static int curl_open(BlockDriverState *bs, QDict *options,
> int flags,
>      // Get file size
>  
>      s->accept_range = false;
> -    curl_easy_setopt(state->curl, CURLOPT_NOBODY, 1);
> +    curl_easy_setopt(state->curl, CURLOPT_HTTPGET, 1);
>      curl_easy_setopt(state->curl, CURLOPT_HEADERFUNCTION,
>                       curl_header_cb);
>      curl_easy_setopt(state->curl, CURLOPT_HEADERDATA, s);
> -    if (curl_easy_perform(state->curl))
> +    if (curl_easy_perform(state->curl) != 23)
>          goto out;
>      curl_easy_getinfo(state->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &d);
>      if (d)
> 

  reply	other threads:[~2015-12-10 21:26 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-07 21:23 [Qemu-devel] [PATCH] qemu-img / curl: When fetching Content-Size use GET instead of HEAD Boris Schrijver
2015-12-08 19:40 ` [Qemu-devel] [Qemu-block] " John Snow
2015-12-08 20:49   ` Boris Schrijver
2015-12-10 21:26     ` John Snow [this message]
2015-12-10 21:29       ` Boris Schrijver
2015-12-08 19:56 ` [Qemu-devel] " Michael Tokarev
2015-12-08 20:39   ` Boris Schrijver
2015-12-09 22:37   ` [Qemu-devel] [PATCH v2] " Boris Schrijver
2015-12-10 22:21     ` [Qemu-devel] [Qemu-block] " John Snow

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5669EDEF.5010501@redhat.com \
    --to=jsnow@redhat.com \
    --cc=boris@pcextreme.nl \
    --cc=jcody@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=wido@pcextreme.nl \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.