From b9212e4eaf48816ea3d1edc1334ad2af04efe416 Mon Sep 17 00:00:00 2001 From: Daisuke Aritomo Date: Wed, 13 May 2026 23:28:25 +0900 Subject: [PATCH] Improve compliance with RFC 9112 for status line parsing This patch improves compliance with RFC 9112 Section 4 for parsing the status-line of the HTTP response. - Require the HTTP version to be in the format "HTTP/x.y" - Disallow cases like "http/1.1" (lowercase "http"), "HTTP" (missing version), "HTTP/10.23" (multidigit versions) - Require a space between the status-code and the reason-phrase, even when the reason-phrase is empty - Disallow cases like "HTTP/1.1 200" (missing space after status code) - Make clear that SP parsing operates on the lenient behavior, which allows 'HTAB, VT (%x0B), FF (%x0C), or bare CR' in addition to space --- lib/net/http/response.rb | 2 +- test/net/http/test_httpresponse.rb | 109 ++++++++++++++++++++++++----- 2 files changed, 91 insertions(+), 20 deletions(-) diff --git a/lib/net/http/response.rb b/lib/net/http/response.rb index bea4346e..f1bf7c31 100644 --- a/lib/net/http/response.rb +++ b/lib/net/http/response.rb @@ -157,7 +157,7 @@ def read_new(sock) #:nodoc: internal use only def read_status_line(sock) str = sock.readline - m = /\AHTTP(?:\/(\d+\.\d+))?\s+(\d\d\d)(?:\s+(.*))?\z/in.match(str) or + m = /\AHTTP\/(\d\.\d)[ \t\v\f\r]+(\d\d\d)[ \t\v\f\r]+(.*)\z/n.match(str) or raise Net::HTTPBadResponse, "wrong status line: #{str.dump}" m.captures end diff --git a/test/net/http/test_httpresponse.rb b/test/net/http/test_httpresponse.rb index 01281063..69d0c0d9 100644 --- a/test/net/http/test_httpresponse.rb +++ b/test/net/http/test_httpresponse.rb @@ -639,9 +639,24 @@ def test_uri_equals assert_not_same uri, response.uri end - def test_ensure_zero_space_does_not_regress + def test_normal_status_line + io = dummy_io(<