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

Allow use of absolute file paths on Windows #137

Closed
mustafaoral opened this issue Jan 12, 2022 · 1 comment
Closed

Allow use of absolute file paths on Windows #137

mustafaoral opened this issue Jan 12, 2022 · 1 comment
Milestone

Comments

@mustafaoral
Copy link
Contributor

When an absolute file path is used on Windows as the src parameter of the Image constructor, the execution fails because the plugin considers the value to be remote.

Image constructor does the following:

this.isRemoteUrl = typeof src === "string" && Util.isFullUrl(src);

Util.isFullUrl, in turn, tries to construct an instance of URL, and if this doesn't throw, returns true:

eleventy-img/img.js

Lines 88 to 96 in e009e56

static isFullUrl(url) {
try {
new URL(url);
return true;
} catch(e) {
// invalid url OR local path
return false;
}
}

This works fine on POSIX where local file paths, whether relative or absolute, result in an exception, but on Windows, a local file path is parsed without an exception if it's absolute: the output from console.log(new URL("C:\\file.txt").href) would be c:\file.txt.

As a result, isFullUrl returns true which is then assigned to isRemoteUrl, and an exception occurs later in the processing with the following stack trace:

`TypeError` was thrown:
    TypeError: Only absolute URLs are supported
        at getNodeRequestOptions (__redacted__\node_modules\node-fetch\lib\index.js:1327:9)
        at __redacted__\node_modules\node-fetch\lib\index.js:1432:19
        at new Promise (<anonymous>)
        at fetch (__redacted__\node_modules\node-fetch\lib\index.js:1429:9)
        at RemoteAssetCache.fetch (__redacted__\node_modules\@11ty\eleventy-cache-assets\src\RemoteAssetCache.js:53:25)
        at __redacted__\node_modules\@11ty\eleventy-img\img.js:260:54
        at run (__redacted__\node_modules\p-queue\dist\index.js:157:104)
        at PQueue._tryToStartAnother (__redacted__\node_modules\p-queue\dist\index.js:105:17)
        at __redacted__\node_modules\p-queue\dist\index.js:171:18
        at new Promise (<anonymous>)

This could be avoided by constructing the URL instance and then inspecting the protocol property. When a remote image is used, the value will be https: or http:. On Windows, if an instance can be constructed successfully, but the protocol isn't either of those, it can be deduced that src is an absolute file path.

I have tried the following on my machine:

static isFullUrl(url) {
  try {
    const validUrl = new URL(url);

    if (validUrl.protocol.startsWith("https:") || validUrl.protocol.startsWith("http:")) {
      return true;
    }

    return false;
  } catch (e) {
    // invalid url OR local path
    return false;
  }
}

It works without issues and transforms source images with an absolute path successfully.

I shall submit a PR to address this.

@mustafaoral
Copy link
Contributor Author

On a side note, running new URL("C:\\file.txt") has different results in different environments. In node 17.3.0 as well as Firefox, the properties are:

hash: ""
host: ""
hostname: ""
href: "c:\\file.txt"
origin: "null"
password: ""
pathname: "\\file.txt"
port: ""
protocol: "c:"
search: ""
searchParams: URLSearchParams { }
username: ""

Chromium seems to be doing a better job:

hash: ""
host: ""
hostname: ""
href: "file:///C:/file.txt"
origin: "file://"
password: ""
pathname: "/C:/file.txt"
port: ""
protocol: "file:"
search: ""
searchParams: URLSearchParams {}
username: ""

protocol is identified as file: and href is formatted to be compliant with RFC 8089.

mustafaoral added a commit to mustafaoral/eleventy-img that referenced this issue Jan 12, 2022
zachleat added a commit that referenced this issue Feb 23, 2022
…-on-windows

Adds ability to use absolute file paths on Windows. Fixes #137
@zachleat zachleat added this to the v1.0.1 milestone Feb 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants