From 45b1e6ffd518ceb62e4329aa433898b7b3fd96e1 Mon Sep 17 00:00:00 2001
From: Nemo <commits@captnemo.in>
Date: Wed, 21 Jul 2021 18:54:40 +0530
Subject: [PATCH] Adds support for downloading and checking files

---
 CHANGELOG.md      |   4 ++++
 README.md         |   8 +++++++-
 package-lock.json | 216 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 package.json      |   7 +++++--
 src/archive.js    |  50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/index.js      | 174 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
 src/zip.js        |  41 -----------------------------------------
 7 files changed, 389 insertions(+), 111 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1e61c79..56858ff 100644
--- a/CHANGELOG.md
+++ a/CHANGELOG.md
@@ -1,8 +1,12 @@
 # Changelog
 
 All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
+## 1.0.2
+### Added
+- Now supports checking URLs directly.
+
 ## 1.0.1
 
 - Support ARM64 builds for Mac/Windows/Linux
diff --git a/README.md b/README.md
index dea886d..462b787 100644
--- a/README.md
+++ a/README.md
@@ -21,6 +21,12 @@
 $ which-electron Appium-linux-1.21.0.AppImage
 Fingerprint: v7.2.4-v7.3.3
 v7.3.3 is currently not supported
+
+$ which-electron https://github.com/stoplightio/studio/releases/download/v2.3.0-stable.5931.git-67616e9/stoplight-studio-mac.dmg
+Downloaded https://github.com/stoplightio/studio/releases/download/v2.3.0-stable.5931.git-67616e9/stoplight-studio-mac.dmg
+/tmp/which-electronaN3QGg/stoplight-studio-mac.dmg
+Fingerprint: v11.0.5-v11.1.1
+v11.1.1 is currently not supported
 ```
 
 ## How does it work?
@@ -40,7 +46,7 @@
 It is known to not work against:
 
 1. Windows setup files (ones with `-setup` in their name)
-2. Breaks with newer AppImage and deb files
+2. On systems without 7-zip installed, it falls back to an older version of 7zip via the 7z-bin package on NPM. Unfortunately, the older version can't extract AppImage files correctly.
 
 ## License
 
diff --git a/package-lock.json b/package-lock.json
index 5cbd923..e6162bb 100644
--- a/package-lock.json
+++ a/package-lock.json
@@ -1,22 +1,25 @@
 {
   "name": "which-electron",
-  "version": "1.0.0",
+  "version": "1.0.1",
   "lockfileVersion": 2,
   "requires": true,
   "packages": {
     "": {
-      "version": "1.0.0",
+      "version": "1.0.1",
       "license": "MIT",
       "dependencies": {
         "7zip-bin": "^5.1.1",
         "electron-fingerprints": "^1.0.0",
         "hasha": "^5.2.2",
+        "is-valid-http-url": "^1.0.3",
         "node-7z": "^3.0.0",
+        "nodejs-file-downloader": "^4.7.1",
         "rimraf": "^3.0.2",
-        "semver-sort": "^0.0.4"
+        "semver-sort": "^0.0.4",
+        "which": "^2.0.2"
       },
       "bin": {
-        "which-electron": "index.js"
+        "which-electron": "src/index.js"
       },
       "devDependencies": {
         "kuta": "*"
@@ -26,6 +29,17 @@
       "version": "5.1.1",
       "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.1.1.tgz",
       "integrity": "sha512-sAP4LldeWNz0lNzmTird3uWfFDWWTeg6V/MsmyyLR9X1idwKBWIgt/ZvinqQldJm3LecKEs1emkbquO6PCiLVQ=="
+    },
+    "node_modules/agent-base": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+      "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+      "dependencies": {
+        "debug": "4"
+      },
+      "engines": {
+        "node": ">= 6.0.0"
+      }
     },
     "node_modules/balanced-match": {
       "version": "1.0.2",
@@ -99,6 +113,25 @@
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/electron-fingerprints/-/electron-fingerprints-1.1.0.tgz",
       "integrity": "sha512-b9eLRfbqQJ+eVGa/tizGKkDlRIwoN83TwByvmr9pLCkpbN48X/2pZDgaHrl7PdrlJqUvut6pOfC8d8Bc7b8tAA=="
+    },
+    "node_modules/follow-redirects": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz",
+      "integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==",
+      "funding": [
+        {
+          "type": "individual",
+          "url": "https://github.com/sponsors/RubenVerborgh"
+        }
+      ],
+      "engines": {
+        "node": ">=4.0"
+      },
+      "peerDependenciesMeta": {
+        "debug": {
+          "optional": true
+        }
+      }
     },
     "node_modules/fs.realpath": {
       "version": "1.0.0",
@@ -137,6 +170,18 @@
       },
       "funding": {
         "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/https-proxy-agent": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
+      "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
+      "dependencies": {
+        "agent-base": "6",
+        "debug": "4"
+      },
+      "engines": {
+        "node": ">= 6"
       }
     },
     "node_modules/inflight": {
@@ -159,8 +204,21 @@
       "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
       "engines": {
         "node": ">=8"
+      }
+    },
+    "node_modules/is-valid-http-url": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/is-valid-http-url/-/is-valid-http-url-1.0.3.tgz",
+      "integrity": "sha512-lrPp25k/Ft3HdusDBdXqne9lNKDtN0HWIHNuC9cfzuFBLlay/gyQeBJukUR1smjyp+zw+gJ5E9wHonpcE9kiCQ==",
+      "engines": {
+        "node": ">=6"
       }
     },
+    "node_modules/isexe": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
+    },
     "node_modules/kuta": {
       "version": "2.0.0-beta.6",
       "resolved": "https://registry.npmjs.org/kuta/-/kuta-2.0.0-beta.6.tgz",
@@ -202,7 +260,26 @@
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/lodash.negate/-/lodash.negate-3.0.2.tgz",
       "integrity": "sha1-nIl7C/YQAZ4LQ7j/Pwr+89e2bzQ="
+    },
+    "node_modules/mime-db": {
+      "version": "1.48.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz",
+      "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==",
+      "engines": {
+        "node": ">= 0.6"
+      }
     },
+    "node_modules/mime-types": {
+      "version": "2.1.31",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz",
+      "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==",
+      "dependencies": {
+        "mime-db": "1.48.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
     "node_modules/mimic-fn": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
@@ -251,6 +328,17 @@
         "node": ">=10"
       }
     },
+    "node_modules/nodejs-file-downloader": {
+      "version": "4.7.1",
+      "resolved": "https://registry.npmjs.org/nodejs-file-downloader/-/nodejs-file-downloader-4.7.1.tgz",
+      "integrity": "sha512-ZeL+yD1+iOW4gn126uQTZzDJ7q50os8MrzBpMuygtweSX9QTZbiGaqGOaEuKjl+ChrkUa6t00zf460jvmyLZBw==",
+      "dependencies": {
+        "follow-redirects": "^1.13.0",
+        "https-proxy-agent": "^5.0.0",
+        "mime-types": "^2.1.27",
+        "sanitize-filename": "^1.6.3"
+      }
+    },
     "node_modules/normalize-path": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -321,6 +409,14 @@
       },
       "funding": {
         "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/sanitize-filename": {
+      "version": "1.6.3",
+      "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz",
+      "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==",
+      "dependencies": {
+        "truncate-utf8-bytes": "^1.0.0"
       }
     },
     "node_modules/semver": {
@@ -356,6 +452,14 @@
       "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
       "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
       "dev": true
+    },
+    "node_modules/truncate-utf8-bytes": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz",
+      "integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=",
+      "dependencies": {
+        "utf8-byte-length": "^1.0.1"
+      }
     },
     "node_modules/type-fest": {
       "version": "0.8.1",
@@ -363,6 +467,25 @@
       "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
       "engines": {
         "node": ">=8"
+      }
+    },
+    "node_modules/utf8-byte-length": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz",
+      "integrity": "sha1-9F8VDExm7uloGGUFq5P8u4rWv2E="
+    },
+    "node_modules/which": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+      "dependencies": {
+        "isexe": "^2.0.0"
+      },
+      "bin": {
+        "node-which": "bin/node-which"
+      },
+      "engines": {
+        "node": ">= 8"
       }
     },
     "node_modules/wrappy": {
@@ -376,6 +499,14 @@
       "version": "5.1.1",
       "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.1.1.tgz",
       "integrity": "sha512-sAP4LldeWNz0lNzmTird3uWfFDWWTeg6V/MsmyyLR9X1idwKBWIgt/ZvinqQldJm3LecKEs1emkbquO6PCiLVQ=="
+    },
+    "agent-base": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+      "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+      "requires": {
+        "debug": "4"
+      }
     },
     "balanced-match": {
       "version": "1.0.2",
@@ -430,6 +561,11 @@
       "resolved": "https://registry.npmjs.org/electron-fingerprints/-/electron-fingerprints-1.1.0.tgz",
       "integrity": "sha512-b9eLRfbqQJ+eVGa/tizGKkDlRIwoN83TwByvmr9pLCkpbN48X/2pZDgaHrl7PdrlJqUvut6pOfC8d8Bc7b8tAA=="
     },
+    "follow-redirects": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz",
+      "integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg=="
+    },
     "fs.realpath": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@@ -455,6 +591,15 @@
       "requires": {
         "is-stream": "^2.0.0",
         "type-fest": "^0.8.0"
+      }
+    },
+    "https-proxy-agent": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
+      "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
+      "requires": {
+        "agent-base": "6",
+        "debug": "4"
       }
     },
     "inflight": {
@@ -475,7 +620,17 @@
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
       "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw=="
+    },
+    "is-valid-http-url": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/is-valid-http-url/-/is-valid-http-url-1.0.3.tgz",
+      "integrity": "sha512-lrPp25k/Ft3HdusDBdXqne9lNKDtN0HWIHNuC9cfzuFBLlay/gyQeBJukUR1smjyp+zw+gJ5E9wHonpcE9kiCQ=="
     },
+    "isexe": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
+    },
     "kuta": {
       "version": "2.0.0-beta.6",
       "resolved": "https://registry.npmjs.org/kuta/-/kuta-2.0.0-beta.6.tgz",
@@ -514,6 +669,19 @@
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/lodash.negate/-/lodash.negate-3.0.2.tgz",
       "integrity": "sha1-nIl7C/YQAZ4LQ7j/Pwr+89e2bzQ="
+    },
+    "mime-db": {
+      "version": "1.48.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz",
+      "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ=="
+    },
+    "mime-types": {
+      "version": "2.1.31",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz",
+      "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==",
+      "requires": {
+        "mime-db": "1.48.0"
+      }
     },
     "mimic-fn": {
       "version": "1.2.0",
@@ -552,6 +720,17 @@
         "lodash.isempty": "^4.4.0",
         "lodash.negate": "^3.0.2",
         "normalize-path": "^3.0.0"
+      }
+    },
+    "nodejs-file-downloader": {
+      "version": "4.7.1",
+      "resolved": "https://registry.npmjs.org/nodejs-file-downloader/-/nodejs-file-downloader-4.7.1.tgz",
+      "integrity": "sha512-ZeL+yD1+iOW4gn126uQTZzDJ7q50os8MrzBpMuygtweSX9QTZbiGaqGOaEuKjl+ChrkUa6t00zf460jvmyLZBw==",
+      "requires": {
+        "follow-redirects": "^1.13.0",
+        "https-proxy-agent": "^5.0.0",
+        "mime-types": "^2.1.27",
+        "sanitize-filename": "^1.6.3"
       }
     },
     "normalize-path": {
@@ -605,6 +784,14 @@
         "glob": "^7.1.3"
       }
     },
+    "sanitize-filename": {
+      "version": "1.6.3",
+      "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz",
+      "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==",
+      "requires": {
+        "truncate-utf8-bytes": "^1.0.0"
+      }
+    },
     "semver": {
       "version": "5.7.1",
       "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
@@ -629,11 +816,32 @@
       "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
       "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
       "dev": true
+    },
+    "truncate-utf8-bytes": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz",
+      "integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=",
+      "requires": {
+        "utf8-byte-length": "^1.0.1"
+      }
     },
     "type-fest": {
       "version": "0.8.1",
       "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
       "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA=="
+    },
+    "utf8-byte-length": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz",
+      "integrity": "sha1-9F8VDExm7uloGGUFq5P8u4rWv2E="
+    },
+    "which": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+      "requires": {
+        "isexe": "^2.0.0"
+      }
     },
     "wrappy": {
       "version": "1.0.2",
diff --git a/package.json b/package.json
index a63c271..72309e4 100644
--- a/package.json
+++ a/package.json
@@ -1,6 +1,6 @@
 {
   "name": "which-electron",
-  "version": "1.0.1",
+  "version": "1.0.2",
   "description": "Guess which electron version is bundled in an application",
   "main": "src/index.js",
   "bin": {
@@ -30,9 +30,12 @@
     "7zip-bin": "^5.1.1",
     "electron-fingerprints": "^1.0.0",
     "hasha": "^5.2.2",
+    "is-valid-http-url": "^1.0.3",
     "node-7z": "^3.0.0",
+    "nodejs-file-downloader": "^4.7.1",
     "rimraf": "^3.0.2",
-    "semver-sort": "^0.0.4"
+    "semver-sort": "^0.0.4",
+    "which": "^2.0.2"
   },
   "devDependencies": {
     "kuta": "*"
diff --git a/src/archive.js b/src/archive.js
new file mode 100644
index 0000000..7309cac 100644
--- /dev/null
+++ a/src/archive.js
@@ -1,0 +1,50 @@
+const Seven = require("node-7z");
+const which = require('which');
+const path = require("path");
+const fs = require("fs");
+
+let sevenBin = null;
+
+try {
+  sevenBin = which.sync('7z')
+} catch(e) {
+  sevenBin = require('7zip-bin').path7za
+  console.error("Couldn't find 7-zip installed. Using the 7zip-bin package, which uses an older version of 7-zip. Not all files may work properly.")
+}
+
+module.exports = {
+  readFileContents: function(archive, filepath, dir, cb) {
+    let stream = Seven.extract(archive, dir, {
+      recursive: true,
+      $cherryPick: filepath,
+      $bin: sevenBin
+    });
+    let fn = path.basename(filepath);
+    stream.on("end", ()=>{
+      cb(fs.readFileSync(`${dir}/${fn}`, {encoding: 'utf8'}))
+    });
+  },
+  extractSomeFiles: function(archive, list, dir, cb) {
+    let stream = Seven.extract(archive, dir, {
+      $cherryPick: list,
+      $bin: sevenBin
+    })
+    stream.on('end', ()=>{
+      cb()
+    })
+  },
+  listFileContents: function(archive, cb) {
+    let zip = Seven.list(archive, {
+      $bin: sevenBin,
+      alternateStreamExtract: true,
+      alternateStreamReplace: true,
+    });
+    let entries = [];
+    zip.on("data", (data) => {
+      entries.push(data);
+    });
+    zip.on("end", () => {
+      cb(entries);
+    });
+  },
+};
diff --git a/src/index.js b/src/index.js
index 6cd8ab9..c10bf65 100644
--- a/src/index.js
+++ a/src/index.js
@@ -1,15 +1,59 @@
-const path = require("path");
 const osguess = require("./os");
 const finder = require("./finder");
-const zip = require("./zip");
+const archive = require("./archive");
 const fp = require("./fingerprint");
-const cleanup = require("rimraf");
 const V = require("./version");
+
+const isUrl = require("is-valid-http-url");
+const cleanup = require("rimraf");
+const dl = require('nodejs-file-downloader')
 
+const path = require("path");
+const fs = require('fs');
+const os = require('os');
+const process = require('process');
+const TMPDIR = path.join(os.tmpdir(), 'which-electron')
+
 // Input file comes from process.argv[2]
-const FILENAME = process.argv[2];
+let FILENAME = process.argv[2];
+
+if (!FILENAME) {
+  console.error("Please pass a valid URL or file as the first argument");
+  process.exit(1)
+}
 
-console.log(FILENAME);
+if(isUrl(FILENAME)) {
+  let url = FILENAME;
+  // Download to temporary directory
+  let tmpdir = fs.mkdtempSync(TMPDIR);
+  let fn = `${tmpdir}/${path.basename(url)}`;
+  const downloader = new dl({
+    url: url,
+    directory: tmpdir,//This folder will be created, if it doesn't exist.
+  })
+  downloader.download().then(()=> {
+    console.log(`Downloaded ${url}`)
+    validateFile(fn)
+  }).catch((e)=> {
+    console.error(`Error while downloading ${url}`)
+    console.error(e)
+    process.exit(1)
+  })
+} else {
+  validateFile(FILENAME)
+}
+
+function validateFile(fn) {
+  fs.access(fn, fs.constants.R_OK, (err) => {
+    if (err) {
+      console.error(`${fn} not readable`)
+      process.exit(1);
+    } else {
+      console.log(fn);
+      whichElectron(fn)
+    }
+  });
+}
 
 function logSupport(version) {
   if (V.isSupported(version)) {
@@ -19,67 +63,71 @@
   }
 }
 
-zip.listFileContents(FILENAME, (entries) => {
-  let osguess1 = osguess.guessFromFilename(FILENAME);
-  let osguess2 = osguess.guessFromContents(entries);
+let whichElectron = function(filename) {
+  archive.listFileContents(filename, (entries) => {
+    let osguess1 = osguess.guessFromFilename(filename);
+    let osguess2 = osguess.guessFromContents(entries);
 
-  if (osguess1 !== osguess2 && osguess1 && osguess2) {
-    console.log(`Unsure about operating system. Going with ${osguess2}. Other option was ${osguess1}`);
-  }
-  if (osguess1 && !osguess2) {
-    osguess2 = osguess1
-  }
-  let arch = osguess.guessArch(FILENAME, entries);
-  let asar = finder.asar(entries);
-  let binary = finder.binary(entries);
-  let versionFiles = finder.version(entries);
-  let enm = finder.findElectronPackageInsideNodeModules(entries);
-
-  let filesToHash = finder.fingerprintable(entries);
-
-  zip.extractSomeFiles(FILENAME, filesToHash, (dir) => {
-    hashes = fp.getHashes(dir);
-    guesses = fp.guessFromHashes(osguess2, arch, hashes);
-    if (guesses.length == 1) {
-      console.log("Fingerprint: " + guesses[0]);
-      logSupport(guesses[0])
-    } else if (guesses.length > 1) {
-      console.log("Fingerprint: " + V.asText(guesses));
-      logSupport(V.max(guesses))
+    if (osguess1 !== osguess2 && osguess1 && osguess2) {
+      console.log(`Unsure about operating system. Going with ${osguess2}. Other option was ${osguess1}`);
     }
+    if (osguess1 && !osguess2) {
+      osguess2 = osguess1
+    }
+    let arch = osguess.guessArch(filename, entries);
+    let asar = finder.asar(entries);
+    let binary = finder.binary(entries);
+    let versionFiles = finder.version(entries);
+    let enm = finder.findElectronPackageInsideNodeModules(entries);
 
-    cleanup.sync(dir);
-  });
+    let filesToHash = finder.fingerprintable(entries);
 
-  // if (binary) {
-  //   console.log(`${process.argv[2]}:${binary}`);
-  // }
-  if (versionFiles.length > 0) {
-    versionFiles.map((f) => {
-      zip.readFileContents(FILENAME, f, (c) => {
-        console.log("Found Version file: " + c);
-        logSupport(`${c}`)
-      });
-    });
-  }
-  if (asar.length > 0) {
-    asar.forEach((a) => {
-      console.log("Version Constraint (Unsupported): <v7.0.0");
+    archive.extractSomeFiles(filename, filesToHash, TMPDIR, () => {
+      hashes = fp.getHashes(TMPDIR);
+      guesses = fp.guessFromHashes(osguess2, arch, hashes);
+      if (guesses.length == 1) {
+        console.log("Fingerprint: " + guesses[0]);
+        logSupport(guesses[0])
+      } else if (guesses.length > 1) {
+        console.log("Fingerprint: " + V.asText(guesses));
+        logSupport(V.max(guesses))
+      }
+
+      cleanup.sync(TMPDIR);
     });
-  }
-  if (enm) {
-    enm.forEach((a) => {
-      zip.readFileContents(FILENAME, a, (c) => {
-        try {
-          let packageData = JSON.parse(c);
-          console.log(
-            "Found version in package.json file: " + packageData["version"]
-          );
-          logSupport(`v${packageData["version"]}`)
-        } catch (e) {
-          // TODO: Do something
-        }
+
+    // if (binary) {
+    //   console.log(`${process.argv[2]}:${binary}`);
+    // }
+    if (versionFiles.length > 0) {
+      versionFiles.map((f) => {
+        archive.readFileContents(filename, f, TMPDIR, (c) => {
+          console.log("Found Version file: " + c);
+          logSupport(`${c}`)
+        });
       });
-    });
-  }
-});
+    }
+    if (asar.length > 0) {
+      asar.forEach((a) => {
+        console.log("Version Constraint (Unsupported): <v7.0.0");
+      });
+    }
+    if (enm) {
+      enm.forEach((a) => {
+        archive.readFileContents(filename, a, (c) => {
+          try {
+            let packageData = JSON.parse(c);
+            console.log(
+              "Found version in package.json file: " + packageData["version"]
+            );
+            logSupport(`v${packageData["version"]}`)
+          } catch (e) {
+            // TODO: Do something
+          }
+        });
+      });
+    }
+  });
+}
+
+
diff --git a/src/zip.js b/src/zip.js
deleted file mode 100644
index 51e5b0a..0000000 100644
--- a/src/zip.js
+++ /dev/null
@@ -1,41 +1,0 @@
-const Seven = require("node-7z");
-const sevenBin = require('7zip-bin').path7za;
-const path = require("path");
-const fs = require("fs");
-
-module.exports = {
-  readFileContents: function(archive, filepath, cb) {
-    // TODO: Create a new temp directory
-    let stream = Seven.extract(archive, "/tmp", {
-      recursive: true,
-      $cherryPick: filepath,
-      $bin: sevenBin
-    });
-    let fn = path.basename(filepath);
-    stream.on("end", ()=>{
-      cb(fs.readFileSync(`/tmp/${fn}`, {encoding: 'utf8'}))
-    });
-  },
-  extractSomeFiles: function(archive, list, cb) {
-    let dir = fs.mkdtempSync('/tmp/which-electron')
-    let stream = Seven.extract(archive, dir, {
-      $cherryPick: list,
-      $bin: sevenBin
-    })
-    stream.on('end', ()=>{
-      cb(dir)
-    })
-  },
-  listFileContents: function(archive, cb) {
-    let zip = Seven.list(archive, {
-      $bin: sevenBin
-    });
-    let entries = [];
-    zip.on("data", (data) => {
-      entries.push(data);
-    });
-    zip.on("end", () => {
-      cb(entries);
-    });
-  },
-};
--
rgit 0.1.5