Socket
Socket
Sign inDemoInstall

q-io

Package Overview
Dependencies
Maintainers
1
Versions
80
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

q-io - npm Package Compare versions

Comparing version 1.11.0 to 1.11.1

spec/http/normalize-request-spec.js

26

CHANGES.md
<!-- vim:ts=4:sts=4:sw=4:et:tw=60 -->
## 1.11.1
- Fix to `fs.reroot`, binding this properly (@Stuk)
- `fs.reroot` no longer traverses into directory prefixes implicitly.
We do not expect anyone was depending on this strange behavior,
but do expect folks were not using `reroot` because of it.
- Many missing methods added to RootFs (@3on)
- HTTP request normalization has been greatly improved.
Particularly, the ambiguity of `host` vs `hostname` is resolved.
`host` stands for both the hostname and the port, but only includes the port
if it differs from the default port for the protocol.
HTTP requests will normalize any combination of `host`, `port`, and
`hostname`.
The cookie jar HTTP application adapter has been updated.
- Support for URL authorization has been improved. If you use the `auth`
portion of a URL, it will be implicitly normalized to the corresponding
`Authorization` header, for basic HTTP auth.
Note that the convention in Q-IO is to use lower-case for all input and
output headers, since they are case-insensitive.
- MockFS now handles file modes properly (@Stuk)
- `fs.copyTree` fixed for duplicate file modes (@Stuk)
- Fix for HTTP clients on Node.js 0.11, which changed how it interprets the
`agent` option.
- Fixed a bug, NodeWriter was missing a `node` property, referring back to the
Node.js writable stream.
## 1.11.0

@@ -4,0 +30,0 @@

27

fs-common.js

@@ -141,6 +141,10 @@ var Q = require("q");

var self = this;
return Q.spread([
self.open(source, {flags: "rb"}),
self.open(target, {flags: "wb"})
], function (reader, writer) {
return Q.when(self.stat(source), function (stat) {
var mode = stat.node.mode;
return Q.all([
self.open(source, {flags: "rb"}),
self.open(target, {flags: "wb", mode: mode})
]);
})
.spread(function (reader, writer) {
return Q.when(reader.forEach(function (block) {

@@ -175,3 +179,3 @@ return writer.write(block);

} else {
return Q.when(self.makeDirectory(target), function () {
return Q.when(self.makeDirectory(target, stat.node.mode), function () {
return copySubTree;

@@ -417,14 +421,3 @@ });

path = path || this.ROOT;
return Q.when(this.list(path), function (list) {
if (list.length !== 1)
return RootFs(self, path);
var nextPath = self.join(path, list[0]);
return Q.when(self.stat(nextPath), function (stat) {
if (stat.isDirectory()) {
return reroot(nextPath);
} else {
return RootFs(self, path);
}
});
});
return RootFs(self, path);
}

@@ -431,0 +424,0 @@

@@ -97,2 +97,5 @@

node._entries[base] = new FileNode(this);
if ("mode" in options) {
node._entries[base].mode = options.mode;
}
}

@@ -153,3 +156,3 @@ var fileNode = node._entries[base]._follow(path);

MockFs.prototype.makeDirectory = function (path) {
MockFs.prototype.makeDirectory = function (path, mode) {
var self = this;

@@ -175,2 +178,5 @@ return Q.fcall(function () {

node._entries[name] = new DirectoryNode(self);
if (mode) {
node._entries[name].mode = mode;
}
});

@@ -211,4 +217,3 @@ };

path = self.absolute(path);
var node = self._root._walk(path);
return node;
return new self.Stats(self._root._walk(path));
});

@@ -265,3 +270,3 @@ };

path = self.absolute(path);
self._root._walk(path)._follow(path)._mode = mode;
self._root._walk(path)._follow(path).mode = mode;
});

@@ -366,3 +371,3 @@ };

this._accessed = this._modified = new Date();
this._mode = parseInt("0644", 8);
this.mode = parseInt("0644", 8);
this._owner = null;

@@ -469,3 +474,3 @@ }

this._entries = Object.create(null);
this._mode = parseInt("0755", 8);
this.mode = parseInt("0755", 8);
}

@@ -472,0 +477,0 @@

@@ -116,2 +116,26 @@

