Skip to content

Commit

Permalink
Fix CD/DVD URLs parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
imobachgs committed Aug 8, 2016
1 parent 2d15f90 commit e0d150d
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 17 deletions.
27 changes: 18 additions & 9 deletions library/types/src/modules/URL.rb
Expand Up @@ -274,6 +274,8 @@ def Parse(url)
Ops.set(tokens, "domain", Ops.get(options, "workgroup", ""))
end
end

tokens = merge_host_and_path(tokens) if SCHEMES_WO_HOST.include?(tokens["scheme"].downcase)
Builtins.y2debug("tokens=%1", tokens)
deep_copy(tokens)
end
Expand Down Expand Up @@ -368,7 +370,7 @@ def Build(tokens)
userpass = Ops.add(userpass, "@")
end

url = Builtins.sformat("%1:#{scheme_separator(tokens["scheme"])}%2", url, userpass)
url = Builtins.sformat("%1://%2", url, userpass)
Builtins.y2debug("url: %1", url)

if Hostname.CheckFQ(Ops.get_string(tokens, "host", "")) ||
Expand Down Expand Up @@ -653,17 +655,24 @@ def HidePasswordToken(tokens)

# Schemes which should use a single slash.
# see #schema_separator
SINGLE_SLASH_SCHEMES = ["cd", "dvd"].freeze
SCHEMES_WO_HOST = ["cd", "dvd"].freeze

# Returns the separator to be used given a scheme
# Merges host and path tokens
#
# In schemes like 'cd' or 'dvd' the host part is not allowed.
# It leads to conversions like: "cd:/?device=/dev/sr0" to "cd://?device=/dev/sr0"
# or "cd:/info" to "cd://info".
#
# Schemes like 'cd' or 'dvd' should used a single '/' character to separate
# the <scheme> and the <scheme-specific-part> (bsc#991935)
# If no host or path are specified, the path is set to "/".
#
# @param scheme [String] URI scheme
# @return [String] Separator to be used
def scheme_separator(scheme)
SINGLE_SLASH_SCHEMES.include?(scheme.downcase) ? "/" : "//"
# @param [Hash<String,String>] URL tokens
# @return [Hash<String,String>] URL tokens with host and path merged
def merge_host_and_path(tokens)
parts = [tokens["host"], tokens["path"]].reject { |t| t.empty? }
tokens.merge(
"path" => File.join("/", *parts),
"host" => ""
)
end
end

Expand Down
114 changes: 106 additions & 8 deletions library/types/test/url_test.rb
Expand Up @@ -25,23 +25,121 @@
it "returns a hash containing the token extracted from the URL" do
expect(subject.Parse(url)).to eq(tokens)
end

context "given a CD/DVD with a file" do
let(:url) { "cd:/some/file" }
let(:tokens) do
{
"scheme" => "cd",
"host" => "",
"path" => "/some/file",
"fragment" => "",
"user" => "",
"pass" => "",
"port" => "",
"query" => ""
}
end

it "returns a hash containing 'scheme' and 'path'" do
expect(subject.Parse(url)).to eq(tokens)
end
end

context "given a CD/DVD with a device" do
let(:url) { "cd:/?device=/dev/sr0" }
let(:tokens) do
{
"scheme" => "cd",
"host" => "",
"path" => "/",
"fragment" => "",
"user" => "",
"pass" => "",
"port" => "",
"query" => "device=/dev/sr0"
}
end

it "returns a hash containing 'scheme', 'path' and 'query'" do
expect(subject.Parse(url)).to eq(tokens)
end
end

context "given a CD/DVD with a device and a path" do
let(:url) { "cd:/some/file?device=/dev/sr0" }
let(:tokens) do
{
"scheme" => "cd",
"host" => "",
"path" => "/some/file",
"fragment" => "",
"user" => "",
"pass" => "",
"port" => "",
"query" => "device=/dev/sr0"
}
end

it "returns a hash containing 'scheme', 'path' and 'query'" do
expect(subject.Parse(url)).to eq(tokens)
end
end
end

describe ".Build" do
it "returns the URL for the given tokens" do
expect(subject.Build(tokens)).to eq(url)
end

context "given a cd/dvd URL" do
let(:tokens) do
{
"scheme" => "cd",
"query" => "device=/dev/sr0"
}
context "given CD/DVD tokens including a device" do
context "with a device" do
let(:tokens) do
{
"scheme" => "cd",
"query" => "device=/dev/sr0",
"path" => "/"
}
end

it "returns a URL of the form 'cd:///?<device>'" do
expect(subject.Build(tokens)).to eq("cd:///?device=/dev/sr0")
end
end

it "returns a URL containing which a single slash to separate the schema from the rest" do
expect(subject.Build(tokens)).to eq("cd:/?device=/dev/sr0")
context "with a directory" do
let(:tokens) do
{
"scheme" => "cd",
"path" => "/dir"
}
end

it "returns a URL of the form 'cd:///<dir>'" do
expect(subject.Build(tokens)).to eq("cd:///dir")
end
end
end
end

describe "URLs rebuilding" do
# This intention of these tests is to check if URLs are rebuilt correctly.

URLS = {
"dvd:/dir" => "dvd:///dir",
"dvd://dir" => "dvd:///dir",
"dvd:///dir" => "dvd:///dir",
"cd:/?device=/dev/sr0" => "cd:///?device=/dev/sr0",
"cd:/some/file?device=/dev/sr0" => "cd:///some/file?device=/dev/sr0",
"cd:///some/file?device=/dev/sr0" => "cd:///some/file?device=/dev/sr0",
"http://u:p@suse.de/a#b" => "http://u:p@suse.de/a#b"
}

URLS.each do |url, rebuilt|
context "given #{url}" do
it "returns #{rebuilt}" do
expect(subject.Build(subject.Parse(url))).to eq(rebuilt)
end
end
end
end
Expand Down

0 comments on commit e0d150d

Please sign in to comment.