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

Question: syntax for abs paths passed as file:// URLs in Windows? #3730

Open
jaimergp opened this issue Jan 6, 2025 · 4 comments
Open

Question: syntax for abs paths passed as file:// URLs in Windows? #3730

jaimergp opened this issue Jan 6, 2025 · 4 comments
Labels
type::question Further information is requested

Comments

@jaimergp
Copy link
Contributor

jaimergp commented Jan 6, 2025

What's the actual way? Given this absolute path in Windows D:\a_\temp\popen-gw0\test_croot_with_spaces0\space path:

>>> from libmambapy.specs import CondaURL
>>> CondaURL.parse("file:///D:/a/_temp/popen-gw0/test_croot_with_spaces0/space path")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
libmambapy.bindings.specs.ParseError: Failed to parse URL "file:///D:/a/_temp/popen-gw0/test_croot_with_spaces0/space path": Malformed input to a URL function
>>> CondaURL.parse("file:///D:/a/_temp/popen-gw0/test_croot_with_spaces0/space%20path
")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
libmambapy.bindings.specs.ParseError: Failed to parse URL "file:///D:/a/_temp/popen-gw0/test_croot_with_spaces0/space%20path": Bad file:// URL
>>> CondaURL.parse("file:///D/a/_temp/popen-gw0/test_croot_with_spaces0/space path")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
libmambapy.bindings.specs.ParseError: Failed to parse URL "file:///D/a/_temp/popen-gw0/test_croot_with_spaces0/space path": Malformed input to a URL function
>>> CondaURL.parse("file:///D/a/_temp/popen-gw0/test_croot_with_spaces0/space%20path"
)
file:///D/a/_temp/popen-gw0/test_croot_with_spaces0/space%20path

Only the last one (without the : in the drive letter) is accepted, but not sure if that's understood as a Windows path internally? Should I always remove the : in the drive?

@jaimergp
Copy link
Contributor Author

jaimergp commented Jan 6, 2025

Seeing comments like this one:

/**
* Set the path from a not encoded value.
*
* All '/' are not encoded but interpreted as separators.
* On windows with a file scheme, the colon after the drive letter is not encoded.
* A leading '/' is added if abscent.
*/

makes me think it should be accepted?

@kenodegard
Copy link
Contributor

Per this blogpost from the IE team back in 2006, the proper syntax is as follows:

Screenshot 2025-01-06 at 16 17 23

@kenodegard
Copy link
Contributor

Reading the file_uri_unc2_to_unc4 implementation:

auto file_uri_unc2_to_unc4(std::string_view uri) -> std::string
{
static constexpr std::string_view file_scheme = "file:";
// Not "file:" scheme
if (!util::starts_with(uri, file_scheme))
{
return std::string(uri);
}
// No hostname set in "file://hostname/path/to/data.xml"
auto [slashes, rest] = util::lstrip_parts(util::remove_prefix(uri, file_scheme), '/');
if (slashes.size() != 2)
{
return std::string(uri);
}
const auto s_idx = rest.find('/');
const auto c_idx = rest.find(':');
// ':' found before '/', a Windows drive is specified in "file://C:/path/to/data.xml" (not
// really URI compliant, they should have "file:///" or "file:/"). Otherwise no path in
// "file://hostname", also not URI compliant.
if (c_idx < s_idx)
{
return std::string(uri);
}
const auto hostname = rest.substr(0, s_idx);
// '\' are used as path separator in "file://\\hostname\path\to\data.xml" (also not RFC
// compliant)
if (util::starts_with(hostname, R"(\\)"))
{
return std::string(uri);
}
// Things that means localhost are kept for some reason in ``url_to_path``
// in ``conda.common.path``
if ((hostname == "localhost") || (hostname == "127.0.0.1") || (hostname == "::1"))
{
return std::string(uri);
}
return util::concat("file:////", rest);
}

And testing some more, it seems CondaURL wants 4 leading / and %-encoded spaces:

>>> from libmambapy.specs import CondaURL
>>> CondaURL.parse("file:////D:/a_/temp/popen-gw0/test_croot_with_spaces0/space%20path")
file:////D:/a_/temp/popen-gw0/test_croot_with_spaces0/space%20path

@jaimergp
Copy link
Contributor Author

jaimergp commented Jan 7, 2025

It works with 4+ leading /, so I don't think it was intended. file:///C:/path/to/file should be legal imo.

@jjerphan jjerphan added the type::question Further information is requested label Jan 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type::question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants