Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rgw: Fix incorrect content length and range for zero sized objects during range requests #10207

Merged
merged 3 commits into from Aug 1, 2016

Conversation

prallabh
Copy link
Contributor

@prallabh prallabh commented Jul 8, 2016

Fixes: http://tracker.ceph.com/issues/16388

Signed-off-by: Pavan Rallabhandi PRallabhandi@walmartlabs.com

@prallabh
Copy link
Contributor Author

@yehudasa can you please help review

@prallabh
Copy link
Contributor Author

@cbodley, @oritwas can you please help review/assign as appropriate.

@oritwas oritwas self-assigned this Jul 14, 2016
@oritwas
Copy link
Member

oritwas commented Jul 14, 2016

This fixes the content-length header but the content-range is still not correct
I get with this fix for an empty object:
Content-Range: bytes 0--1/0

@prallabh
Copy link
Contributor Author

That's true, should the range be 0-0/0 as well?

@oritwas
Copy link
Member

oritwas commented Jul 14, 2016

it should be:
Content-Range: */0

@prallabh
Copy link
Contributor Author

I guess you meant that to be whatever user specifies as the range? Thinking through this, wouldn't any range be irrelevant for zero sized objects?

@oritwas
Copy link
Member

oritwas commented Jul 14, 2016

We need to respond with 416 (Range Not Satisfiable) and
Content-Range: */0

see http://httpwg.org/specs/rfc7233.html#status.416

@oritwas
Copy link
Member

oritwas commented Jul 15, 2016

@prallabh , Lets return 416 and remove the content-range header . I think this will be the simplest

@prallabh
Copy link
Contributor Author

@oritwas Thanks for the link, wasn't aware of it. Realized that we were returning 416 else where as well in the code, was in the process of building the content-range for this case. If we do not bother about the range header, will update the commit with just the content length and 416.

@prallabh
Copy link
Contributor Author

@oritwas I ended up fixing the range header as per the RFC, please take a look at the same.

@vsespb
Copy link

vsespb commented Jul 18, 2016

Here is what Amazon S3 gives (yes, 416):

