diff --git a/src/node_url.cc b/src/node_url.cc index 4d57027dd29ce9..acc423d931b603 100644 --- a/src/node_url.cc +++ b/src/node_url.cc @@ -2348,6 +2348,19 @@ std::string URL::ToFilePath() const { #endif } +URL URL::FromFilePath(const std::string& file_path) { + URL url("file://"); + std::string escaped_file_path; + for (size_t i = 0; i < file_path.length(); ++i) { + escaped_file_path += file_path[i]; + if (file_path[i] == '%') + escaped_file_path += "25"; + } + URL::Parse(escaped_file_path.c_str(), escaped_file_path.length(), kPathStart, + &url.context_, true, nullptr, false); + return url; +} + // This function works by calling out to a JS function that creates and // returns the JS URL object. Be mindful of the JS<->Native boundary // crossing that is required. diff --git a/src/node_url.h b/src/node_url.h index b2eadf9923a7ea..5e61aee4efbd5a 100644 --- a/src/node_url.h +++ b/src/node_url.h @@ -169,6 +169,8 @@ class URL { // Get the path of the file: URL in a format consumable by native file system // APIs. Returns an empty string if something went wrong. std::string ToFilePath() const; + // Get the file URL from native file system path. + static URL FromFilePath(const std::string& file_path); const Local ToObject(Environment* env) const; diff --git a/test/cctest/test_url.cc b/test/cctest/test_url.cc index 088634152a79c1..2e9b06e3a4783a 100644 --- a/test/cctest/test_url.cc +++ b/test/cctest/test_url.cc @@ -109,3 +109,36 @@ TEST_F(URLTest, ToFilePath) { #undef T } + +TEST_F(URLTest, FromFilePath) { + URL file_url; +#ifdef _WIN32 + file_url = URL::FromFilePath("C:\\Program Files\\"); + EXPECT_EQ("file:", file_url.protocol()); + EXPECT_EQ("/C:/Program%20Files/", file_url.path()); + + file_url = URL::FromFilePath("C:\\a\\b\\c"); + EXPECT_EQ("file:", file_url.protocol()); + EXPECT_EQ("/C:/a/b/c", file_url.path()); + + file_url = URL::FromFilePath("b:\\a\\%%.js"); + EXPECT_EQ("file:", file_url.protocol()); + EXPECT_EQ("/b:/a/%25%25.js", file_url.path()); + + file_url = URL::FromFilePath("\\\\host\\a\\b\\c"); + EXPECT_EQ("file:", file_url.protocol()); + EXPECT_EQ("host/a/b/c", file_url.path()); +#else + file_url = URL::FromFilePath("/"); + EXPECT_EQ("file:", file_url.protocol()); + EXPECT_EQ("/", file_url.path()); + + file_url = URL::FromFilePath("/a/b/c"); + EXPECT_EQ("file:", file_url.protocol()); + EXPECT_EQ("/a/b/c", file_url.path()); + + file_url = URL::FromFilePath("/a/%%.js"); + EXPECT_EQ("file:", file_url.protocol()); + EXPECT_EQ("/a/%25%25.js", file_url.path()); +#endif +}