Skip to content

Commit

Permalink
3.12: upgrade cowboy to 0.10.0 and refresh Crossbar
Browse files Browse the repository at this point in the history
  • Loading branch information
James Aimonetti committed Jun 19, 2014
1 parent 0098693 commit 78d19f6
Show file tree
Hide file tree
Showing 316 changed files with 5,194 additions and 3,331 deletions.
3 changes: 0 additions & 3 deletions applications/Makefile
@@ -1,5 +1,4 @@
ROOT = ../
REBAR = $(ROOT)/utils/rebar/rebar

MAKEDIRS = */Makefile

Expand All @@ -9,11 +8,9 @@ all: compile

compile: ACTION = all
compile: $(MAKEDIRS)
$(REBAR) compile

clean: ACTION = clean
clean: $(MAKEDIRS)
$(REBAR) clean

$(MAKEDIRS):
$(MAKE) -C $(@D) $(ACTION)
77 changes: 39 additions & 38 deletions applications/crossbar/src/api_util.erl
Expand Up @@ -305,9 +305,11 @@ extract_file(Context, ContentType, Req0) ->
{'ok', FileContents, Req1} ->
%% http://tools.ietf.org/html/rfc2045#page-17
case cowboy_req:header(<<"content-transfer-encoding">>, Req1) of
{<<"base64">>, Req2} -> decode_base64(Context, ContentType, Req2);
{<<"base64">>, Req2} ->
lager:debug("base64 encoded request coming in"),
decode_base64(Context, ContentType, Req2);
{_Else, Req2} ->
lager:debug("encoding: ~p", [_Else]),
lager:debug("unexpected transfer encoding: '~s'", [_Else]),
{ContentLength, Req3} = cowboy_req:header(<<"content-length">>, Req2),
Headers = wh_json:from_list([{<<"content_type">>, ContentType}
,{<<"content_length">>, ContentLength}
Expand Down Expand Up @@ -338,6 +340,8 @@ default_filename() ->
{cb_context:context(), cowboy_req:req()} |
halt_return().
decode_base64(Context, CT, Req0) ->
decode_base64(Context, CT, Req0, []).
decode_base64(Context, CT, Req0, Body) ->
case cowboy_req:body(Req0) of
{'error', 'badlength'} ->
lager:debug("the request body was most likely too big"),
Expand All @@ -353,77 +357,74 @@ decode_base64(Context, CT, Req0) ->
cb_context:set_resp_data(Context, E)
,'fatal'
));
{'more', BinData, Req1} ->
lager:debug("recv ~p bytes with more to come", [byte_size(BinData)]),
decode_base64(Context, CT, Req1, [BinData | Body]);
{'ok', Base64Data, Req1} ->
{EncodedType, FileContents} = decode_base64(Base64Data),
Data = iolist_to_binary(lists:reverse([Base64Data | Body])),

{EncodedType, FileContents} = decode_base64(Data),
ContentType = case EncodedType of
'undefined' -> CT;
<<"application/base64">> -> <<"application/octet-stream">>;
Else -> Else
end,
Headers = wh_json:from_list([{<<"content_type">>, ContentType}
,{<<"content_length">>, wh_util:to_binary(size(FileContents))}
,{<<"content_length">>, byte_size(FileContents)}
]),
FileJObj = wh_json:from_list([{<<"headers">>, Headers}
,{<<"contents">>, FileContents}
]),
lager:debug("request is a base64 file upload of type: ~s", [ContentType]),
FileName = <<"uploaded_file_"
,(wh_util:to_binary(wh_util:current_tstamp()))/binary>>,
,(wh_util:to_binary(wh_util:current_tstamp()))/binary
>>,
{cb_context:set_req_files(Context, [{FileName, FileJObj}]), Req1}
end.