$ curl -v -H "Range: bytes=0-5242880" https://s3-eu-west-1.amazonaws.com/vsetest/s3test
* About to connect() to s3-eu-west-1.amazonaws.com port 443 (#0)
*   Trying 54.231.131.83... connected
* successfully set certificate verify locations:
*   CAfile: none
  CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server key exchange (12):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using ECDHE-RSA-AES128-SHA
* Server certificate:
*    subject: C=US; ST=Washington; L=Seattle; O=Amazon.com Inc.; CN=*.s3-eu-west-1.amazonaws.com
*    start date: 2015-12-08 12:05:08 GMT
*    expire date: 2016-09-14 12:00:00 GMT
*    subjectAltName: s3-eu-west-1.amazonaws.com matched
*    issuer: C=US; O=DigiCert Inc; OU=www.digicert.com; CN=DigiCert Baltimore CA-2 G2
*    SSL certificate verify ok.
> GET /vsetest/s3test HTTP/1.1
> User-Agent: curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3
> Host: s3-eu-west-1.amazonaws.com
> Accept: */*
> Range: bytes=0-5242880
> 
< HTTP/1.1 416 Requested Range Not Satisfiable
< x-amz-request-id: EBA23471F0510B1A
< x-amz-id-2: RYTrIF6LmawFzMVTsRQd/5dqF3YRJ+8jof6WgXQ5EAr5oIkBorFcdOexrTqVnojpHHl1KMWkvZk=
< Content-Type: application/xml
< Transfer-Encoding: chunked
< Date: Mon, 18 Jul 2016 11:22:15 GMT
< Server: AmazonS3
< 
<?xml version="1.0" encoding="UTF-8"?>
* Connection #0 to host s3-eu-west-1.amazonaws.com left intact
* Closing connection #0
* SSLv3, TLS alert, Client hello (1):
<Error><Code>InvalidRange</Code><Message>The requested range is not satisfiable</Message><RangeRequested>bytes=0-5242880</RangeRequested><ActualObjectSize>0</ActualObjectSize><RequestId>EBA23471F0510B1A</RequestId><HostId>RYTrIF6LmawFzMVTsRQd/5dqF3YRJ+8jof6WgXQ5EAr5oIkBorFcdOexrTqVnojpHHl1KMWkvZk=</HostId></Error>

@vsespb
Copy link

vsespb commented Jul 18, 2016

I also wondering why you guys have travis "build", but don't write tests. Different condition-branch for handling zero is something tests designed for.

@tchaikov
Copy link
Contributor

tchaikov commented Jul 18, 2016

@vsespb we don't have travis build yet (but yes, we could). why do you say so?

@vsespb
Copy link

vsespb commented Jul 18, 2016

ok, jenkins, not travis.

@prallabh
Copy link
Contributor Author

@oritwas ping

@oritwas
Copy link
Member

oritwas commented Jul 20, 2016

lgtm, but it need more testing.
Can you add a test to s3tests for this?

@prallabh
Copy link
Contributor Author

Thanks, do you mean to add a test under https://github.com/ceph/s3-tests. Have never done that, any pointers/documentation around best practices for that would help.

@prallabh
Copy link
Contributor Author

prallabh commented Jul 22, 2016

@oritwas I have verified the fix with swift/s3 clients, can you please clarify on the test that you were referring to.

@oritwas
Copy link
Member

oritwas commented Jul 22, 2016

I add a test to s3 tests for an empty object see ceph/s3-tests#119

could you try it an see if it passes?

@prallabh
Copy link
Contributor Author

Thanks for the test, find below the result:

S3TEST_CONF=range.conf ./virtualenv/bin/nosetests s3tests.functional.test_s3:test_ranged_request_empty_object

.

Ran 1 test in 0.568s

OK

@prallabh
Copy link
Contributor Author

@oritwas rebased.

@prallabh
Copy link
Contributor Author

@oritwas ping

@prallabh
Copy link
Contributor Author

prallabh commented Jul 27, 2016

@oritwas Realized that having the object size check in the Read::prepare would break while preforming operations like stat/download on a empty object (without a hint that the operation is a range request). Moved the checks ahead to RGWGetObj::execute where they should really be IMO. Please take a look, thanks!

@oritwas
Copy link
Member

oritwas commented Jul 29, 2016

@prallabh can you rebase?

@prallabh
Copy link
Contributor Author

@oritwas done

@prallabh
Copy link
Contributor Author

prallabh commented Aug 1, 2016

@oritwas please let me know if there is anything pending from my side for merge.

@@ -655,7 +655,9 @@ void end_header(struct req_state* s, RGWOp* op, const char *content_type,
s->formatter->close_section();
}
s->formatter->output_footer();
dump_content_length(s, s->formatter->get_len());
if (s->obj_size) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to effect all error response and some require content-length. is it a problem to keep the content-length?

Copy link
Contributor Author

@prallabh prallabh Aug 1, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The content length here is that of the end header's and its not relevant in this context (I guess that should be true for all zero sized responses). For range requests on zero sized objects, without suppressing this header, the output looks something like this:

HTTP/1.1 416 Requested Range Not Satisfiable
Content-Range: bytes */0
Content-Length: 0
Accept-Ranges: bytes
X-Trans-Id: tx000000000000000000026-00579f3001-1011-default
Content-Length: 12
Accept-Ranges: bytes
Content-Type: text/plain; charset=utf-8
Date: Mon, 01 Aug 2016 11:18:25 GMT

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you have here two content lengths headers,
it is because you add the content length even in case of an error see my comment on rgw_rest_swift.cc

@oritwas
Copy link
Member

oritwas commented Aug 1, 2016

As both swift or AWS are not returning a content-range header in case of such error, we can do the same.
It will simplify the code just to return 416 error if the object is empty

@prallabh
Copy link
Contributor Author

prallabh commented Aug 1, 2016

@oritwas Thanks, can you please check now if that is what you are expecting.

dump_content_length(s, total_len);

Copy link
Member

@oritwas oritwas Aug 1, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

small nit : extra empty line
other wise looks good

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done, thanks!

root added 3 commits August 1, 2016 20:52
Signed-off-by: Pavan Rallabhandi <PRallabhandi@walmartlabs.com>
Signed-off-by: Pavan Rallabhandi <PRallabhandi@walmartlabs.com>
Signed-off-by: Pavan Rallabhandi <PRallabhandi@walmartlabs.com>
@prallabh
Copy link
Contributor Author

prallabh commented Aug 1, 2016

@oritwas updated and rebased, please help merge.

@oritwas
Copy link
Member

oritwas commented Aug 1, 2016

looks good

@cbodley cbodley merged commit 4a90e64 into ceph:master Aug 1, 2016
@prallabh prallabh deleted the wip-16388 branch August 17, 2016 05:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants