diff options
Diffstat (limited to 'src/cowboy_bstr.erl')
-rw-r--r-- | src/cowboy_bstr.erl | 49 |
1 files changed, 46 insertions, 3 deletions
diff --git a/src/cowboy_bstr.erl b/src/cowboy_bstr.erl index e906de7..bc6818f 100644 --- a/src/cowboy_bstr.erl +++ b/src/cowboy_bstr.erl @@ -16,16 +16,40 @@ -module(cowboy_bstr). %% Binary strings. +-export([capitalize_token/1]). -export([to_lower/1]). %% Characters. -export([char_to_lower/1]). -export([char_to_upper/1]). +-ifdef(TEST). +-include_lib("eunit/include/eunit.hrl"). +-endif. + +%% @doc Capitalize a token. +%% +%% The first letter and all letters after a dash are capitalized. +%% This is the form seen for header names in the HTTP/1.1 RFC and +%% others. Note that using this form isn't required, as header name +%% are case insensitive, and it is only provided for use with eventual +%% badly implemented clients. +-spec capitalize_token(B) -> B when B::binary(). +capitalize_token(B) -> + capitalize_token(B, true, <<>>). +capitalize_token(<<>>, _, Acc) -> + Acc; +capitalize_token(<< $-, Rest/bits >>, _, Acc) -> + capitalize_token(Rest, true, << Acc/binary, $- >>); +capitalize_token(<< C, Rest/bits >>, true, Acc) -> + capitalize_token(Rest, false, << Acc/binary, (char_to_upper(C)) >>); +capitalize_token(<< C, Rest/bits >>, false, Acc) -> + capitalize_token(Rest, false, << Acc/binary, (char_to_lower(C)) >>). + %% @doc Convert a binary string to lowercase. --spec to_lower(binary()) -> binary(). -to_lower(L) -> - << << (char_to_lower(C)) >> || << C >> <= L >>. +-spec to_lower(B) -> B when B::binary(). +to_lower(B) -> + << << (char_to_lower(C)) >> || << C >> <= B >>. %% @doc Convert [A-Z] characters to lowercase. %% @end @@ -88,3 +112,22 @@ char_to_upper($x) -> $X; char_to_upper($y) -> $Y; char_to_upper($z) -> $Z; char_to_upper(Ch) -> Ch. + +%% Tests. + +-ifdef(TEST). + +capitalize_token_test_() -> + %% {Header, Result} + Tests = [ + {<<"heLLo-woRld">>, <<"Hello-World">>}, + {<<"Sec-Websocket-Version">>, <<"Sec-Websocket-Version">>}, + {<<"Sec-WebSocket-Version">>, <<"Sec-Websocket-Version">>}, + {<<"sec-websocket-version">>, <<"Sec-Websocket-Version">>}, + {<<"SEC-WEBSOCKET-VERSION">>, <<"Sec-Websocket-Version">>}, + {<<"Sec-WebSocket--Version">>, <<"Sec-Websocket--Version">>}, + {<<"Sec-WebSocket---Version">>, <<"Sec-Websocket---Version">>} + ], + [{H, fun() -> R = capitalize_token(H) end} || {H, R} <- Tests]. + +-endif. |