Socket
Socket
Sign inDemoInstall

get-uri

Package Overview
Dependencies
Maintainers
1
Versions
21
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

get-uri - npm Package Compare versions

Comparing version 3.0.2 to 4.0.0

47

dist/data.js
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {

@@ -20,3 +11,3 @@ return (mod && mod.__esModule) ? mod : { "default": mod };

const notmodified_1 = __importDefault(require("./notmodified"));
const debug = debug_1.default('get-uri:data');
const debug = (0, debug_1.default)('get-uri:data');
class DataReadable extends stream_1.Readable {

@@ -33,23 +24,21 @@ constructor(hash, buf) {

*/
function get({ href: uri }, { cache }) {
return __awaiter(this, void 0, void 0, function* () {
// need to create a SHA1 hash of the URI string, for cacheability checks
// in future `getUri()` calls with the same data URI passed in.
const shasum = crypto_1.createHash('sha1');
shasum.update(uri);
const hash = shasum.digest('hex');
debug('generated SHA1 hash for "data:" URI: %o', hash);
// check if the cache is the same "data:" URI that was previously passed in.
if (cache && cache.hash === hash) {
debug('got matching cache SHA1 hash: %o', hash);
throw new notmodified_1.default();
}
else {
debug('creating Readable stream from "data:" URI buffer');
const buf = data_uri_to_buffer_1.default(uri);
return new DataReadable(hash, buf);
}
});
async function get({ href: uri }, { cache }) {
// need to create a SHA1 hash of the URI string, for cacheability checks
// in future `getUri()` calls with the same data URI passed in.
const shasum = (0, crypto_1.createHash)('sha1');
shasum.update(uri);
const hash = shasum.digest('hex');
debug('generated SHA1 hash for "data:" URI: %o', hash);
// check if the cache is the same "data:" URI that was previously passed in.
if (cache && cache.hash === hash) {
debug('got matching cache SHA1 hash: %o', hash);
throw new notmodified_1.default();
}
else {
debug('creating Readable stream from "data:" URI buffer');
const buf = (0, data_uri_to_buffer_1.default)(uri);
return new DataReadable(hash, buf);
}
}
exports.default = get;
//# sourceMappingURL=data.js.map
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {

@@ -21,38 +12,40 @@ return (mod && mod.__esModule) ? mod : { "default": mod };

const notmodified_1 = __importDefault(require("./notmodified"));
const debug = debug_1.default('get-uri:file');
const debug = (0, debug_1.default)('get-uri:file');
/**
* Returns a `fs.ReadStream` instance from a "file:" URI.
*/
function get({ href: uri }, opts) {
return __awaiter(this, void 0, void 0, function* () {
const { cache, flags = 'r', mode = 438 // =0666
} = opts;
try {
// Convert URI → Path
const filepath = file_uri_to_path_1.default(uri);
debug('Normalized pathname: %o', filepath);
// `open()` first to get a file descriptor and ensure that the file
// exists.
const fd = yield fs_extra_1.open(filepath, flags, mode);
// Now `fstat()` to check the `mtime` and store the stat object for
// the cache.
const stat = yield fs_extra_1.fstat(fd);
// if a `cache` was provided, check if the file has not been modified
if (cache && cache.stat && stat && isNotModified(cache.stat, stat)) {
throw new notmodified_1.default();
}
// `fs.ReadStream` takes care of calling `fs.close()` on the
// fd after it's done reading
// @ts-ignore - `@types/node` doesn't allow `null` as file path :/
const rs = fs_1.createReadStream(null, Object.assign(Object.assign({ autoClose: true }, opts), { fd }));
rs.stat = stat;
return rs;
async function get({ href: uri }, opts) {
const { cache, flags = 'r', mode = 438 // =0666
} = opts;
try {
// Convert URI → Path
const filepath = (0, file_uri_to_path_1.default)(uri);
debug('Normalized pathname: %o', filepath);
// `open()` first to get a file descriptor and ensure that the file
// exists.
const fd = await (0, fs_extra_1.open)(filepath, flags, mode);
// Now `fstat()` to check the `mtime` and store the stat object for
// the cache.
const stat = await (0, fs_extra_1.fstat)(fd);
// if a `cache` was provided, check if the file has not been modified
if (cache && cache.stat && stat && isNotModified(cache.stat, stat)) {
throw new notmodified_1.default();
}
catch (err) {
if (err.code === 'ENOENT') {
throw new notfound_1.default();
}
throw err;
// `fs.ReadStream` takes care of calling `fs.close()` on the
// fd after it's done reading
// @ts-ignore - `@types/node` doesn't allow `null` as file path :/
const rs = (0, fs_1.createReadStream)(null, {
autoClose: true,
...opts,
fd
});
rs.stat = stat;
return rs;
}
catch (err) {
if (err.code === 'ENOENT') {
throw new notfound_1.default();
}
});
throw err;
}
}

@@ -59,0 +52,0 @@ exports.default = get;

"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {

@@ -21,99 +12,96 @@ return (mod && mod.__esModule) ? mod : { "default": mod };

const notmodified_1 = __importDefault(require("./notmodified"));
const debug = debug_1.default('get-uri:ftp');
const debug = (0, debug_1.default)('get-uri:ftp');
/**
* Returns a Readable stream from an "ftp:" URI.
*/
function get(parsed, opts) {
return __awaiter(this, void 0, void 0, function* () {
const { cache } = opts;
const filepath = parsed.pathname;
let lastModified = null;
if (!filepath) {
throw new TypeError('No "pathname"!');
async function get(parsed, opts) {
const { cache } = opts;
const filepath = parsed.pathname;
let lastModified = null;
if (!filepath) {
throw new TypeError('No "pathname"!');
}
const client = new ftp_1.default();
client.once('greeting', (greeting) => {
debug('FTP greeting: %o', greeting);
});
function onend() {
// close the FTP client socket connection
client.end();
}
try {
opts.host = parsed.hostname || parsed.host || 'localhost';
opts.port = parseInt(parsed.port || '0', 10) || 21;
opts.debug = debug;
if (parsed.auth) {
const [user, password] = parsed.auth.split(':');
opts.user = user;
opts.password = password;
}
const client = new ftp_1.default();
client.once('greeting', (greeting) => {
debug('FTP greeting: %o', greeting);
});
function onend() {
// close the FTP client socket connection
client.end();
}
const readyPromise = (0, once_1.default)(client, 'ready');
client.connect(opts);
await readyPromise;
// first we have to figure out the Last Modified date.
// try the MDTM command first, which is an optional extension command.
try {
opts.host = parsed.hostname || parsed.host || 'localhost';
opts.port = parseInt(parsed.port || '0', 10) || 21;
opts.debug = debug;
if (parsed.auth) {
const [user, password] = parsed.auth.split(':');
opts.user = user;
opts.password = password;
}
// await cb(_ => client.connect(opts, _));
const readyPromise = once_1.default(client, 'ready');
client.connect(opts);
yield readyPromise;
// first we have to figure out the Last Modified date.
// try the MDTM command first, which is an optional extension command.
try {
lastModified = yield new Promise((resolve, reject) => {
client.lastMod(filepath, (err, res) => {
return err ? reject(err) : resolve(res);
});
lastModified = await new Promise((resolve, reject) => {
client.lastMod(filepath, (err, res) => {
return err ? reject(err) : resolve(res);
});
}
catch (err) {
// handle the "file not found" error code
if (err.code === 550) {
throw new notfound_1.default();
}
}
if (!lastModified) {
// Try to get the last modified date via the LIST command (uses
// more bandwidth, but is more compatible with older FTP servers
const list = yield new Promise((resolve, reject) => {
client.list(path_1.dirname(filepath), (err, res) => {
return err ? reject(err) : resolve(res);
});
});
// attempt to find the "entry" with a matching "name"
const name = path_1.basename(filepath);
const entry = list.find(e => e.name === name);
if (entry) {
lastModified = entry.date;
}
}
if (lastModified) {
if (isNotModified()) {
throw new notmodified_1.default();
}
}
else {
});
}
catch (err) {
// handle the "file not found" error code
if (err.code === 550) {
throw new notfound_1.default();
}
// XXX: a small timeout seemed necessary otherwise FTP servers
// were returning empty sockets for the file occasionally
// setTimeout(client.get.bind(client, filepath, onfile), 10);
const rs = (yield new Promise((resolve, reject) => {
client.get(filepath, (err, res) => {
}
if (!lastModified) {
// Try to get the last modified date via the LIST command (uses
// more bandwidth, but is more compatible with older FTP servers
const list = await new Promise((resolve, reject) => {
client.list((0, path_1.dirname)(filepath), (err, res) => {
return err ? reject(err) : resolve(res);
});
}));
rs.once('end', onend);
rs.lastModified = lastModified;
return rs;
});
// attempt to find the "entry" with a matching "name"
const name = (0, path_1.basename)(filepath);
const entry = list.find(e => e.name === name);
if (entry) {
lastModified = entry.date;
}
}
catch (err) {
client.destroy();
throw err;
}
// called when `lastModified` is set, and a "cache" stream was provided
function isNotModified() {
if (cache && cache.lastModified && lastModified) {
return +cache.lastModified === +lastModified;
if (lastModified) {
if (isNotModified()) {
throw new notmodified_1.default();
}
return false;
}
});
else {
throw new notfound_1.default();
}
// XXX: a small timeout seemed necessary otherwise FTP servers
// were returning empty sockets for the file occasionally
// setTimeout(client.get.bind(client, filepath, onfile), 10);
const rs = (await new Promise((resolve, reject) => {
client.get(filepath, (err, res) => {
return err ? reject(err) : resolve(res);
});
}));
rs.once('end', onend);
rs.lastModified = lastModified;
return rs;
}
catch (err) {
client.destroy();
throw err;
}
// called when `lastModified` is set, and a "cache" stream was provided
function isNotModified() {
if (cache && cache.lastModified && lastModified) {
return +cache.lastModified === +lastModified;
}
return false;
}
}
exports.default = get;
//# sourceMappingURL=ftp.js.map
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {

@@ -23,105 +14,103 @@ return (mod && mod.__esModule) ? mod : { "default": mod };

const notmodified_1 = __importDefault(require("./notmodified"));
const debug = debug_1.default('get-uri:http');
const debug = (0, debug_1.default)('get-uri:http');
/**
* Returns a Readable stream from an "http:" URI.
*/
function get(parsed, opts) {
return __awaiter(this, void 0, void 0, function* () {
debug('GET %o', parsed.href);
const cache = getCache(parsed, opts.cache);
// first check the previous Expires and/or Cache-Control headers
// of a previous response if a `cache` was provided
if (cache && isFresh(cache) && typeof cache.statusCode === 'number') {
// check for a 3xx "redirect" status code on the previous cache
const type = (cache.statusCode / 100) | 0;
if (type === 3 && cache.headers.location) {
debug('cached redirect');
throw new Error('TODO: implement cached redirects!');
}
// otherwise we assume that it's the destination endpoint,
// since there's nowhere else to redirect to
throw new notmodified_1.default();
async function get(parsed, opts) {
debug('GET %o', parsed.href);
const cache = getCache(parsed, opts.cache);
// first check the previous Expires and/or Cache-Control headers
// of a previous response if a `cache` was provided
if (cache && isFresh(cache) && typeof cache.statusCode === 'number') {
// check for a 3xx "redirect" status code on the previous cache
const type = (cache.statusCode / 100) | 0;
if (type === 3 && cache.headers.location) {
debug('cached redirect');
throw new Error('TODO: implement cached redirects!');
}
// 5 redirects allowed by default
const maxRedirects = typeof opts.maxRedirects === 'number' ? opts.maxRedirects : 5;
debug('allowing %o max redirects', maxRedirects);
let mod;
if (opts.http) {
// the `https` module passed in from the "http.js" file
mod = opts.http;
debug('using secure `https` core module');
// otherwise we assume that it's the destination endpoint,
// since there's nowhere else to redirect to
throw new notmodified_1.default();
}
// 5 redirects allowed by default
const maxRedirects = typeof opts.maxRedirects === 'number' ? opts.maxRedirects : 5;
debug('allowing %o max redirects', maxRedirects);
let mod;
if (opts.http) {
// the `https` module passed in from the "http.js" file
mod = opts.http;
debug('using secure `https` core module');
}
else {
mod = http_1.default;
debug('using `http` core module');
}
const options = { ...opts, ...parsed };
// add "cache validation" headers if a `cache` was provided
if (cache) {
if (!options.headers) {
options.headers = {};
}
else {
mod = http_1.default;
debug('using `http` core module');
const lastModified = cache.headers['last-modified'];
if (lastModified) {
options.headers['If-Modified-Since'] = lastModified;
debug('added "If-Modified-Since" request header: %o', lastModified);
}
const options = Object.assign(Object.assign({}, opts), parsed);
// add "cache validation" headers if a `cache` was provided
if (cache) {
if (!options.headers) {
options.headers = {};
}
const lastModified = cache.headers['last-modified'];
if (lastModified) {
options.headers['If-Modified-Since'] = lastModified;
debug('added "If-Modified-Since" request header: %o', lastModified);
}
const etag = cache.headers.etag;
if (etag) {
options.headers['If-None-Match'] = etag;
debug('added "If-None-Match" request header: %o', etag);
}
const etag = cache.headers.etag;
if (etag) {
options.headers['If-None-Match'] = etag;
debug('added "If-None-Match" request header: %o', etag);
}
const req = mod.get(options);
const res = yield once_1.default(req, 'response');
const code = res.statusCode || 0;
// assign a Date to this response for the "Cache-Control" delta calculation
res.date = Date.now();
res.parsed = parsed;
debug('got %o response status code', code);
// any 2xx response is a "success" code
let type = (code / 100) | 0;
// check for a 3xx "redirect" status code
let location = res.headers.location;
if (type === 3 && location) {
if (!opts.redirects)
opts.redirects = [];
let redirects = opts.redirects;
if (redirects.length < maxRedirects) {
debug('got a "redirect" status code with Location: %o', location);
// flush this response - we're not going to use it
res.resume();
// hang on to this Response object for the "redirects" Array
redirects.push(res);
let newUri = url_1.resolve(parsed.href, location);
debug('resolved redirect URL: %o', newUri);
let left = maxRedirects - redirects.length;
debug('%o more redirects allowed after this one', left);
// check if redirecting to a different protocol
let parsedUrl = url_1.parse(newUri);
if (parsedUrl.protocol !== parsed.protocol) {
opts.http = parsedUrl.protocol === 'https:' ? https_1.default : undefined;
}
return get(parsedUrl, opts);
}
}
// if we didn't get a 2xx "success" status code, then create an Error object
if (type !== 2) {
}
const req = mod.get(options);
const [res] = await (0, once_1.default)(req, 'response');
const code = res.statusCode || 0;
// assign a Date to this response for the "Cache-Control" delta calculation
res.date = Date.now();
res.parsed = parsed;
debug('got %o response status code', code);
// any 2xx response is a "success" code
let type = (code / 100) | 0;
// check for a 3xx "redirect" status code
let location = res.headers.location;
if (type === 3 && location) {
if (!opts.redirects)
opts.redirects = [];
let redirects = opts.redirects;
if (redirects.length < maxRedirects) {
debug('got a "redirect" status code with Location: %o', location);
// flush this response - we're not going to use it
res.resume();
if (code === 304) {
throw new notmodified_1.default();
// hang on to this Response object for the "redirects" Array
redirects.push(res);
let newUri = (0, url_1.resolve)(parsed.href, location);
debug('resolved redirect URL: %o', newUri);
let left = maxRedirects - redirects.length;
debug('%o more redirects allowed after this one', left);
// check if redirecting to a different protocol
let parsedUrl = (0, url_1.parse)(newUri);
if (parsedUrl.protocol !== parsed.protocol) {
opts.http = parsedUrl.protocol === 'https:' ? https_1.default : undefined;
}
else if (code === 404) {
throw new notfound_1.default();
}
// other HTTP-level error
throw new http_error_1.default(code);
return get(parsedUrl, opts);
}
if (opts.redirects) {
// store a reference to the "redirects" Array on the Response object so that
// they can be inspected during a subsequent call to GET the same URI
res.redirects = opts.redirects;
}
// if we didn't get a 2xx "success" status code, then create an Error object
if (type !== 2) {
res.resume();
if (code === 304) {
throw new notmodified_1.default();
}
return res;
});
else if (code === 404) {
throw new notfound_1.default();
}
// other HTTP-level error
throw new http_error_1.default(code);
}
if (opts.redirects) {
// store a reference to the "redirects" Array on the Response object so that
// they can be inspected during a subsequent call to GET the same URI
res.redirects = opts.redirects;
}
return res;
}

@@ -128,0 +117,0 @@ exports.default = get;

@@ -12,5 +12,5 @@ "use strict";

function get(parsed, opts) {
return http_1.default(parsed, Object.assign(Object.assign({}, opts), { http: https_1.default }));
return (0, http_1.default)(parsed, { ...opts, http: https_1.default });
}
exports.default = get;
//# sourceMappingURL=https.js.map

@@ -13,3 +13,3 @@ "use strict";

const https_1 = __importDefault(require("./https"));
const debug = debug_1.default('get-uri');
const debug = (0, debug_1.default)('get-uri');
function getUri(uri, opts, fn) {

@@ -26,3 +26,3 @@ const p = new Promise((resolve, reject) => {

}
const parsed = url_1.parse(uri);
const parsed = (0, url_1.parse)(uri);
// Strip trailing `:`

@@ -29,0 +29,0 @@ const protocol = (parsed.protocol || '').replace(/:$/, '');

{
"name": "get-uri",
"version": "3.0.2",
"version": "4.0.0",
"description": "Returns a `stream.Readable` from a URI string",

@@ -14,3 +14,2 @@ "main": "./dist/index.js",

"test": "mocha --reporter spec",
"test-lint": "eslint src --ext .js,.ts",
"prepublishOnly": "npm run build"

@@ -46,11 +45,2 @@ },

"@types/node": "^12.12.11",
"@typescript-eslint/eslint-plugin": "1.6.0",
"@typescript-eslint/parser": "1.1.0",
"eslint": "5.16.0",
"eslint-config-airbnb": "17.1.0",
"eslint-config-prettier": "4.1.0",
"eslint-import-resolver-typescript": "1.1.1",
"eslint-plugin-import": "2.16.0",
"eslint-plugin-jsx-a11y": "6.2.1",
"eslint-plugin-react": "7.12.4",
"ftpd": "https://files-jg1s1zt9l.n8.io/ftpd-v0.2.14.tgz",

@@ -61,6 +51,6 @@ "mocha": "^6.2.2",

"stream-to-array": "2",
"typescript": "^3.7.3"
"typescript": "^4.4.3"
},
"dependencies": {
"@tootallnate/once": "1",
"@tootallnate/once": "2",
"data-uri-to-buffer": "3",

@@ -73,4 +63,4 @@ "debug": "4",

"engines": {
"node": ">= 6"
"node": ">= 8"
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc