Skip to content

Commit

Permalink
Adding support for public_suffix.
Browse files Browse the repository at this point in the history
* New runtime dependency on `public_suffix` gem.
* Match the escaping rules in the `reg-name` rule.
  * Note: This implies underscores are no longer escaped in hostnames.
  • Loading branch information
sporkmonger committed Nov 4, 2016
1 parent 8d040f6 commit f032606
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 19 deletions.
10 changes: 6 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Addressable 2.5.0
- Paths beginning with // and missing an authority are now considered invalid
- URI validation now also takes place after setting a path
- Handle backslashes in authority more like a browser for `heuristic_parse`
- Unescaped backslashes in host now raise an `InvalidURIError`
- add support for public suffixes and tld; first runtime dependency
- hostname escaping should match RFC; underscores in hostnames no longer escaped
- paths beginning with // and missing an authority are now considered invalid
- validation now also takes place after setting a path
- handle backslashes in authority more like a browser for `heuristic_parse`
- unescaped backslashes in host now raise an `InvalidURIError`
- `merge!`, `join!`, `omit!` and `normalize!` don't disable deferred validation
- `heuristic_parse` now trims whitespace before parsing

Expand Down
13 changes: 8 additions & 5 deletions addressable.gemspec
Original file line number Diff line number Diff line change
@@ -1,34 +1,37 @@
# -*- encoding: utf-8 -*-
# stub: addressable 2.4.0 ruby lib
# stub: addressable 2.5.0 ruby lib

Gem::Specification.new do |s|
s.name = "addressable"
s.version = "2.4.0"
s.version = "2.5.0"

s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.require_paths = ["lib"]
s.authors = ["Bob Aman"]
s.date = "2015-12-07"
s.date = "2016-11-04"
s.description = "Addressable is a replacement for the URI implementation that is part of\nRuby's standard library. It more closely conforms to the relevant RFCs and\nadds support for IRIs and URI templates.\n"
s.email = "bob@sporkmonger.com"
s.extra_rdoc_files = ["README.md"]
s.files = ["CHANGELOG.md", "Gemfile", "LICENSE.txt", "README.md", "Rakefile", "addressable.gemspec", "data/unicode.data", "lib/addressable.rb", "lib/addressable/idna.rb", "lib/addressable/idna/native.rb", "lib/addressable/idna/pure.rb", "lib/addressable/template.rb", "lib/addressable/uri.rb", "lib/addressable/version.rb", "spec/addressable/idna_spec.rb", "spec/addressable/net_http_compat_spec.rb", "spec/addressable/rack_mount_compat_spec.rb", "spec/addressable/security_spec.rb", "spec/addressable/template_spec.rb", "spec/addressable/uri_spec.rb", "spec/spec_helper.rb", "tasks/clobber.rake", "tasks/gem.rake", "tasks/git.rake", "tasks/metrics.rake", "tasks/rspec.rake", "tasks/yard.rake"]
s.files = ["CHANGELOG.md", "Gemfile", "LICENSE.txt", "README.md", "Rakefile", "data/unicode.data", "lib/addressable", "lib/addressable.rb", "lib/addressable/idna", "lib/addressable/idna.rb", "lib/addressable/idna/native.rb", "lib/addressable/idna/pure.rb", "lib/addressable/template.rb", "lib/addressable/uri.rb", "lib/addressable/version.rb", "spec/addressable", "spec/addressable/idna_spec.rb", "spec/addressable/net_http_compat_spec.rb", "spec/addressable/rack_mount_compat_spec.rb", "spec/addressable/security_spec.rb", "spec/addressable/template_spec.rb", "spec/addressable/uri_spec.rb", "spec/spec_helper.rb", "tasks/clobber.rake", "tasks/gem.rake", "tasks/git.rake", "tasks/metrics.rake", "tasks/rspec.rake", "tasks/yard.rake"]
s.homepage = "https://github.com/sporkmonger/addressable"
s.licenses = ["Apache-2.0"]
s.rdoc_options = ["--main", "README.md"]
s.required_ruby_version = Gem::Requirement.new(">= 1.9.0")
s.rubygems_version = "2.5.0"
s.rubygems_version = "2.5.1"
s.summary = "URI Implementation"

if s.respond_to? :specification_version then
s.specification_version = 4

if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
s.add_runtime_dependency(%q<public_suffix>, [">= 2.0.3", "~> 2.0"])
s.add_development_dependency(%q<bundler>, ["~> 1.0"])
else
s.add_dependency(%q<public_suffix>, [">= 2.0.3", "~> 2.0"])
s.add_dependency(%q<bundler>, ["~> 1.0"])
end
else
s.add_dependency(%q<public_suffix>, [">= 2.0.3", "~> 2.0"])
s.add_dependency(%q<bundler>, ["~> 1.0"])
end
end
21 changes: 20 additions & 1 deletion lib/addressable/uri.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

require "addressable/version"
require "addressable/idna"
require "public_suffix"

