URLComponents
を使用してURL
を作成しようとしています。
ただし、コンポーネントのurl
プロパティにアクセスすると、nilになります。
例...
var urlComponents = URLComponents(string: "http://google.com")!
urlComponents.path = "auth/login"
その後、私は...
print(urlComponents)
出力...
scheme: http Host: google.com path: auth/login
- scheme : "http"
- Host : "google.com"
- path : "auth/login"
しかしその後...
print(urlComponents.url)
nil
を出力します。
私はこれで何か悪いことをしていますか?これらすべてから完全な形式のURLを取得するにはどうすればよいですか?ありがとう
path
パラメータの文字列は/
で始まる必要があるようです。
したがって、"auth/login"
を"/auth/login"
に変更してください。
TL; DR
WebのURL(http://example.com/path
など)を作成する場合は、/
を含めます。これは、次のテンプレートを使用しているためです。
{scheme}://{user}:{password}@{Host}:{port}{path}?{query}#{fragment}
Web以外のURL(mailto:[email protected]
など)を作成する場合は、/
を含めないでください。次のテンプレートが使用されているためです。
{scheme}:{path}?{query}%23{fragment}
これが発生している理由を明確にするために、 URLComponents の実際のテンプレートは次のとおりです。
{scheme}://{user}:{password}@{Host}:{port}{path}?{query}#{fragment}
2つのコンポーネント間に句読点(://
、:
、@
、:
、?
、#
)があることに注意してくださいexcept({port}
および{path}
の場合)。
そのため、{path}
の前に句読点(/
)を付ける必要があります。そうしないと、無効なURLが生成されます。
あなたのケースではあなたが使用する必要があります:
urlComponents.path = "/auth/login"
URLComponentsの一般的ではないフィールドを省略しても、同じ問題が発生することに注意してください。
{scheme}://{Host}{path}?{query}#{fragment}
この場合も、{Host}
と{path}
が隣接しており、2つを区切る句読点がないことに注意してください。
Appleが{port}
の前に句読点を含めなかったのはなぜか疑問に思われるかもしれません。URLComponentsを使用して RFC 3986 仕様、Web URLだけでなく、たとえばhttp://www.example.com/foo
を簡単に生成できますが、mailto:[email protected]
という形式のURLを簡単に生成できます。
URLComponentsは、{scheme}
が省略されている場合に{path}
と{Host}
の間の区切り文字を変更することでこれを可能にします。
{scheme}:{path}?{query}%23{fragment}
したがって、mailtoリンクを作成する場合、実際にはパスに/
を含めないとします。
urlComponents.scheme = "mailto"
urlComponents.path = "[email protected]"
// urlComponents.url!.absoluteString == "mailto:[email protected]"
URLComponentsのプロパティをURLのプロパティと比較すると、もう少し洞察が得られます(そして少し不整合が明らかになります)。
let string = "scheme://user:password@Host:123/path/path/path/?query#fragment"
let urlComponents = URLComponents(string: string)!
let url = URL(string: string)!
// these are expected
url.absoluteString == urlComponents.url!.absoluteString
url.scheme == urlComponents.scheme
url.user == urlComponents.user
url.password == urlComponents.password
url.Host == urlComponents.Host
url.port == urlComponents.port
url.query == urlComponents.query
url.fragment == urlComponents.fragment
// this is unexpected. They should have been equal to each other
url.path != urlComponents.path
url.path == "/path/path/path"
urlComponents.path == "/path/path/path/"
url.pathComponents == ["/", "path", "path", "path"]
url.lastPathComponent == "path"
注意すべき2つの点:
url.path
の接尾辞には/
がありません。url.pathComponents[0]
は、URLの最初の/
です。テンプレートの完全なリストについては、次のコードを使用できます。
let componentsCount = Double(8)
let iterations = Int(pow(2, componentsCount))
for i in 0..<iterations {
var urlComponents = URLComponents()
var key = ""
if i & 0b10000000 > 0 { urlComponents.scheme = "scheme"; key += "s" } else { key += " " }
if i & 0b01000000 > 0 { urlComponents.user = "user"; key += "u" } else { key += " " }
if i & 0b00100000 > 0 { urlComponents.password = "password"; key += "w" } else { key += " " }
if i & 0b00010000 > 0 { urlComponents.Host = "Host"; key += "h" } else { key += " " }
if i & 0b00001000 > 0 { urlComponents.port = 123; key += "r" } else { key += " " }
if i & 0b00000100 > 0 { urlComponents.path = "/path"; key += "p" } else { key += " " }
if i & 0b00000010 > 0 { urlComponents.query = "query"; key += "q" } else { key += " " }
if i & 0b00000001 > 0 { urlComponents.fragment = "fragment"; key += "f" } else { key += " " }
if let url = urlComponents.url?.absoluteString {
print("[\(key)] \(url)")
} else {
print("[\(key)] ------- nil --------")
}
}
次の出力が生成されます。
[ ]
[ f] #fragment
[ q ] ?query
[ qf] ?query#fragment
[ p ] /path
[ p f] /path#fragment
[ pq ] /path?query
[ pqf] /path?query#fragment
[ r ] //:123
[ r f] //:123#fragment
[ r q ] //:123?query
[ r qf] //:123?query#fragment
[ rp ] //:123/path
[ rp f] //:123/path#fragment
[ rpq ] //:123/path?query
[ rpqf] //:123/path?query#fragment
[ h ] //Host
[ h f] //Host#fragment
[ h q ] //host?query
[ h qf] //host?query#fragment
[ h p ] //Host/path
[ h p f] //Host/path#fragment
[ h pq ] //Host/path?query
[ h pqf] //Host/path?query#fragment
[ hr ] //Host:123
[ hr f] //Host:123#fragment
[ hr q ] //Host:123?query
[ hr qf] //Host:123?query#fragment
[ hrp ] //Host:123/path
[ hrp f] //Host:123/path#fragment
[ hrpq ] //Host:123/path?query
[ hrpqf] //Host:123/path?query#fragment
[ w ] //:password@
[ w f] //:password@#fragment
[ w q ] //:password@?query
[ w qf] //:password@?query#fragment
[ w p ] //:password@/path
[ w p f] //:password@/path#fragment
[ w pq ] //:password@/path?query
[ w pqf] //:password@/path?query#fragment
[ w r ] //:password@:123
[ w r f] //:password@:123#fragment
[ w r q ] //:password@:123?query
[ w r qf] //:password@:123?query#fragment
[ w rp ] //:password@:123/path
[ w rp f] //:password@:123/path#fragment
[ w rpq ] //:password@:123/path?query
[ w rpqf] //:password@:123/path?query#fragment
[ wh ] //:password@Host
[ wh f] //:password@Host#fragment
[ wh q ] //:password@host?query
[ wh qf] //:password@host?query#fragment
[ wh p ] //:password@Host/path
[ wh p f] //:password@Host/path#fragment
[ wh pq ] //:password@Host/path?query
[ wh pqf] //:password@Host/path?query#fragment
[ whr ] //:password@Host:123
[ whr f] //:password@Host:123#fragment
[ whr q ] //:password@Host:123?query
[ whr qf] //:password@Host:123?query#fragment
[ whrp ] //:password@Host:123/path
[ whrp f] //:password@Host:123/path#fragment
[ whrpq ] //:password@Host:123/path?query
[ whrpqf] //:password@Host:123/path?query#fragment
[ u ] //user@
[ u f] //user@#fragment
[ u q ] //user@?query
[ u qf] //user@?query#fragment
[ u p ] //user@/path
[ u p f] //user@/path#fragment
[ u pq ] //user@/path?query
[ u pqf] //user@/path?query#fragment
[ u r ] //user@:123
[ u r f] //user@:123#fragment
[ u r q ] //user@:123?query
[ u r qf] //user@:123?query#fragment
[ u rp ] //user@:123/path
[ u rp f] //user@:123/path#fragment
[ u rpq ] //user@:123/path?query
[ u rpqf] //user@:123/path?query#fragment
[ u h ] //user@Host
[ u h f] //user@Host#fragment
[ u h q ] //user@host?query
[ u h qf] //user@host?query#fragment
[ u h p ] //user@Host/path
[ u h p f] //user@Host/path#fragment
[ u h pq ] //user@Host/path?query
[ u h pqf] //user@Host/path?query#fragment
[ u hr ] //user@Host:123
[ u hr f] //user@Host:123#fragment
[ u hr q ] //user@Host:123?query
[ u hr qf] //user@Host:123?query#fragment
[ u hrp ] //user@Host:123/path
[ u hrp f] //user@Host:123/path#fragment
[ u hrpq ] //user@Host:123/path?query
[ u hrpqf] //user@Host:123/path?query#fragment
[ uw ] //user:password@
[ uw f] //user:password@#fragment
[ uw q ] //user:password@?query
[ uw qf] //user:password@?query#fragment
[ uw p ] //user:password@/path
[ uw p f] //user:password@/path#fragment
[ uw pq ] //user:password@/path?query
[ uw pqf] //user:password@/path?query#fragment
[ uw r ] //user:password@:123
[ uw r f] //user:password@:123#fragment
[ uw r q ] //user:password@:123?query
[ uw r qf] //user:password@:123?query#fragment
[ uw rp ] //user:password@:123/path
[ uw rp f] //user:password@:123/path#fragment
[ uw rpq ] //user:password@:123/path?query
[ uw rpqf] //user:password@:123/path?query#fragment
[ uwh ] //user:password@Host
[ uwh f] //user:password@Host#fragment
[ uwh q ] //user:password@host?query
[ uwh qf] //user:password@host?query#fragment
[ uwh p ] //user:password@Host/path
[ uwh p f] //user:password@Host/path#fragment
[ uwh pq ] //user:password@Host/path?query
[ uwh pqf] //user:password@Host/path?query#fragment
[ uwhr ] //user:password@Host:123
[ uwhr f] //user:password@Host:123#fragment
[ uwhr q ] //user:password@Host:123?query
[ uwhr qf] //user:password@Host:123?query#fragment
[ uwhrp ] //user:password@Host:123/path
[ uwhrp f] //user:password@Host:123/path#fragment
[ uwhrpq ] //user:password@Host:123/path?query
[ uwhrpqf] //user:password@Host:123/path?query#fragment
[s ] scheme:
[s f] scheme:%23fragment
[s q ] scheme:?query
[s qf] scheme:?query%23fragment
[s p ] scheme:/path
[s p f] scheme:/path#fragment
[s pq ] scheme:/path?query
[s pqf] scheme:/path?query#fragment
[s r ] scheme://:123
[s r f] scheme://:123#fragment
[s r q ] scheme://:123?query
[s r qf] scheme://:123?query#fragment
[s rp ] scheme://:123/path
[s rp f] scheme://:123/path#fragment
[s rpq ] scheme://:123/path?query
[s rpqf] scheme://:123/path?query#fragment
[s h ] scheme://Host
[s h f] scheme://Host#fragment
[s h q ] scheme://host?query
[s h qf] scheme://host?query#fragment
[s h p ] scheme://Host/path
[s h p f] scheme://Host/path#fragment
[s h pq ] scheme://Host/path?query
[s h pqf] scheme://Host/path?query#fragment
[s hr ] scheme://Host:123
[s hr f] scheme://Host:123#fragment
[s hr q ] scheme://Host:123?query
[s hr qf] scheme://Host:123?query#fragment
[s hrp ] scheme://Host:123/path
[s hrp f] scheme://Host:123/path#fragment
[s hrpq ] scheme://Host:123/path?query
[s hrpqf] scheme://Host:123/path?query#fragment
[s w ] scheme://:password@
[s w f] scheme://:password@#fragment
[s w q ] scheme://:password@?query
[s w qf] scheme://:password@?query#fragment
[s w p ] scheme://:password@/path
[s w p f] scheme://:password@/path#fragment
[s w pq ] scheme://:password@/path?query
[s w pqf] scheme://:password@/path?query#fragment
[s w r ] scheme://:password@:123
[s w r f] scheme://:password@:123#fragment
[s w r q ] scheme://:password@:123?query
[s w r qf] scheme://:password@:123?query#fragment
[s w rp ] scheme://:password@:123/path
[s w rp f] scheme://:password@:123/path#fragment
[s w rpq ] scheme://:password@:123/path?query
[s w rpqf] scheme://:password@:123/path?query#fragment
[s wh ] scheme://:password@Host
[s wh f] scheme://:password@Host#fragment
[s wh q ] scheme://:password@host?query
[s wh qf] scheme://:password@host?query#fragment
[s wh p ] scheme://:password@Host/path
[s wh p f] scheme://:password@Host/path#fragment
[s wh pq ] scheme://:password@Host/path?query
[s wh pqf] scheme://:password@Host/path?query#fragment
[s whr ] scheme://:password@Host:123
[s whr f] scheme://:password@Host:123#fragment
[s whr q ] scheme://:password@Host:123?query
[s whr qf] scheme://:password@Host:123?query#fragment
[s whrp ] scheme://:password@Host:123/path
[s whrp f] scheme://:password@Host:123/path#fragment
[s whrpq ] scheme://:password@Host:123/path?query
[s whrpqf] scheme://:password@Host:123/path?query#fragment
[su ] scheme://user@
[su f] scheme://user@#fragment
[su q ] scheme://user@?query
[su qf] scheme://user@?query#fragment
[su p ] scheme://user@/path
[su p f] scheme://user@/path#fragment
[su pq ] scheme://user@/path?query
[su pqf] scheme://user@/path?query#fragment
[su r ] scheme://user@:123
[su r f] scheme://user@:123#fragment
[su r q ] scheme://user@:123?query
[su r qf] scheme://user@:123?query#fragment
[su rp ] scheme://user@:123/path
[su rp f] scheme://user@:123/path#fragment
[su rpq ] scheme://user@:123/path?query
[su rpqf] scheme://user@:123/path?query#fragment
[su h ] scheme://user@Host
[su h f] scheme://user@Host#fragment
[su h q ] scheme://user@host?query
[su h qf] scheme://user@host?query#fragment
[su h p ] scheme://user@Host/path
[su h p f] scheme://user@Host/path#fragment
[su h pq ] scheme://user@Host/path?query
[su h pqf] scheme://user@Host/path?query#fragment
[su hr ] scheme://user@Host:123
[su hr f] scheme://user@Host:123#fragment
[su hr q ] scheme://user@Host:123?query
[su hr qf] scheme://user@Host:123?query#fragment
[su hrp ] scheme://user@Host:123/path
[su hrp f] scheme://user@Host:123/path#fragment
[su hrpq ] scheme://user@Host:123/path?query
[su hrpqf] scheme://user@Host:123/path?query#fragment
[suw ] scheme://user:password@
[suw f] scheme://user:password@#fragment
[suw q ] scheme://user:password@?query
[suw qf] scheme://user:password@?query#fragment
[suw p ] scheme://user:password@/path
[suw p f] scheme://user:password@/path#fragment
[suw pq ] scheme://user:password@/path?query
[suw pqf] scheme://user:password@/path?query#fragment
[suw r ] scheme://user:password@:123
[suw r f] scheme://user:password@:123#fragment
[suw r q ] scheme://user:password@:123?query
[suw r qf] scheme://user:password@:123?query#fragment
[suw rp ] scheme://user:password@:123/path
[suw rp f] scheme://user:password@:123/path#fragment
[suw rpq ] scheme://user:password@:123/path?query
[suw rpqf] scheme://user:password@:123/path?query#fragment
[suwh ] scheme://user:password@Host
[suwh f] scheme://user:password@Host#fragment
[suwh q ] scheme://user:password@host?query
[suwh qf] scheme://user:password@host?query#fragment
[suwh p ] scheme://user:password@Host/path
[suwh p f] scheme://user:password@Host/path#fragment
[suwh pq ] scheme://user:password@Host/path?query
[suwh pqf] scheme://user:password@Host/path?query#fragment
[suwhr ] scheme://user:password@Host:123
[suwhr f] scheme://user:password@Host:123#fragment
[suwhr q ] scheme://user:password@Host:123?query
[suwhr qf] scheme://user:password@Host:123?query#fragment
[suwhrp ] scheme://user:password@Host:123/path
[suwhrp f] scheme://user:password@Host:123/path#fragment
[suwhrpq ] scheme://user:password@Host:123/path?query
[suwhrpqf] scheme://user:password@Host:123/path?query#fragment
これらのどれもnil
ではないことに注意してください。ただし、urlComponents.path = "/path"
をurlComponents.path = "path"
に変更すると、完全に異なるテンプレートセットが得られます。
[ ]
[ f] #fragment
[ q ] ?query
[ qf] ?query#fragment
[ p ] path
[ p f] path#fragment
[ pq ] path?query
[ pqf] path?query#fragment
[ r ] //:123
[ r f] //:123#fragment
[ r q ] //:123?query
[ r qf] //:123?query#fragment
[ rp ] ------- nil --------
[ rp f] ------- nil --------
[ rpq ] ------- nil --------
[ rpqf] ------- nil --------
[ h ] //Host
[ h f] //Host#fragment
[ h q ] //host?query
[ h qf] //host?query#fragment
[ h p ] ------- nil --------
[ h p f] ------- nil --------
[ h pq ] ------- nil --------
[ h pqf] ------- nil --------
[ hr ] //Host:123
[ hr f] //Host:123#fragment
[ hr q ] //Host:123?query
[ hr qf] //Host:123?query#fragment
[ hrp ] ------- nil --------
[ hrp f] ------- nil --------
[ hrpq ] ------- nil --------
[ hrpqf] ------- nil --------
[ w ] //:password@
[ w f] //:password@#fragment
[ w q ] //:password@?query
[ w qf] //:password@?query#fragment
[ w p ] ------- nil --------
[ w p f] ------- nil --------
[ w pq ] ------- nil --------
[ w pqf] ------- nil --------
[ w r ] //:password@:123
[ w r f] //:password@:123#fragment
[ w r q ] //:password@:123?query
[ w r qf] //:password@:123?query#fragment
[ w rp ] ------- nil --------
[ w rp f] ------- nil --------
[ w rpq ] ------- nil --------
[ w rpqf] ------- nil --------
[ wh ] //:password@Host
[ wh f] //:password@Host#fragment
[ wh q ] //:password@host?query
[ wh qf] //:password@host?query#fragment
[ wh p ] ------- nil --------
[ wh p f] ------- nil --------
[ wh pq ] ------- nil --------
[ wh pqf] ------- nil --------
[ whr ] //:password@Host:123
[ whr f] //:password@Host:123#fragment
[ whr q ] //:password@Host:123?query
[ whr qf] //:password@Host:123?query#fragment
[ whrp ] ------- nil --------
[ whrp f] ------- nil --------
[ whrpq ] ------- nil --------
[ whrpqf] ------- nil --------
[ u ] //user@
[ u f] //user@#fragment
[ u q ] //user@?query
[ u qf] //user@?query#fragment
[ u p ] ------- nil --------
[ u p f] ------- nil --------
[ u pq ] ------- nil --------
[ u pqf] ------- nil --------
[ u r ] //user@:123
[ u r f] //user@:123#fragment
[ u r q ] //user@:123?query
[ u r qf] //user@:123?query#fragment
[ u rp ] ------- nil --------
[ u rp f] ------- nil --------
[ u rpq ] ------- nil --------
[ u rpqf] ------- nil --------
[ u h ] //user@Host
[ u h f] //user@Host#fragment
[ u h q ] //user@host?query
[ u h qf] //user@host?query#fragment
[ u h p ] ------- nil --------
[ u h p f] ------- nil --------
[ u h pq ] ------- nil --------
[ u h pqf] ------- nil --------
[ u hr ] //user@Host:123
[ u hr f] //user@Host:123#fragment
[ u hr q ] //user@Host:123?query
[ u hr qf] //user@Host:123?query#fragment
[ u hrp ] ------- nil --------
[ u hrp f] ------- nil --------
[ u hrpq ] ------- nil --------
[ u hrpqf] ------- nil --------
[ uw ] //user:password@
[ uw f] //user:password@#fragment
[ uw q ] //user:password@?query
[ uw qf] //user:password@?query#fragment
[ uw p ] ------- nil --------
[ uw p f] ------- nil --------
[ uw pq ] ------- nil --------
[ uw pqf] ------- nil --------
[ uw r ] //user:password@:123
[ uw r f] //user:password@:123#fragment
[ uw r q ] //user:password@:123?query
[ uw r qf] //user:password@:123?query#fragment
[ uw rp ] ------- nil --------
[ uw rp f] ------- nil --------
[ uw rpq ] ------- nil --------
[ uw rpqf] ------- nil --------
[ uwh ] //user:password@Host
[ uwh f] //user:password@Host#fragment
[ uwh q ] //user:password@host?query
[ uwh qf] //user:password@host?query#fragment
[ uwh p ] ------- nil --------
[ uwh p f] ------- nil --------
[ uwh pq ] ------- nil --------
[ uwh pqf] ------- nil --------
[ uwhr ] //user:password@Host:123
[ uwhr f] //user:password@Host:123#fragment
[ uwhr q ] //user:password@Host:123?query
[ uwhr qf] //user:password@Host:123?query#fragment
[ uwhrp ] ------- nil --------
[ uwhrp f] ------- nil --------
[ uwhrpq ] ------- nil --------
[ uwhrpqf] ------- nil --------
[s ] scheme:
[s f] scheme:%23fragment
[s q ] scheme:?query
[s qf] scheme:?query%23fragment
[s p ] scheme:path
[s p f] scheme:path%23fragment
[s pq ] scheme:path?query
[s pqf] scheme:path?query%23fragment
[s r ] scheme://:123
[s r f] scheme://:123#fragment
[s r q ] scheme://:123?query
[s r qf] scheme://:123?query#fragment
[s rp ] ------- nil --------
[s rp f] ------- nil --------
[s rpq ] ------- nil --------
[s rpqf] ------- nil --------
[s h ] scheme://Host
[s h f] scheme://Host#fragment
[s h q ] scheme://host?query
[s h qf] scheme://host?query#fragment
[s h p ] ------- nil --------
[s h p f] ------- nil --------
[s h pq ] ------- nil --------
[s h pqf] ------- nil --------
[s hr ] scheme://Host:123
[s hr f] scheme://Host:123#fragment
[s hr q ] scheme://Host:123?query
[s hr qf] scheme://Host:123?query#fragment
[s hrp ] ------- nil --------
[s hrp f] ------- nil --------
[s hrpq ] ------- nil --------
[s hrpqf] ------- nil --------
[s w ] scheme://:password@
[s w f] scheme://:password@#fragment
[s w q ] scheme://:password@?query
[s w qf] scheme://:password@?query#fragment
[s w p ] ------- nil --------
[s w p f] ------- nil --------
[s w pq ] ------- nil --------
[s w pqf] ------- nil --------
[s w r ] scheme://:password@:123
[s w r f] scheme://:password@:123#fragment
[s w r q ] scheme://:password@:123?query
[s w r qf] scheme://:password@:123?query#fragment
[s w rp ] ------- nil --------
[s w rp f] ------- nil --------
[s w rpq ] ------- nil --------
[s w rpqf] ------- nil --------
[s wh ] scheme://:password@Host
[s wh f] scheme://:password@Host#fragment
[s wh q ] scheme://:password@host?query
[s wh qf] scheme://:password@host?query#fragment
[s wh p ] ------- nil --------
[s wh p f] ------- nil --------
[s wh pq ] ------- nil --------
[s wh pqf] ------- nil --------
[s whr ] scheme://:password@Host:123
[s whr f] scheme://:password@Host:123#fragment
[s whr q ] scheme://:password@Host:123?query
[s whr qf] scheme://:password@Host:123?query#fragment
[s whrp ] ------- nil --------
[s whrp f] ------- nil --------
[s whrpq ] ------- nil --------
[s whrpqf] ------- nil --------
[su ] scheme://user@
[su f] scheme://user@#fragment
[su q ] scheme://user@?query
[su qf] scheme://user@?query#fragment
[su p ] ------- nil --------
[su p f] ------- nil --------
[su pq ] ------- nil --------
[su pqf] ------- nil --------
[su r ] scheme://user@:123
[su r f] scheme://user@:123#fragment
[su r q ] scheme://user@:123?query
[su r qf] scheme://user@:123?query#fragment
[su rp ] ------- nil --------
[su rp f] ------- nil --------
[su rpq ] ------- nil --------
[su rpqf] ------- nil --------
[su h ] scheme://user@Host
[su h f] scheme://user@Host#fragment
[su h q ] scheme://user@host?query
[su h qf] scheme://user@host?query#fragment
[su h p ] ------- nil --------
[su h p f] ------- nil --------
[su h pq ] ------- nil --------
[su h pqf] ------- nil --------
[su hr ] scheme://user@Host:123
[su hr f] scheme://user@Host:123#fragment
[su hr q ] scheme://user@Host:123?query
[su hr qf] scheme://user@Host:123?query#fragment
[su hrp ] ------- nil --------
[su hrp f] ------- nil --------
[su hrpq ] ------- nil --------
[su hrpqf] ------- nil --------
[suw ] scheme://user:password@
[suw f] scheme://user:password@#fragment
[suw q ] scheme://user:password@?query
[suw qf] scheme://user:password@?query#fragment
[suw p ] ------- nil --------
[suw p f] ------- nil --------
[suw pq ] ------- nil --------
[suw pqf] ------- nil --------
[suw r ] scheme://user:password@:123
[suw r f] scheme://user:password@:123#fragment
[suw r q ] scheme://user:password@:123?query
[suw r qf] scheme://user:password@:123?query#fragment
[suw rp ] ------- nil --------
[suw rp f] ------- nil --------
[suw rpq ] ------- nil --------
[suw rpqf] ------- nil --------
[suwh ] scheme://user:password@Host
[suwh f] scheme://user:password@Host#fragment
[suwh q ] scheme://user:password@host?query
[suwh qf] scheme://user:password@host?query#fragment
[suwh p ] ------- nil --------
[suwh p f] ------- nil --------
[suwh pq ] ------- nil --------
[suwh pqf] ------- nil --------
[suwhr ] scheme://user:password@Host:123
[suwhr f] scheme://user:password@Host:123#fragment
[suwhr q ] scheme://user:password@Host:123?query
[suwhr qf] scheme://user:password@Host:123?query#fragment
[suwhrp ] ------- nil --------
[suwhrp f] ------- nil --------
[suwhrpq ] ------- nil --------
[suwhrpqf] ------- nil --------