aboutsummaryrefslogtreecommitdiff
path: root/tests/url
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2018-09-29 00:12:26 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2018-10-09 21:07:02 +0300
commitec9c6f1bbdfd3d86fba493ea56473c0aaf9acad1 (patch)
tree85f063f5fa0ea307d0c8f67e39fdfdd93731cb89 /tests/url
parent758b64bcf02d9269ae4765ab98d7d46396b3e69a (diff)
Add support for rootless URLs
Diffstat (limited to 'tests/url')
-rw-r--r--tests/url/driver.cxx86
-rw-r--r--tests/url/testscript21
2 files changed, 82 insertions, 25 deletions
diff --git a/tests/url/driver.cxx b/tests/url/driver.cxx
index 64bc2b5..dd124cd 100644
--- a/tests/url/driver.cxx
+++ b/tests/url/driver.cxx
@@ -33,7 +33,8 @@ enum class scheme
{
http,
https,
- file
+ file,
+ pkcs11
};
namespace butl
@@ -47,37 +48,63 @@ namespace butl
using scheme_type = scheme;
using authority_type = basic_url_authority<string_type>;
- static scheme_type
+ static optional<scheme_type>
translate_scheme (const string_type& url,
string_type&& scheme,
- optional<authority_type>& /*authority*/,
+ optional<authority_type>& authority,
optional<path_type>& path,
- optional<string_type>& /*query*/,
- optional<string_type>& /*fragment*/)
+ optional<string_type>& query,
+ optional<string_type>& /*fragment*/,
+ bool& rootless)
{
- // Note that we must compare case-insensitive in the real program.
- //
- if (scheme == L"http")
- return scheme_type::http;
- else if (scheme == L"https")
- return scheme_type::https;
- else if (scheme == L"file")
- return scheme_type::file;
- else if (scheme.empty ())
+ if (scheme.empty ())
{
// If the URL looks like an absolute filesystem path, then translate it
- // to the file URL. If it is not, then leave all the components absent
- // to fail with a proper exception description.
+ // to the file URL. If it is not, then return nullopt to fail with a
+ // proper exception description.
//
wchar_t c;
if ((c = url[0]) == '/' ||
(url.size () > 2 && alpha (c) && url[1] == ':' && url[2] == '/'))
+ {
path = url;
+ rootless = false;
+ return scheme_type::file;
+ }
- return scheme_type::file;
+ return nullopt;
}
+
+ scheme_type t;
+
+ // Note that we must compare case-insensitive in the real program.
+ //
+ if (scheme == L"http")
+ t = scheme_type::http;
+ else if (scheme == L"https")
+ t = scheme_type::https;
+ else if (scheme == L"file")
+ t = scheme_type::file;
+ else if (scheme == L"pkcs11")
+ t = scheme_type::pkcs11;
else
throw invalid_argument ("unknown scheme");
+
+ if (t != scheme_type::pkcs11 && !authority && !path && !query)
+ throw invalid_argument ("no authority, path or query");
+
+ if (path)
+ {
+ if (t == scheme_type::pkcs11)
+ {
+ if (!rootless || path->find (L'/') != string_type::npos)
+ throw invalid_argument ("unexpected slash");
+ }
+ else if (rootless)
+ throw invalid_argument ("rootless path");
+ }
+
+ return t;
}
// Translate scheme type back to its string representation.
@@ -88,13 +115,15 @@ namespace butl
const optional<authority_type>& /*authority*/,
const optional<path_type>& /*path*/,
const optional<string_type>& /*query*/,
- const optional<string_type>& /*fragment*/)
+ const optional<string_type>& /*fragment*/,
+ bool /*rootless*/)
{
switch (scheme)
{
- case scheme_type::http: return L"http";
- case scheme_type::https: return L"https";
- case scheme_type::file: return L"file";
+ case scheme_type::http: return L"http";
+ case scheme_type::https: return L"https";
+ case scheme_type::file: return L"file";
+ case scheme_type::pkcs11: return L"pkcs11";
}
assert (false); // Can't be here.
@@ -104,11 +133,19 @@ namespace butl
static path_type
translate_path (string_type&& path)
{
- return path_type (move (path));
+ // Note that a real pkcs11-supporting URL most likely would keep the
+ // path URL-encoded as its components can contain binary data. Or, it
+ // would split the path into components before decoding them.
+ //
+ return path_type (basic_url<string_type>::decode (path));
}
static string_type
- translate_path (const path_type& path) {return string_type (path);}
+ translate_path (const path_type& path)
+ {
+ using url = basic_url<string_type>;
+ return url::encode (path, [] (wchar_t& c) {return !url::path_char (c);});
+ }
};
}
@@ -317,7 +354,8 @@ try
nullopt,
nullopt,
nullopt,
- nullopt) << endl;
+ nullopt,
+ false) << endl;
}
else
wcout << L"[null]" << endl;
diff --git a/tests/url/testscript b/tests/url/testscript
index 4166007..05cc528 100644
--- a/tests/url/testscript
+++ b/tests/url/testscript
@@ -33,7 +33,6 @@ $*
:
{
$* 'file:#f' 2>'no authority, path or query' != 0 : fragment
- $* 'file:aaa' 2>'no authority, path or query' != 0 : junk
$* 'file:' 2>'no authority, path or query' != 0 : none
}
@@ -324,6 +323,24 @@ $*
[null]
[null]
EOO
+
+ $* 'http:a/b/c' 2>'rootless path' != 0 : rootless-path
+ $* 'pkcs11:/abc' 2>'unexpected slash' != 0 : unexpected-slash1
+ $* 'pkcs11:a/bc' 2>'unexpected slash' != 0 : unexpected-slash2
+ }
+
+ : rootless
+ :
+ {
+ : non-empty
+ :
+ $* 'pkcs11:token=sign;object=SIGN%20key' >>EOO
+ pkcs11
+ [null]
+ token=sign;object=SIGN key
+ [null]
+ [null]
+ EOO
}
: query
@@ -388,6 +405,8 @@ $*
$* 'file:/b%7C2' >'file:/b%7C2' : path
$* 'http://a?q=' >'http://a?q=' : query
$* 'http://a#f' >'http://a#f' : fragment
+
+ $* 'pkcs11:object=SIGN%20key' >'pkcs11:object=SIGN%20key' : rootless
}
: wstring