##
# Addressable is a library for processing links and URIs.
Expand All @@ -44,7 +45,7 @@ module CharacterClasses
UNRESERVED = ALPHA + DIGIT + "\\-\\.\\_\\~"
PCHAR = UNRESERVED + SUB_DELIMS + "\\:\\@"
SCHEME = ALPHA + DIGIT + "\\-\\+\\."
HOST = ALPHA + DIGIT + "\\-\\.\\[\\:\\]"
HOST = UNRESERVED + SUB_DELIMS + "\\[\\:\\]"
AUTHORITY = PCHAR
PATH = PCHAR + "\\/"
QUERY = PCHAR + "\\/\\?"
Expand Down Expand Up @@ -1145,6 +1146,24 @@ def hostname=(new_hostname)
self.host = v
end

##
# Returns the top-level domain for this host.
#
# @example
# Addressable::URI.parse("www.example.co.uk").tld # => "co.uk"
def tld

This comment has been minimized.

Copy link
@weppos

weppos Nov 4, 2016

@sporkmonger FYI PublicSuffix 2.x requires Ruby 2.x, whereas I see addressable still provides 1.9 compatibility.

However, 1.9 users will experience a crash trying to execute this line, as it uses Ruby 2.x keyword arguments.

PublicSuffix.parse(self.host, ignore_private: true).tld
end

##
# Returns the public suffix domain for this host.
#
# @example
# Addressable::URI.parse("www.example.co.uk").domain # => "example.co.uk"
def domain
PublicSuffix.domain(self.host, ignore_private: true)
end

##
# The authority component for this URI.
# Combines the user, password, host, and port components.
Expand Down
78 changes: 78 additions & 0 deletions spec/addressable/uri_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,10 @@ def to_s
expect(@uri.normalized_host).to eq("example.com")
end

it "returns 'com' for #tld" do
expect(@uri.tld).to eq("com")
end

it "returns 'user:password@example.com:8080' for #authority" do
expect(@uri.authority).to eq("user:password@example.com:8080")
end
Expand Down Expand Up @@ -2344,6 +2348,80 @@ def to_s
end
end

describe Addressable::URI, "when parsed from " +
"'HTTP://EXAMPLE.COM/'" do
before do
@uri = Addressable::URI.parse("HTTP://EXAMPLE.COM/")
end

it "should be equivalent to http://example.com" do
expect(@uri).to eq(Addressable::URI.parse("http://example.com"))
end

it "should correctly convert to a hash" do
expect(@uri.to_hash).to eq({
:scheme => "HTTP",
:user => nil,
:password => nil,
:host => "EXAMPLE.COM",
:port => nil,
:path => "/",
:query => nil,
:fragment => nil
})
end

it "should be identical to its duplicate" do
expect(@uri).to eq(@uri.dup)
end

it "should have an origin of 'http://example.com'" do
expect(@uri.origin).to eq('http://example.com')
end

it "should have a tld of 'com'" do
expect(@uri.tld).to eq('com')
end
end

describe Addressable::URI, "when parsed from " +
"'http://www.example.co.uk/'" do
before do
@uri = Addressable::URI.parse("http://www.example.co.uk/")
end

it "should have an origin of 'http://www.example.co.uk'" do
expect(@uri.origin).to eq('http://www.example.co.uk')
end

it "should have a tld of 'co.uk'" do
expect(@uri.tld).to eq('co.uk')
end

it "should have a domain of 'example.co.uk'" do
expect(@uri.domain).to eq('example.co.uk')
end
end

describe Addressable::URI, "when parsed from " +
"'http://sub_domain.blogspot.com/'" do
before do
@uri = Addressable::URI.parse("http://sub_domain.blogspot.com/")
end

it "should have an origin of 'http://sub_domain.blogspot.com'" do
expect(@uri.origin).to eq('http://sub_domain.blogspot.com')
end

it "should have a tld of 'com'" do
expect(@uri.tld).to eq('com')
end

it "should have a domain of 'blogspot.com'" do
expect(@uri.domain).to eq('blogspot.com')
end
end

describe Addressable::URI, "when parsed from " +
"'http://example.com/~smith/'" do
before do
Expand Down
12 changes: 3 additions & 9 deletions tasks/gem.rake
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ namespace :gem do

s.required_ruby_version = '>= 1.9.0'

s.add_runtime_dependency 'public_suffix', '~> 2.0', '>= 2.0.3'
s.add_development_dependency 'bundler', '~> 1.0'

s.require_path = "lib"
Expand All @@ -39,15 +40,8 @@ namespace :gem do
desc "Generates .gemspec file"
task :gemspec do
spec_string = GEM_SPEC.to_ruby

begin
Thread.new { eval("$SAFE = 3\n#{spec_string}", binding) }.join
rescue
abort "unsafe gemspec: #{$!}"
else
File.open("#{GEM_SPEC.name}.gemspec", 'w') do |file|
file.write spec_string
end
File.open("#{GEM_SPEC.name}.gemspec", 'w') do |file|
file.write spec_string
end
end

Expand Down

2 comments on commit f032606

@iainbeeston
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sporkmonger This change means addressable (and any gems depending on it) will only work with ruby 2.0+ - is that intentional? (At the moment the travis build for ruby 1.9 is failing because of that)

@sporkmonger
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It wasn't entirely intentional, but a number of development dependencies have also dropped support for 1.9, so it simplifies a number of things.

Please sign in to comment.