diff --git a/src/hackney_http.erl b/src/hackney_http.erl index d37b5f93..d2d19931 100644 --- a/src/hackney_http.erl +++ b/src/hackney_http.erl @@ -232,7 +232,12 @@ parse_status(<< C, Rest/bits >>, St, Version, Acc) -> end. parse_reason(Reason, St, Version, StatusCode) -> - StatusInt = list_to_integer(binary_to_list(StatusCode)), + %% Handle non-standard decimal status codes (e.g., 401.1 from IIS) by truncating + StatusCodeInt = case binary:split(StatusCode, <<".">>) of + [IntPart, _DecPart] -> IntPart; + [IntPart] -> IntPart + end, + StatusInt = list_to_integer(binary_to_list(StatusCodeInt)), NState = St#hparser{type=response, version=Version, diff --git a/test/hackney_http_tests.erl b/test/hackney_http_tests.erl index 4b7e7315..a1fed2e4 100644 --- a/test/hackney_http_tests.erl +++ b/test/hackney_http_tests.erl @@ -66,3 +66,18 @@ parse_chunked_response_trailers_test() -> {_, P3} = hackney_http:execute(P2, <<"\r\n">>), {more, P4} = hackney_http:execute(P3, <<"0\r\nFoo: ">>), ?assertEqual({done, <<>>}, hackney_http:execute(P4, <<"Bar\r\n\r\n">>)). + +%% Issue #697: Handle non-standard decimal status codes (e.g., 401.1 from IIS) +parse_response_decimal_status_code_test() -> + Response = <<"HTTP/1.1 401.1 Access Denied">>, + St = #hparser{}, + {response, _Version, StatusInt, Reason, _NState} = hackney_http:parse_response_version(Response, St), + ?assertEqual(401, StatusInt), + ?assertEqual(<<"Access Denied">>, Reason). + +parse_response_decimal_status_code_two_digits_test() -> + Response = <<"HTTP/1.1 403.14 Forbidden">>, + St = #hparser{}, + {response, _Version, StatusInt, Reason, _NState} = hackney_http:parse_response_version(Response, St), + ?assertEqual(403, StatusInt), + ?assertEqual(<<"Forbidden">>, Reason).