inner.remove = function (path) {
return attenuate(path).then(function (path) {
return outer.remove(path.outer);
}).catch(function (error) {
throw new Error("Can't remove " + JSON.stringify(path));
});
};
inner.makeTree = function (path) {
return attenuate(path).then(function (path) {
return outer.makeTree(path.outer);
}).catch(function (error) {
throw new Error("Can't make tree " + JSON.stringify(path));
});
};
inner.removeTree = function (path) {
return attenuate(path).then(function (path) {
return outer.removeTree(path.outer);
}).catch(function (error) {
throw new Error("Can't remove tree " + JSON.stringify(path));
});
};
return Q.when(outer.canonical(root), function (_root) {

@@ -118,0 +142,0 @@ root = _root;

var Q = require("q");
var Cookie = require("../http-cookie");
Q.longStackSupport = true;

@@ -9,2 +10,5 @@ exports.CookieJar = function (app) {

if (!request.headers.host) {
throw new Error("Requests must have a host header");
}
var hosts = allHostsContaining(request.headers.host);

@@ -34,4 +38,5 @@

.map(function (host) {
if (!hostContains(host, request.headers.host))
if (!hostContains(host, request.headers.host)) {
return [];
}
var pathCookies = hostCookies[host];

@@ -79,5 +84,6 @@ return concat(

if (response.headers["set-cookie"]) {
var requestHost = ipRe.test(request.headers.host) ?
request.headers.host :
"." + request.headers.host;
var host = request.headers.host;
var hostParts = splitHost(host);
var hostname = hostParts[0];
var requestHost = ipRe.test(hostname) ? host : "." + host;
// normalize to array

@@ -111,13 +117,26 @@ if (!Array.isArray(response.headers["set-cookie"])) {

var ipRe = /^\d+\.\d+\.\d+\.\d+$/;
var portRe = /^(.*)(:\d+)$/;
function allHostsContaining(content) {
if (ipRe.test(content)) {
return [content];
} if (content === "localhost") {
return [content];
function splitHost(host) {
var match = portRe.exec(host);
if (match) {
return [match[1], match[2]];
} else {
var parts = content.split(".");
return [host, ""];
}
}
function allHostsContaining(host) {
var parts = splitHost(host);
var hostname = parts[0];
var port = parts[1];
if (ipRe.test(hostname)) {
return [hostname + port];
} if (hostname === "localhost") {
return [hostname + port];
} else {
var parts = hostname.split(".");
var hosts = [];
while (parts.length > 1) {
hosts.push("." + parts.join("."));
hosts.push("." + parts.join(".") + port);
parts.shift();

@@ -129,14 +148,23 @@ }

function hostContains(container, content) {
if (ipRe.test(container) || ipRe.test(content)) {
return container === content;
} else if (/^\./.test(container)) {
function hostContains(containerHost, contentHost) {
var containerParts = splitHost(containerHost);
var containerHostname = containerParts[0];
var containerPort = containerParts[1];
var contentParts = splitHost(contentHost);
var contentHostname = contentParts[0];
var contentPort = contentParts[1];
if (containerPort !== contentPort) {
return false;
}
if (ipRe.test(containerHostname) || ipRe.test(contentHostname)) {
return containerHostname === contentHostname;
} else if (/^\./.test(containerHostname)) {
return (
content.lastIndexOf(container) ===
content.length - container.length
contentHostname.lastIndexOf(containerHostname) ===
contentHostname.length - containerHostname.length
) || (
container.slice(1) === content
containerHostname.slice(1) === contentHostname
);
} else {
return container === content;
return containerHostname === contentHostname;
}

@@ -143,0 +171,0 @@ };

@@ -190,4 +190,5 @@ /**

/*** {String} host */
request.host = request.hostname + ":" + address.port;
request.port = address.port;
var defaultPort = request.port === (ssl ? 443 : 80);
request.host = request.hostname + (defaultPort ? "" : ":" + request.port);

@@ -233,16 +234,34 @@ var socket = _request.socket;

if (typeof request === "string") {
request = {
url: request
};
request = {url: request};
}
request.method = request.method || "GET";
request.headers = request.headers || {};
if (request.url) {
var url = URL.parse(request.url);
request.host = url.hostname;
request.port = url.port;
request.ssl = url.protocol === "https:";
request.method = request.method || "GET";
request.hostname = url.hostname;
request.host = url.host;
request.port = +url.port;
request.path = (url.pathname || "") + (url.search || "");
request.headers = request.headers || {};
request.headers.host = url.hostname; // FIXME name consistency
if (url.auth) {
request.auth = url.auth;
if (!request.headers["authorization"]) {
request.headers["authorization"] = (
"Basic " + new Buffer(url.auth)
.toString("base64")
);
}
}
}
request.host = request.host || request.headers.host;
request.port = request.port || (request.ssl ? 443 : 80);
if (request.host && !request.hostname) {
request.hostname = request.host.split(":")[0];
}
if (request.hostname && request.port && !request.host) {
var defaultPort = request.ssl ? 443 : 80;
request.host = request.hostname + (defaultPort ? "" : ":" + request.port);
}
request.headers.host = request.headers.host || request.host;
request.path = request.path || "/";
return request;

@@ -281,17 +300,17 @@ };

var deferred = Q.defer();
var ssl = request.ssl;
var http = ssl ? HTTPS : HTTP;
var http = request.ssl ? HTTPS : HTTP;
var headers = request.headers || {};
var requestOptions = {
"host": request.hostname, // Node.js quirk
"port": request.port || (request.ssl ? 443 : 80),
"path": request.path || "/",
"method": request.method || "GET",
"headers": request.headers
};
headers.host = headers.host || request.host;
if (request.agent) {
requestOptions.agent = request.agent;
}
var _request = http.request({
"host": request.host,
"port": request.port || (ssl ? 443 : 80),
"path": request.path || "/",
"method": request.method || "GET",
"headers": headers,
"agent": request.agent
}, function (_response) {
var _request = http.request(requestOptions, function (_response) {
deferred.resolve(exports.ClientResponse(_response, request.charset));

@@ -298,0 +317,0 @@ _response.on("error", function (error) {

{
"name": "q-io",
"version": "1.11.0",
"version": "1.11.1",
"description": "IO using Q promises",
"homepage": "http://github.com/kriskowal/q-io/",
"author": "Kris Kowal <kris@cixar.com> (http://github.com/kriskowal/)",
"contributors": [
"Montage Studio",
"Stuart Knightley",
"Jean-romain Prevost",
"Andreas Pizsa (http://github.com/AndreasPizsa/)"
],
"bugs": {

@@ -8,0 +14,0 @@ "mail": "kris@cixar.com",

@@ -56,3 +56,37 @@ "use strict";

it("should preserve permissions", function () {
var mock = Mock({
"a/b": {
"c": {
"d": 66,
"e": 99
}
}
});
var mode0777 = parseInt("0777", 8);
var mode0700 = parseInt("0700", 8);
return Q.all([
mock.chmod("a/b/c/d", mode0777),
mock.chmod("a/b", mode0700),
mock.chmod("a/b/c", mode0700)
])
.then(function () {
return mock.copyTree("a/b", "a/f");
})
.then(function () {
return Q.all([
mock.stat("a/f/c/d"),
mock.stat("a/f"),
mock.stat("a/f/c")
]);
})
.spread(function (dStat, fStat, cStat) {
expect(dStat.node.mode & mode0777).toEqual(mode0777);
expect(fStat.node.mode & mode0777).toEqual(mode0700);
expect(cStat.node.mode & mode0777).toEqual(mode0700);
});
});
});

@@ -12,3 +12,3 @@

hosts.forEach(function (host) {
it("should work on host" + host, function () {
it("should work on host " + host, function () {

@@ -15,0 +15,0 @@ var server = Http.Server(function (request) {

@@ -94,4 +94,21 @@

it('should set correct HTTP Basic authentication headers when username and password are passed in the URL',function(){
request = HTTP.normalizeRequest('http://username:password@www.google.com/');
expect(request.auth).toBe('username:password');
expect(request.headers.authorization).toBe('Basic dXNlcm5hbWU6cGFzc3dvcmQ=');
});
it('should successfully access resources that require HTTP Basic authentication when using the username:password@host.com URL syntax', function(){
// This tries to access a public resource, see http://test.webdav.org/
//
// The resource is password protected, but there's no content behind it
// so we will actually receive a 404; that's ok though as at least it's
// a well-defined and expected status.
return HTTP.request('http://user1:user1@test.webdav.org/auth-basic/')
.then(function(response){
expect(response.status).not.toBe(401);
expect(response.status).toBe(404);
});
});
});

@@ -109,4 +109,6 @@

self.node = _stream;
return Q(self); // todo returns the begin.promise
}
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