@@ -801,4 +801,74 @@ mod tests {
801801 assert ! ( elapsed >= Duration :: from_secs( 2 ) ) ;
802802 assert ! ( elapsed < Duration :: from_secs( 3 ) ) ;
803803 }
804+
805+ #[ tokio:: test]
806+ async fn test_parse_retry_after_logic ( ) {
807+ use reqwest:: header:: HeaderValue ;
808+ use std:: time:: SystemTime ;
809+
810+ // 1. Test with valid integer seconds
811+ let header = HeaderValue :: from_static ( "5" ) ;
812+ assert_eq ! ( parse_retry_after( & header) , Some ( Duration :: from_secs( 5 ) ) ) ;
813+
814+ // 2. Test with zero seconds (edge case)
815+ let header = HeaderValue :: from_static ( "0" ) ;
816+ assert_eq ! ( parse_retry_after( & header) , Some ( Duration :: from_secs( 0 ) ) ) ;
817+
818+ // 3. Test with large valid number
819+ let header = HeaderValue :: from_static ( "86400" ) ; // 24 hours
820+ assert_eq ! (
821+ parse_retry_after( & header) ,
822+ Some ( Duration :: from_secs( 86400 ) )
823+ ) ;
824+
825+ // 4. Test with whitespace (should fail - HTTP headers shouldn't have leading/trailing spaces)
826+ let header = HeaderValue :: from_static ( " 5 " ) ;
827+ assert_eq ! ( parse_retry_after( & header) , None ) ;
828+
829+ // 5. Test with fractional seconds (should fail)
830+ let header = HeaderValue :: from_static ( "1.5" ) ;
831+ assert_eq ! ( parse_retry_after( & header) , None ) ;
832+
833+ // 6. Test with a valid HTTP-date in future
834+ let future_time = SystemTime :: now ( ) + Duration :: from_secs ( 10 ) ;
835+ let date_str = httpdate:: fmt_http_date ( future_time) ;
836+ let header = HeaderValue :: from_str ( & date_str) . unwrap ( ) ; //#[allow_ci]
837+ let duration = parse_retry_after ( & header) . unwrap ( ) ; //#[allow_ci]
838+ // Check that the duration is close to 10s, allowing for minor timing delays
839+ assert ! ( duration. as_secs( ) >= 9 && duration. as_secs( ) <= 10 ) ;
840+
841+ // 7. Test with HTTP-date in the past (should return Duration::ZERO)
842+ let past_time = SystemTime :: now ( ) - Duration :: from_secs ( 10 ) ;
843+ let past_date_str = httpdate:: fmt_http_date ( past_time) ;
844+ let header = HeaderValue :: from_str ( & past_date_str) . unwrap ( ) ; //#[allow_ci]
845+ assert_eq ! ( parse_retry_after( & header) , Some ( Duration :: ZERO ) ) ;
846+
847+ // 8. Test with malformed string value
848+ let header = HeaderValue :: from_static ( "not-a-valid-value" ) ;
849+ assert_eq ! ( parse_retry_after( & header) , None ) ;
850+
851+ // 9. Test with invalid UTF-8 sequence
852+ let invalid_utf8_bytes = & [ 0xC3 , 0x28 ] ; // This is an invalid UTF-8 sequence
853+ let header = HeaderValue :: from_bytes ( invalid_utf8_bytes) . unwrap ( ) ; //#[allow_ci]
854+ assert_eq ! (
855+ parse_retry_after( & header) ,
856+ None ,
857+ "Should return None for non-UTF-8 header values"
858+ ) ;
859+
860+ // 10. Test with empty string
861+ let header = HeaderValue :: from_static ( "" ) ;
862+ assert_eq ! ( parse_retry_after( & header) , None ) ;
863+
864+ // 11. Test with negative number (should fail)
865+ let header = HeaderValue :: from_static ( "-5" ) ;
866+ assert_eq ! ( parse_retry_after( & header) , None ) ;
867+
868+ // 12. Test with very large number that might overflow
869+ let header = HeaderValue :: from_static ( "18446744073709551615" ) ; // u64::MAX
870+ // This should either work or fail gracefully, but not panic
871+ let result = parse_retry_after ( & header) ;
872+ assert ! ( result. is_some( ) || result. is_none( ) ) ; // Just ensure no panic
873+ }
804874}
0 commit comments