diff --git a/history.md b/history.md index 4f79715b..5b75d77b 100644 --- a/history.md +++ b/history.md @@ -4,6 +4,7 @@ - Change default Accept header to `*/*` - Use a more descriptive User-Agent header by default - Drop RC4-MD5 from default cipher list (will have no affect on most users) +- Only prepend http:// to URIs without a scheme # 1.7.2 diff --git a/lib/restclient/request.rb b/lib/restclient/request.rb index 024e3fdb..09334d51 100644 --- a/lib/restclient/request.rb +++ b/lib/restclient/request.rb @@ -270,8 +270,22 @@ def net_http_do_request(http, req, body=nil, &block) end end + # Parse a string into a URI object. If the string has no HTTP-like scheme + # (i.e. scheme followed by '//'), a scheme of 'http' will be added. This + # mimics the behavior of browsers and user agents like cURL. + # + # @param url [String] A URL string. + # + # @return [URI] + # + # @raise URI::InvalidURIError on invalid URIs + # def parse_url(url) - url = "http://#{url}" unless url.match(/^http/) + # Prepend http:// unless the string already contains an RFC 3986 scheme + # followed by two forward slashes. (The slashes are not part of the URI + # RFC, but specified by the URL RFC 1738.) + # https://tools.ietf.org/html/rfc3986#section-3.1 + url = 'http://' + url unless url.match(/\A[a-z][a-z0-9+.-]*:\/\//i) URI.parse(url) end diff --git a/spec/unit/request_spec.rb b/spec/unit/request_spec.rb index d69cf542..5fc92a69 100644 --- a/spec/unit/request_spec.rb +++ b/spec/unit/request_spec.rb @@ -68,14 +68,36 @@ end end - it "parses a url into a URI object" do - URI.should_receive(:parse).with('http://example.com/resource') - @request.parse_url('http://example.com/resource') - end + describe '.parse_url' do + it "parses a url into a URI object" do + URI.should_receive(:parse).with('http://example.com/resource') + @request.parse_url('http://example.com/resource') + end + + it "adds http:// to the front of resources specified in the syntax example.com/resource" do + URI.should_receive(:parse).with('http://example.com/resource') + @request.parse_url('example.com/resource') + end + + it 'adds http:// to resources containing a colon' do + URI.should_receive(:parse).with('http://example.com:1234') + @request.parse_url('example.com:1234') + end - it "adds http:// to the front of resources specified in the syntax example.com/resource" do - URI.should_receive(:parse).with('http://example.com/resource') - @request.parse_url('example.com/resource') + it 'does not add http:// to the front of https resources' do + URI.should_receive(:parse).with('https://example.com/resource') + @request.parse_url('https://example.com/resource') + end + + it 'does not add http:// to the front of capital HTTP resources' do + URI.should_receive(:parse).with('HTTP://example.com/resource') + @request.parse_url('HTTP://example.com/resource') + end + + it 'does not add http:// to the front of capital HTTPS resources' do + URI.should_receive(:parse).with('HTTPS://example.com/resource') + @request.parse_url('HTTPS://example.com/resource') + end end describe "user - password" do