diff --git a/lib/http/request.rb b/lib/http/request.rb index 1372cd11..f576d290 100644 --- a/lib/http/request.rb +++ b/lib/http/request.rb @@ -169,11 +169,13 @@ def connect_using_proxy(socket) def headline request_uri = if using_proxy? && !uri.https? - uri.omit(:fragment) + uri.omit(:fragment).to_s else - uri.request_uri + uri.request_uri.to_s end + raise RequestError, "Invalid request URI: #{request_uri.inspect}" if request_uri.match?(/\s/) + "#{verb.to_s.upcase} #{request_uri} HTTP/#{version}" end @@ -230,7 +232,11 @@ def port # @return [String] Default host (with port if needed) header value. def default_host_header_value - PORTS[@scheme] == port ? host : "#{host}:#{port}" + value = PORTS[@scheme] == port ? host : "#{host}:#{port}" + + raise RequestError, "Invalid host: #{value.inspect}" if value.match?(/\s/) + + value end def prepare_body(body) diff --git a/spec/lib/http_spec.rb b/spec/lib/http_spec.rb index f7a1bb21..746a08ec 100644 --- a/spec/lib/http_spec.rb +++ b/spec/lib/http_spec.rb @@ -460,20 +460,37 @@ def setsockopt(*args) context "with :normalize_uri" do it "normalizes URI" do - response = HTTP.get "#{dummy.endpoint}/hello world" + response = HTTP.get "#{dummy.endpoint}/héllö-wörld" expect(response.to_s).to eq("hello world") end it "uses the custom URI Normalizer method" do client = HTTP.use(:normalize_uri => {:normalizer => :itself.to_proc}) - response = client.get("#{dummy.endpoint}/hello world") + response = client.get("#{dummy.endpoint}/héllö-wörld") expect(response.status).to eq(400) end + it "raises if custom URI Normalizer returns invalid path" do + client = HTTP.use(:normalize_uri => {:normalizer => :itself.to_proc}) + expect { client.get("#{dummy.endpoint}/hello\nworld") }. + to raise_error HTTP::RequestError, 'Invalid request URI: "/hello\nworld"' + end + + it "raises if custom URI Normalizer returns invalid host" do + normalizer = lambda do |uri| + uri.port = nil + uri.instance_variable_set(:@host, "example\ncom") + uri + end + client = HTTP.use(:normalize_uri => {:normalizer => normalizer}) + expect { client.get(dummy.endpoint) }. + to raise_error HTTP::RequestError, 'Invalid host: "example\ncom"' + end + it "uses the default URI normalizer" do client = HTTP.use :normalize_uri expect(HTTP::URI::NORMALIZER).to receive(:call).and_call_original - response = client.get("#{dummy.endpoint}/hello world") + response = client.get("#{dummy.endpoint}/héllö-wörld") expect(response.to_s).to eq("hello world") end end diff --git a/spec/support/dummy_server/servlet.rb b/spec/support/dummy_server/servlet.rb index 9f835c33..81e32ab4 100644 --- a/spec/support/dummy_server/servlet.rb +++ b/spec/support/dummy_server/servlet.rb @@ -149,7 +149,7 @@ def do_#{method.upcase}(req, res) res.body = req.body end - get "/hello world" do |_req, res| + get "/héllö-wörld".b do |_req, res| res.status = 200 res.body = "hello world" end