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

Handle get_object with range #21

Merged
merged 10 commits into from
Jun 16, 2015
Merged

Conversation

windkit
Copy link
Contributor

@windkit windkit commented Jun 8, 2015

About issue leo-project/leofs#376

Instead of using transfer-encoding:chunked, respond with HTTP 200 and resp_body_func
(Note: aws-java-jdk is case-sensitive to HTTP Headers... cowboy internally uses lower case which does not match)

Code is not polished at the moment, I have only tested with a short Java program

Also Unit test is broken at the moment because it checks against transfer-encoding:chunked

@yosukehara
Copy link
Member

Thank you for your contribution. I've merge this request with feature/fix-issue-376 branch.
I'll test issue-376 on feature/fix-issue-376.

@yosukehara
Copy link
Member

In addition, I found Leo Gateway could not pass the unit test as below:

leo_gateway_web_tests: range_object_base...*failed*
in function leo_gateway_web_tests:'-range_object_base/2-fun-0-'/2 (test/leo_gateway_web_tests.erl, line 663)
in call from leo_gateway_web_tests:'-range_object_base/2-fun-2-'/2 (test/leo_gateway_web_tests.erl, line 663)
**error:{assertEqual_failed,[{module,leo_gateway_web_tests},
                     {line,663},
                     {expression,"SC"},
                     {expected,206},
                     {value,200}]}


leo_gateway_web_tests: range_object_base...*failed*
in function leo_gateway_web_tests:'-range_object_base/2-fun-0-'/2 (test/leo_gateway_web_tests.erl, line 663)
in call from leo_gateway_web_tests:'-range_object_base/2-fun-2-'/2 (test/leo_gateway_web_tests.erl, line 663)
**error:{assertEqual_failed,[{module,leo_gateway_web_tests},
                     {line,663},
                     {expression,"SC"},
                     {expected,206},
                     {value,200}]}


leo_gateway_web_tests: range_object_base...*failed*
in function leo_gateway_web_tests:'-range_object_base/2-fun-0-'/2 (test/leo_gateway_web_tests.erl, line 663)
in call from leo_gateway_web_tests:'-range_object_base/2-fun-2-'/2 (test/leo_gateway_web_tests.erl, line 663)
**error:{assertEqual_failed,[{module,leo_gateway_web_tests},
                     {line,663},
                     {expression,"SC"},
                     {expected,206},
                     {value,200}]}


cwd:"/Users/yosuke.hara/dev/leo-project/leofs/deps/leo_gateway/.eunit\n"
src/leo_cache_server_dcerl.erl:82:<0.860.0>: Options4 = [{disc_cache_journal_dir,"./cache/journal/"},
            {disc_cache_data_dir,"./cache/data/"},
            {ram_cache_name,mcerl},
            {ram_cache_workers,32},
            {ram_cache_size,128000000},
            {disc_cache_name,dcerl},
            {disc_cache_workers,16},
            {disc_cache_size,128000000},
            {disc_cache_threshold_len,1000000},
            {ram_cache_mod,leo_cache_server_mcerl},
            {disc_cache_mod,leo_cache_server_dcerl},
            {ram_cache_active,true},
            {disc_cache_active,...}]
=======================================================
  Failed: 3.  Skipped: 0.  Passed: 46.

@windkit
Copy link
Contributor Author

windkit commented Jun 9, 2015

Bug fix for End < 0
Updates of Unit test

@yosukehara
Copy link
Member

@windkit I've checked your request, again and then confirmed the test case. There is no issue. Thanks.

@yosukehara yosukehara closed this Jun 9, 2015
get_range_object_1(Req, Bucket, Key, Range, undefined, Socket, Transport)
end,
Req),
?reply_ok(Header, Req2)
Copy link
Member

Choose a reason for hiding this comment

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

@windkit @yosukehara
Sorry for the late reply to this pull request.

To comply with HTTP spec,
We need to respond HTTP_ST_PARTIAL_CONTENT(206) as a status code so reply_ok can't use.

@mocchira
Copy link
Member

reopen

@mocchira mocchira reopened this Jun 10, 2015
@windkit windkit force-pushed the range_get branch 2 times, most recently from 30e3d0b to e7e7c38 Compare June 10, 2015 06:24
@windkit
Copy link
Contributor Author

windkit commented Jun 10, 2015

I have pushed the commits addressing @mocchira comments.

BTW, I am not sure why the CI build is failing... as I can't reproduce it on my machine

@mocchira
Copy link
Member

@windkit almost LGTM.
There are still two error handling mistakes. I'll comment that on the source view.

BTW, I am not sure why the CI build is failing... as I can't reproduce it on my machine