-spec decode_base64(ne_binary()) -> {api_binary(), ne_binary()}.
decode_base64(Base64) ->
case binary:split(Base64, <<",">>) of
%% http://tools.ietf.org/html/rfc4648
[Bin] -> {'undefined', corrected_base64_decode(Bin)};
[Bin] ->
lager:debug("not split on ','"),
{'undefined', corrected_base64_decode(Bin)};
%% http://tools.ietf.org/rfc/rfc2397.txt
[<<"data:", CT/binary>>, Bin] ->
{ContentType, _Opts} = mochiweb_util:parse_header(wh_util:to_list(CT)),
{wh_util:to_binary(ContentType), corrected_base64_decode(Bin)}

{wh_util:to_binary(ContentType), corrected_base64_decode(Bin)};
[_SplitLeft, _SplitRight] ->
lager:debug("split unexpectedly: ~p/~p", [byte_size(_SplitLeft), byte_size(_SplitRight)]),
lager:debug("l: ~s", [binary:part(_SplitLeft, byte_size(_SplitLeft), -20)]),
lager:debug("r: ~s", [binary:part(_SplitRight, byte_size(_SplitRight), -10)]),
{'undefined', corrected_base64_decode(Base64)}
end.

-spec corrected_base64_decode(ne_binary()) -> ne_binary().
corrected_base64_decode(Base64) when byte_size(Base64) rem 4 == 3 ->
base64:mime_decode(<<Base64/bytes, "=">>);
base64:mime_decode(<<Base64/binary, "=">>);
corrected_base64_decode(Base64) when byte_size(Base64) rem 4 == 2 ->
base64:mime_decode(<<Base64/bytes, "==">>);
base64:mime_decode(<<Base64/binary, "==">>);
corrected_base64_decode(Base64) ->
base64:mime_decode(Base64).

-spec get_request_body(cowboy_req:req()) -> {binary(), cowboy_req:req()}.
get_request_body(Req0) ->
-spec get_request_body(cowboy_req:req()) ->
{binary(), cowboy_req:req()}.
-spec get_request_body(cowboy_req:req(), iolist()) ->
{binary(), cowboy_req:req()}.
get_request_body(Req) ->
get_request_body(Req, []).
get_request_body(Req0, Body) ->
case cowboy_req:body(Req0) of
{'error', 'chunked'} ->
lager:debug("handling chunked request"),
handle_chunked(Req0);
{'error', _E} ->
lager:debug("request body had no payload: ~p", [_E]),
{<<>>, Req0};
{'ok', <<>>, Req1} ->
lager:debug("request body was empty"),
{<<>>, Req1};
{'ok', ReqBody, Req1} ->
{ReqBody, Req1}
end.

-spec handle_chunked(cowboy_req:req()) -> {binary(), cowboy_req:req()}.
handle_chunked(Req) ->
handle_chunked(Req, <<>>).

-spec handle_chunked(cowboy_req:req(), binary()) -> {binary(), cowboy_req:req()}.
handle_chunked(Req, Body) ->
case cowboy_req:stream_body(Req) of
{'done', Req2} ->
{Body, Req2};
{'ok', Data, Req2} ->
handle_chunked(Req2, <<Body/binary, Data/binary>>);
{'error', 'timeout'} ->
lager:debug("timed out recv chunked request body, using none"),
{Body, Req};
{'error', _E} ->
lager:debug("error while fetching chunk: ~p", [_E]),
{Body, Req}
{'more', Data, Req1} ->
lager:debug("recv chunk ~p bytes", [byte_size(Data)]),
get_request_body(Req1, [Body, Data]);
{'ok', Data, Req1} ->
{iolist_to_binary([Body, Data]), Req1}
end.

