Project

General

Profile

Bug #897

RGW does not send content-length for HEAD requests sometimes

Added by Colin McCabe over 8 years ago. Updated over 8 years ago.

Status:
Resolved
Priority:
Normal
Assignee:
Category:
-
Target version:
% Done:

0%

Source:
Tags:
Backport:
Regression:
No
Severity:
3 - minor
Reviewed:
Affected Versions:
ceph-qa-suite:
Pull request ID:
Crash signature:

Description

RGW does not send content-length for HEAD requests when content-length would be 0. This breaks libboto:

cmccabe@metropolis:~/src/ceph/src/osync$  ./osync.py -v file:///tmp/a s3://rgw-1.ceph.dreamhost.com/test-bucket/ 
obj.name = a2
Traceback (most recent call last):
  File "./osync.py", line 324, in <module>
    dobj = dst.locate_object(sobj)
  File "./osync.py", line 172, in locate_object
    k = self.bucket.get_key(obj.name)
  File "/usr/lib/pymodules/python2.6/boto/s3/bucket.py", line 130, in get_key
    k.size = int(response.getheader('content-length'))
TypeError: int() argument must be a string or a number, not 'NoneType'

Examination with wireshark reveals that the content-length header is missing on RGW's response.

We can patch libboto, of course, but I suspect that this kind of behavior will break a lot of other ad-hoc clients that people have written over the years.

Apparently not sending content-length when it is 0 is considered a feature by the apache guys and is not going away:
http://marc.theaimsgroup.com/?l=apache-modperl&m=108647669726915&w=2
http://marc.theaimsgroup.com/?t=109122984600001&r=1&w=2

There are some hints that there may be a workaround for CGI clients.
From http://perl.apache.org/docs/2.0/user/handlers/http.html#C_Content_Length__Response_Header

> Not getting Content-Length header with HEAD requests
> Even though the spec says that content handlers should send an identical 
> response for GET and HEAD requests, some folks try to avoid the overhead 
> of generating the response body, which Apache is going to discard anyway 
> for HEAD requests. The following discussion assumes that we deal with a 
> HEAD request.
>
> When Apache sees EOS and no headers and no response body were sent, 
> ap_content_length_filter() (httpd-2.0/server/protocol.c) sets C-L to 0. 
> Later on ap_http_header_filter() (httpd-2.0/modules/http/http_protocol.c) 
> removes the C-L header for the HEAD requests.
> 
> The workaround is to force the sending of the response headers, before EOS 
> was sent (which happens when the response handler returns). The simplest 
> solution is to use rflush():

apache2-2.2.16-rgw-1.patch View (750 Bytes) Yehuda Sadeh, 03/18/2011 05:28 PM

History

#1 Updated by Yehuda Sadeh over 8 years ago

You're quoting the wrong symptom and the workaround stated here will not work:

> 
> The workaround is to force the sending of the response headers, before EOS 
> was sent (which happens when the response handler returns). The simplest 
> solution is to use rflush():

#2 Updated by Yehuda Sadeh over 8 years ago

That's the actual apache code that does it:

    /* This is a hack, but I can't find anyway around it.  The idea is that
     * we don't want to send out 0 Content-Lengths if it is a head request.
     * This happens when modules try to outsmart the server, and return
     * if they see a HEAD request.  Apache 1.3 handlers were supposed to
     * just return in that situation, and the core handled the HEAD.  In
     * 2.0, if a handler returns, then the core sends an EOS bucket down
     * the filter stack, and the content-length filter computes a C-L of
     * zero and that gets put in the headers, and we end up sending a
     * zero C-L to the client.  We can't just remove the C-L filter,
     * because well behaved 2.0 handlers will send their data down the stack,
     * and we will compute a real C-L for the head request. RBB
     */
    if (r->header_only
        && (clheader = apr_table_get(r->headers_out, "Content-Length"))
        && !strcmp(clheader, "0")) {
        apr_table_unset(r->headers_out, "Content-Length");
    }

#3 Updated by Colin McCabe over 8 years ago

I posted a patch to boto-dev which allows libboto to handle a missing content-length as a 0 content-length. We'll just have to see if they pick it up or not. Either way, though, I think we should resolve this eventually so that other clients don't break.

#5 Updated by Colin McCabe over 8 years ago

  • Assignee set to Yehuda Sadeh
  • Target version set to v0.25.2

#6 Updated by Yehuda Sadeh over 8 years ago

The attached patch fixes the issue. Also, Colin's patch got a positive review and will be merged into boto.

Also available in: Atom PDF