Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change URI#to_s to handle default ports for more schemes than http/https #5233

Merged
merged 26 commits into from
Jan 2, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
d844362
Change URI#to_s to handle default ports for more schemes than http/https
lachlan Nov 2, 2017
6077c5b
Change DEFAULT_PORTS to be a constant rather than class variable
lachlan Nov 2, 2017
18a0728
Rename method to default_port? and move nil check back to #to_s
lachlan Nov 2, 2017
b886778
Remove unnecessary return statement from default_port? method
lachlan Nov 3, 2017
23a825e
Add URI.default_ports method, which allows for default ports to
lachlan Nov 4, 2017
5cb8564
Fix URI::DefaultPorts#[]= to downcase scheme on delete
lachlan Nov 4, 2017
57a2936
Add URI.default_port method for returning a scheme's the default port
lachlan Nov 4, 2017
965ccde
Rename URI.default_ports method to URI.default_port, allowing
lachlan Nov 4, 2017
a665fe4
Fix method comments to use back ticks consistently
lachlan Nov 4, 2017
82fa4c4
Change DefaultPort class to use instance variable rather than class
lachlan Nov 4, 2017
1fe8e52
Simplify to use two methods: URI.default_port and URI.set_default_port
lachlan Nov 4, 2017
43df609
Fix the method documentation formatting
lachlan Nov 4, 2017
a43adff
Add more well-known default ports sourced from IANA via Mahmoud's
lachlan Nov 4, 2017
aeffdf4
Fix #default_port? to correctly handle nil scheme
lachlan Nov 4, 2017
5923d8e
Change URI default port API to return a mutable subclass of Hash
lachlan Nov 5, 2017
3afe221
Change DefaultPortHash seeding to use merge! method
lachlan Nov 5, 2017
88c7a5f
Fix default_port? to not call scheme.downcase unnecessarily
lachlan Nov 5, 2017
b64d394
Add spec for URI with nil scheme and non-nil port
lachlan Nov 5, 2017
1684fab
Change DefaultPortHash seeds to be an initialize parameter
lachlan Nov 5, 2017
4c10f9f
Fix DefaultPortHash case insensitive keys for methods other than []= …
lachlan Nov 5, 2017
d8af953
Revert to using two methods: URI.default_port and URI.set_default_port
lachlan Nov 5, 2017
4f8dd3e
Fix typo in URI.default_port comment
lachlan Nov 5, 2017
fa62ae9
Fix typo in URI.set_default_port comment
lachlan Nov 5, 2017
de6329b
Fix URI.set_default_port comment formatting for scheme parameter
lachlan Nov 5, 2017
7dec28c
Fix URI#default_port? to be thread safe
lachlan Nov 24, 2017
bb3f56a
Change URI.set_default_port to always return nil
lachlan Nov 25, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions spec/std/uri_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,28 @@ describe "URI" do
end
end

describe ".default_ports" do
it "returns default port for well known schemes" do
URI.default_ports["http"].should eq(80)
URI.default_ports["https"].should eq(443)
end

it "returns nil for unknown schemes" do
URI.default_ports["xyz"].should eq(nil)
end

it "registers port for scheme" do
URI.default_ports["ponzi"] = 9999
URI.default_ports["ponzi"].should eq(9999)
end

it "unregisters port for scheme" do
URI.default_ports["ftp"].should eq(21)
URI.default_ports["ftp"] = nil
URI.default_ports["ftp"].should eq(nil)
end
end

describe ".unescape" do
{
{"hello", "hello"},
Expand Down
50 changes: 35 additions & 15 deletions src/uri.cr
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require "./uri/uri_default_ports"
require "./uri/uri_parser"

# This class represents a URI reference as defined by [RFC 3986: Uniform Resource Identifier
Expand Down Expand Up @@ -427,22 +428,41 @@ class URI
end
end

DEFAULT_PORTS = {
"ftp" => 21,
"ftps" => 990,
"gopher" => 70,
"http" => 80,
"https" => 443,
"ldap" => 389,
"ldaps" => 636,
"nntp" => 119,
"scp" => 22,
"sftp" => 22,
"ssh" => 22,
"telnet" => 23,
}
# The global registry for URI scheme default ports.
@@default_ports = DefaultPorts.new

# Returns the global registry for URI schemes and their respective
# default ports.
#
# The registry can then be used to query the default port for a
# given scheme.
#
# ```
# URI.default_ports["http"] # => 80
# URI.default_ports["ponzi"] # => nil
# ```
#
# Or it can be used to register the default port for a given
# scheme.
#
# ```
# URI.default_ports["ponzi"] = 9999
# URI.default_ports["ponzi"] # => 9999
# ```
#
# Or it can be used to unregister the default port for a given
# scheme.
#
# ```
# URI.default_ports["ponzi"] = nil
# URI.default_ports["ponzi"] # => nil
# ```
def self.default_ports
@@default_ports
end

# Returns true if this URI's port is the default port for its scheme.
private def default_port?
port == DEFAULT_PORTS[scheme]?
port == @@default_ports[scheme]
end
end
49 changes: 49 additions & 0 deletions src/uri/uri_default_ports.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
class URI
# Global registry for URI scheme default ports.
private class DefaultPorts
# Well-known schemes and their respective default ports.
@@default_ports = {
"ftp" => 21,
"ftps" => 990,
"gopher" => 70,
"http" => 80,
"https" => 443,
"ldap" => 389,
"ldaps" => 636,
"nntp" => 119,
"scp" => 22,
"sftp" => 22,
"ssh" => 22,
"telnet" => 23,
}

# Returns the default port for the given `scheme` if known,
# otherwise returns `nil`.
#
# ```
# default_ports = DefaultPorts.new
# default_ports["http"] # => 80
# default_ports["ponzi"] # => nil
# ```
def [](scheme : String?) : Int32?
Copy link
Contributor

Choose a reason for hiding this comment

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

Why allow a nil scheme here? It should be String only imo

return nil if scheme.nil?
@@default_ports[scheme.downcase]?
end

# Globally registers the default `port` for the given `scheme`.
#
# ```
# default_ports = DefaultPorts.new
# default_ports["ponzi"] # => nil
# default_ports["ponzi"] = 9999
# default_ports["ponzi"] # => 9999
# ```
def []=(scheme : String, port : Int32?)
if port
@@default_ports[scheme.downcase] = port
else
@@default_ports.delete scheme
end
end
end
end