-type get_json_return() :: {wh_json:object(), cowboy_req:req()} |
Expand Down
2 changes: 1 addition & 1 deletion applications/crossbar/src/cb_context.erl
Expand Up @@ -131,7 +131,7 @@ method(#cb_context{method=M}) -> M.

-spec path_tokens(context()) -> ne_binaries().
path_tokens(#cb_context{raw_path=Path}) ->
[cowboy_http:urldecode(Token) || Token <- binary:split(Path, <<"/">>, ['global', 'trim'])].
[cow_qs:urldecode(Token) || Token <- binary:split(Path, <<"/">>, ['global', 'trim'])].

-spec magic_pathed(context()) -> boolean().
magic_pathed(#cb_context{magic_pathed=MP}) -> MP.
Expand Down
3 changes: 0 additions & 3 deletions core/Makefile
@@ -1,5 +1,4 @@
ROOT = ../
REBAR = $(ROOT)/utils/rebar/rebar

MAKEDIRS = */Makefile

Expand All @@ -9,11 +8,9 @@ all: compile

compile: ACTION = all
compile: kazoo $(MAKEDIRS)
$(REBAR) compile

clean: ACTION = clean
clean: $(MAKEDIRS)
$(REBAR) clean

kazoo:
$(MAKE) -C whistle-1.0.0 compile
Expand Down
1 change: 0 additions & 1 deletion core/whistle_transactions-1.0.0/Makefile
@@ -1,6 +1,5 @@
PROJECT = whistle_transactions
ROOT = ../..
REBAR = $(ROOT)/utils/rebar/rebar
DIALYZER = dialyzer

EBINS = $(shell find $(ROOT)/core -maxdepth 2 -name ebin -print) $(shell find $(ROOT)/deps -maxdepth 2 -name ebin -print)
Expand Down
10 changes: 8 additions & 2 deletions deps/Makefile
Expand Up @@ -3,6 +3,7 @@ ROOT = ..
MAKEDIRS = rabbitmq_server-*/Makefile \
lager-*/Makefile \
ibrowse-*/Makefile \
cowlib-*/Makefile \
*/Makefile

.PHONY: all compile clean $(MAKEDIRS)
Expand All @@ -11,8 +12,8 @@ all: compile

compile: ACTION = all
compile: $(MAKEDIRS)
cp -a rabbitmq_server-3.2.0/plugins-src/rabbitmq-erlang-client rabbitmq_client-3.2.0
rm -f rabbitmq_client-*/Makefile
cp -a rabbitmq_server-3.2.0/plugins-src/rabbitmq-erlang-client rabbitmq_client-3.2.0
rm -f rabbitmq_client-*/Makefile

clean: ACTION = clean
clean: $(MAKEDIRS)
Expand All @@ -21,6 +22,11 @@ clean: $(MAKEDIRS)
rm -rf lager-2.0.0rc1
rm -rf rabbitmq_server-2.8.6
rm -rf goldrush-0.1.0
rm -rf cowboy-0.8.4
rm -rf cowboy-0.9.0
rm -rf cowlib-0.4.0
rm -rf ranch-0.8.1
rm -rf ranch-0.9.0

$(MAKEDIRS):
$(MAKE) -C $(@D) $(ACTION)
11 changes: 9 additions & 2 deletions deps/cowboy-0.9.0/AUTHORS → deps/cowboy-0.10.0/AUTHORS
Expand Up @@ -13,18 +13,22 @@ Vladimir Dronnikov
YAMAMOTO Takashi
Yurii Rashkovskii
Andrew Majorov
Eduardo Gurgel
Egobrain
Josh Toft
Steven Gravell
Andrew Thompson
Hunter Morris
Ivan Lisenkov
Matthias Endler
Seletskiy Stanislav
Sina Samavati
Tristan Sloughter
0x00F6
0xAX
Adam Cammmack
Adrian Roe
Alexei Sholik
Andre Graf
Andrzej Sliwa
Blake Gentry
Expand All @@ -37,7 +41,9 @@ Dave Peticolas
David Kelly
DeadZen
Dmitry Groshev
Eduardo Gurgel
Drew
Drew Varner
Eiichi Tsukata
Hans Ulrich Niedermann
Ivan Blinkov
Jeremy Ong
Expand All @@ -46,13 +52,14 @@ Josh Allmann
Josh Marchán
José Valim
Julian Squires
Klaus Trainer
Kuk-Hyun Lee
Mathieu Lecarme
Matthias Endler
Max Lapshin
Michiel Hakvoort
Ori Bar
Pablo Vieytes
Peter Ericson
RJ
Radosław Szymczyszyn
Richard Ramsden
Expand Down
82 changes: 82 additions & 0 deletions deps/cowboy-0.9.0/CHANGELOG.md → deps/cowboy-0.10.0/CHANGELOG.md
@@ -1,6 +1,88 @@
CHANGELOG
=========

0.10.0
------

* Update Ranch to 0.10 and Cowlib to 0.6.2

* Update the body reading API to allow controlling rate of transfer

The lack of this feature was causing various timeout issues
in some environments.

The body/2 function now takes a Req and a list of options. The older
interface can still be used until Cowboy 1.0.

The body_qs/2, part/2 and part_body/2 also accept this list of
options, and pass it down to the body/2 call. The default options
vary between the different functions.

The return value of the function has changed. Older code should work
without modification but you should definitely still test it.

All functions appropriately decode transfer and content encoding.
There is no need to have a special case for that anymore.

The body/1,2 function supports streaming, with the same interface
as the part_body/1,2 function.

* Deprecate the cowboy_req:init_stream, stream_body and skip_body functions

They will be removed in Cowboy 1.0.

* Add support for multipart

The cowboy_req:part/1,2 and cowboy_req:part_body/1,2 can be
used for reading a multipart body.

Documentation has been added.

The old undocumented multipart functions were removed.

* Allow the onresponse hook to override only status and headers

Previously it wasn't possible to override them without also
overriding the body. The new return value is currently marked
as experimental.

* Make loop handlers work with SPDY

* Fix a race condition with loop handlers and keepalive requests

* Fix parsing of accept-language header

* Fix parsing of authorization header with empty passwords

* Fix multiline headers handling

* Various optimizations

All code that is moved to cowlib is optimized at the same time
and benchmarks get added for all functions.

The parsing of connection, content-length and transfer-encoding
has been optimized.

Chunked transfer decoding has been optimized.

* Enable +warn_missing_spec by default and fix specs

* Remove the non-documented cowboy_client module; use gun instead

* Numerous documentation updates and tweaks

The guide now has a REST principles chapter and revised
and completed Websocket chapters, alongside a new multipart chapter.

* Add a multipart file upload example

* Test suites are being reworked and greatly improved
* Test Cowboy across all releases from R15B01 to 17.0, plus maint and master
* The Autobahn test suite is now always ran (as long as it's installed)
* Expected error reports are now silenced (but still logged)
* Applications are now only started once from a ct hook

0.9.0
-----

Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion deps/cowlib-0.4.0/LICENSE → deps/cowboy-0.10.0/LICENSE
@@ -1,4 +1,4 @@
Copyright (c) 2013, Loïc Hoguin <essen@ninenines.eu>
Copyright (c) 2011-2014, Loïc Hoguin <essen@ninenines.eu>

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
Expand Down
6 changes: 3 additions & 3 deletions deps/cowboy-0.9.0/Makefile → deps/cowboy-0.10.0/Makefile
@@ -1,16 +1,16 @@
PROJECT = cowboy
ROOT = ../..
REBAR = $(ROOT)/utils/rebar/rebar
DIALYZER = dialyzer

EBINS = $(shell find $(ROOT)/core -maxdepth 2 -name ebin -print) $(shell find $(ROOT)/deps -maxdepth 2 -name ebin -print)
PA = $(foreach EBIN,$(EBINS),-pa $(EBIN))

ERLC_OPTS = +debug_info +warn_export_all -I$(ROOT)/core -I$(ROOT)/deps $(PA)
ERLC_OPTS = +debug_info +warn_export_all -I$(ROOT)/deps $(PA)
# +bin_opt_info

DIRS = . \
$(ROOT)/deps/ranch-0.8.1
$(ROOT)/deps/ranch-0.10.0 \
$(ROOT)/deps/cowlib-0.6.2

.PHONY: all compile clean

Expand Down

0 comments on commit 78d19f6

Please sign in to comment.