Skip to content

Commit 009cb8f

Browse files
committed
fix: handle non-standard decimal status codes (#697)
Some IIS servers return status codes like 401.1 or 403.14 (see Microsoft IIS HTTP status codes documentation). These are non-standard but do exist in the wild. The fix truncates at the decimal point since HTTP status codes are defined as 3-digit integers per RFC 7231.
1 parent 8f94455 commit 009cb8f

2 files changed

Lines changed: 21 additions & 1 deletion

File tree

src/hackney_http.erl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,12 @@ parse_status(<< C, Rest/bits >>, St, Version, Acc) ->
232232
end.
233233

234234
parse_reason(Reason, St, Version, StatusCode) ->
235-
StatusInt = list_to_integer(binary_to_list(StatusCode)),
235+
%% Handle non-standard decimal status codes (e.g., 401.1 from IIS) by truncating
236+
StatusCodeInt = case binary:split(StatusCode, <<".">>) of
237+
[IntPart, _DecPart] -> IntPart;
238+
[IntPart] -> IntPart
239+
end,
240+
StatusInt = list_to_integer(binary_to_list(StatusCodeInt)),
236241

237242
NState = St#hparser{type=response,
238243
version=Version,

test/hackney_http_tests.erl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,18 @@ parse_chunked_response_trailers_test() ->
6666
{_, P3} = hackney_http:execute(P2, <<"\r\n">>),
6767
{more, P4} = hackney_http:execute(P3, <<"0\r\nFoo: ">>),
6868
?assertEqual({done, <<>>}, hackney_http:execute(P4, <<"Bar\r\n\r\n">>)).
69+
70+
%% Issue #697: Handle non-standard decimal status codes (e.g., 401.1 from IIS)
71+
parse_response_decimal_status_code_test() ->
72+
Response = <<"HTTP/1.1 401.1 Access Denied">>,
73+
St = #hparser{},
74+
{response, _Version, StatusInt, Reason, _NState} = hackney_http:parse_response_version(Response, St),
75+
?assertEqual(401, StatusInt),
76+
?assertEqual(<<"Access Denied">>, Reason).
77+
78+
parse_response_decimal_status_code_two_digits_test() ->
79+
Response = <<"HTTP/1.1 403.14 Forbidden">>,
80+
St = #hparser{},
81+
{response, _Version, StatusInt, Reason, _NState} = hackney_http:parse_response_version(Response, St),
82+
?assertEqual(403, StatusInt),
83+
?assertEqual(<<"Forbidden">>, Reason).

0 commit comments

Comments
 (0)