Browse Source

Avoid crashing in cowboy_req on invalid Accept-Encoding header

Certain clients send malformed Accept-Encoding headers, which causes
cowboy_req to crash is compression is enabled.
Ali Sabil 12 years ago
parent
commit
ba1eca6b97
1 changed files with 30 additions and 25 deletions
  1. 30 25
      src/cowboy_req.erl

+ 30 - 25
src/cowboy_req.erl

@@ -1021,31 +1021,36 @@ reply(Status, Headers, Body, Req=#http_req{
 reply_may_compress(Status, Headers, Body, Req,
 		RespHeaders, HTTP11Headers, Method) ->
 	BodySize = iolist_size(Body),
-	{ok, Encodings, Req2} = parse_header(<<"accept-encoding">>, Req),
-	CanGzip = (BodySize > 300)
-		andalso (false =:= lists:keyfind(<<"content-encoding">>,
-			1, Headers))
-		andalso (false =:= lists:keyfind(<<"content-encoding">>,
-			1, RespHeaders))
-		andalso (false =:= lists:keyfind(<<"transfer-encoding">>,
-			1, Headers))
-		andalso (false =:= lists:keyfind(<<"transfer-encoding">>,
-			1, RespHeaders))
-		andalso (Encodings =/= undefined)
-		andalso (false =/= lists:keyfind(<<"gzip">>, 1, Encodings)),
-	case CanGzip of
-		true ->
-			GzBody = zlib:gzip(Body),
-			{_, Req3} = response(Status, Headers, RespHeaders, [
-					{<<"content-length">>, integer_to_list(byte_size(GzBody))},
-					{<<"content-encoding">>, <<"gzip">>},
-					{<<"date">>, cowboy_clock:rfc1123()},
-					{<<"server">>, <<"Cowboy">>}
-				|HTTP11Headers],
-				case Method of <<"HEAD">> -> <<>>; _ -> GzBody end,
-				Req2),
-			Req3;
-		false ->
+	case parse_header(<<"accept-encoding">>, Req) of
+		{ok, Encodings, Req2} ->
+			CanGzip = (BodySize > 300)
+				andalso (false =:= lists:keyfind(<<"content-encoding">>,
+					1, Headers))
+				andalso (false =:= lists:keyfind(<<"content-encoding">>,
+					1, RespHeaders))
+				andalso (false =:= lists:keyfind(<<"transfer-encoding">>,
+					1, Headers))
+				andalso (false =:= lists:keyfind(<<"transfer-encoding">>,
+					1, RespHeaders))
+				andalso (Encodings =/= undefined)
+				andalso (false =/= lists:keyfind(<<"gzip">>, 1, Encodings)),
+			case CanGzip of
+				true ->
+					GzBody = zlib:gzip(Body),
+					{_, Req3} = response(Status, Headers, RespHeaders, [
+							{<<"content-length">>, integer_to_list(byte_size(GzBody))},
+							{<<"content-encoding">>, <<"gzip">>},
+							{<<"date">>, cowboy_clock:rfc1123()},
+							{<<"server">>, <<"Cowboy">>}
+						|HTTP11Headers],
+						case Method of <<"HEAD">> -> <<>>; _ -> GzBody end,
+						Req2),
+					Req3;
+				false ->
+					reply_no_compress(Status, Headers, Body, Req,
+						RespHeaders, HTTP11Headers, Method, BodySize)
+			end;
+		{error, badarg} ->
 			reply_no_compress(Status, Headers, Body, Req,
 				RespHeaders, HTTP11Headers, Method, BodySize)
 	end.