leo_gateway_web_tests: range_object_base...failed
in function leo_gateway_web_tests:'-range_object_base/2-fun-2-'/2 >>> (test/leo_gateway_web_tests.erl, line 657)
**error:{badmatch,{error,unknown_encoding}}

This error might depend on Erlang version.
Erlang version is specified as R16B03-1 by .travis.yml.
Have you tried with R16B03-1?

{error, unavailable} ->
?reply_service_unavailable_error([?SERVER_HEADER], Key, <<>>, Req);
_ ->
?reply_not_found([?SERVER_HEADER], Key, <<>>, Req)
Copy link
Member

Choose a reason for hiding this comment

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

Need to handle errors of the below clauses

  • {error, ?ERR_TYPE_INTERNAL_ERROR}
  • {error, timeout}

fun(Socket, Transport) ->
get_range_object_1(Req, Bucket, Key, Range, undefined, Socket, Transport)
end,
Req),
Copy link
Member

Choose a reason for hiding this comment

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

@windkit I found out why CI failed.
You need to use set_resp_body_fun's another version.

https://github.com/ninenines/cowboy/blob/1.0.0/src/cowboy_req.erl#L776

Try to pass the content length you calculated as the first argument.

Since R16B03-1 coudn't understand transfer-encoding: identify, this error have occured on CI.
https://github.com/erlang/otp/blob/OTP_R16B03-1/lib/inets/src/http_client/httpc_handler.erl#L1122

The latest one can understand this header.
https://github.com/erlang/otp/blob/OTP-17.5.6/lib/inets/src/http_client/httpc_handler.erl#L1130

@windkit
Copy link
Contributor Author

windkit commented Jun 10, 2015

@mocchira Thanks for helping to sort out the cause.
It seems that the only solution is to set the content-length twice, one with explicit Header and one with cowboy
The reason is cowboy sends the header in lower case as 'content-length' but aws-sdk-java assumes it is capitalized as 'Content-Length'...... That's why I did not use the set_resp_body_fun/3 at the first place. So now I would use both....

@mocchira
Copy link
Member

@windkit YW and GJ!

It seems that the only solution is to set the content-length twice, one with explicit Header and one with cowboy

Yes.
Unfortunately there are lots of aws client implementations which do NOT comply with RFC2616.
So we need to handle those clients not only aws-sdk :(
That's why capitalized http headers are defined in leo_http.hrl.

@mocchira
Copy link
Member

@yosukehara
Finished to review and @windkit have fixed all issues I pointed out,
so please merge if you don't have something to be

@windkit
Copy link
Contributor Author

windkit commented Jun 11, 2015

And setting both actually breaks other clients such as boto (Python).......

@yosukehara
Copy link
Member

I've merged your code with the branch of feature/fix-issue-376 as follows:

@windkit
Copy link
Contributor Author

windkit commented Jun 12, 2015

Short Summary of setting content-length (pass length to cowboy:set_reps_body_fun/3) and Content-Length (Explicitly set the HTTP Header) in HTTP Header

Setting both, breaks
aws-sdk-ruby (both v1 and v2)
boto

Setting content-length only, breaks
aws-sdk-ruby (both v1 and v2)
boto
aws-sdk-java
(RFC suggests headers are case-insensitive but actually it is implementation dependent)
[Before reading the RFC, I also thought it should be Content-Length ...]

Setting Content-Length only, breaks
httpc in Erlang R16B03-1
(Technically Speaking, it is about cowboy setting content-type to identity if content length is not specified in sending the Reply HTTP Header and in R16B03-1, it was not handled)

@mocchira
Copy link
Member

@windkit Thank you for the Good summary.

So Applying the patch which replace <<"content-length">> at this line https://github.com/ninenines/cowboy/blob/1.0.0/src/cowboy_req.erl#L869 with <<"Content-Length">> will solve all issues?
if so, I think we should go with this patch.

@windkit
Copy link
Contributor Author

windkit commented Jun 15, 2015

@mocchira The fix seems working, the issue I encountered after applying the patch was related to leo_storage leo-project/leofs#382

@windkit
Copy link
Contributor Author

windkit commented Jun 15, 2015

Tested with the simple "Content-Length" Hack, works fine

@mocchira
Copy link
Member

LGTM.

@yosukehara
Copy link
Member

I've added other fixed code: leo-project/cowboy@22a4dcf
OK then, we will check this issue more.

@yosukehara
Copy link
Member

I've merged your code with feature/fix-issue-376 branch as follows:

@yosukehara yosukehara merged commit 794856c into leo-project:develop Jun 16, 2015
@windkit windkit deleted the range_get branch March 2, 2016 03:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants