Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

urllib

Package Overview
Dependencies
Maintainers
1
Versions
222
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

urllib - npm Package Compare versions

Comparing version 0.5.11 to 0.5.12

6

History.md
0.5.12 / 2014-03-29
==================
* support Digest access authentication. fix #27
* add co-urllib desc
0.5.11 / 2014-03-13

@@ -3,0 +9,0 @@ ==================

109

lib/urllib.js

@@ -18,2 +18,4 @@ /**!

var debug = require('debug')('urllib');
var utility = require('utility');
var crypto = require('crypto');
var http = require('http');

@@ -74,2 +76,3 @@ var https = require('https');

* - {String} [auth]: Basic authentication i.e. 'user:password' to compute an Authorization header.
* - {String} [digestAuth]: Digest authentication i.e. 'user:password' to compute an Authorization header.
* - {String|Buffer|Array} [ca]: An array of strings or Buffers of trusted certificates.

@@ -230,2 +233,19 @@ * If this is omitted several well known "root" CAs will be used, like VeriSign.

}
// handle digest auth
if (res && res.statusCode === 401 && res.headers['www-authenticate']
&& (!args.headers || !args.headers.Authorization) && args.digestAuth) {
var authenticate = res.headers['www-authenticate'];
if (authenticate.indexOf('Digest ') >= 0) {
debug('Request#%d %s: got degist auth header WWW-Authenticate: %s', reqId, url, authenticate);
args.headers = args.headers || {};
args.headers.Authorization = digestAuthHeader(options.method, options.path, authenticate, args.digestAuth);
debug('Request#%d %s: auth with digest header: %s', reqId, url, args.headers.Authorization);
if (res.headers['set-cookie']) {
args.headers.Cookie = res.headers['set-cookie'].join(';');
}
return exports.request(url, args, cb);
}
}
cb(err, data, res);

@@ -293,6 +313,7 @@ };

var reqId = ++REQUEST_ID;
debug('Request#%d %s %s with headers %j', reqId, method, url, options.headers);
var req = httplib.request(options, function (res) {
connnected = true;
debug('Request#%d %s `req response` event emit: status %d, headers: %j',
reqId, options.path, res.statusCode, res.headers);
reqId, url, res.statusCode, res.headers);

@@ -346,3 +367,3 @@ if (writeStream) {

res.on('data', function (chunk) {
debug('Request#%d %s: `res data` event emit, size %d', reqId, options.path, chunk.length);
debug('Request#%d %s: `res data` event emit, size %d', reqId, url, chunk.length);
size += chunk.length;

@@ -353,7 +374,7 @@ chunks.push(chunk);

res.on('close', function () {
debug('Request#%d %s: `res close` event emit, total size %d', reqId, options.path, size);
debug('Request#%d %s: `res close` event emit, total size %d', reqId, url, size);
});
res.on('error', function () {
debug('Request#%d %s: `res error` event emit, total size %d', reqId, options.path, size);
debug('Request#%d %s: `res error` event emit, total size %d', reqId, url, size);
});

@@ -363,3 +384,3 @@

res.aborted = true;
debug('Request#%d %s: `res aborted` event emit, total size %d', reqId, options.path, size);
debug('Request#%d %s: `res aborted` event emit, total size %d', reqId, url, size);
});

@@ -369,3 +390,3 @@

var body = Buffer.concat(chunks, size);
debug('Request#%d %s: `res end` event emit, total size %d, _dumped: %s', reqId, options.path, size, res._dumped);
debug('Request#%d %s: `res end` event emit, total size %d, _dumped: %s', reqId, url, size, res._dumped);

@@ -466,1 +487,77 @@ if (__err && connnected) {

};
var AUTH_KEY_VALUE_RE = /(\w+)=["']?([^'"\s]+)["']?/;
var NC = 0;
var NC_PAD = '00000000';
function digestAuthHeader(method, pathname, auth, userpass, options) {
var parts = auth.split(',');
var opts = {};
for (var i = 0; i < parts.length; i++) {
var m = parts[i].match(AUTH_KEY_VALUE_RE);
if (m) {
opts[m[1]] = m[2].replace(/["']/g, '');
}
}
if (!opts.realm || !opts.nonce) {
return '';
}
var qop = opts.qop || '';
// WWW-Authenticate: Digest realm="testrealm@host.com",
// qop="auth,auth-int",
// nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
// opaque="5ccc069c403ebaf9f0171e9517f40e41"
// Authorization: Digest username="Mufasa",
// realm="testrealm@host.com",
// nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
// uri="/dir/index.html",
// qop=auth,
// nc=00000001,
// cnonce="0a4f113b",
// response="6629fae49393a05397450978507c4ef1",
// opaque="5ccc069c403ebaf9f0171e9517f40e41"
// HA1 = MD5( "Mufasa:testrealm@host.com:Circle Of Life" )
// = 939e7578ed9e3c518a452acee763bce9
//
// HA2 = MD5( "GET:/dir/index.html" )
// = 39aff3a2bab6126f332b942af96d3366
//
// Response = MD5( "939e7578ed9e3c518a452acee763bce9:\
// dcd98b7102dd2f0e8b11d0f600bfb0c093:\
// 00000001:0a4f113b:auth:\
// 39aff3a2bab6126f332b942af96d3366" )
// = 6629fae49393a05397450978507c4ef1
userpass = userpass.split(':');
var nc = String(++NC);
nc = NC_PAD.substring(nc.length) + nc;
var cnonce = crypto.randomBytes(8).toString('hex');
if (options) {
nc = options.nc || nc;
cnonce = options.cnonce;
}
var ha1 = utility.md5(userpass[0] + ':' + opts.realm + ':' + userpass[1]);
var ha2 = utility.md5(method.toUpperCase() + ':' + pathname);
var s = ha1 + ':' + opts.nonce;
if (qop) {
qop = qop.split(',')[0];
s += ':' + nc + ':' + cnonce + ':' + qop;
}
s += ':' + ha2;
var response = utility.md5(s);
var authstring = 'Digest username="' + userpass[0] + '", realm="' + opts.realm
+ '", nonce="' + opts.nonce + '", uri="' + pathname
+ '", response="' + response + '"';
if (opts.opaque) {
authstring += ', opaque="' + opts.opaque + '"';
}
if (qop) {
authstring +=', qop=' + qop + ', nc=' + nc + ', cnonce="' + cnonce + '"';
}
return authstring;
}
exports.digestAuthHeader = digestAuthHeader;

7

package.json
{
"name": "urllib",
"version": "0.5.11",
"version": "0.5.12",
"description": "Help in opening URLs (mostly HTTP) in a complex world — basic and digest authentication, redirections, cookies and more.",

@@ -21,3 +21,4 @@ "keywords": [ "urllib", "http", "urlopen", "curl", "wget", "request", "https" ],

"debug": "0.7.4",
"default-user-agent": "0.0.1"
"default-user-agent": "0.0.1",
"utility": "0.1.11"
},

@@ -32,3 +33,3 @@ "devDependencies": {

"pedding": "0.0.3",
"should": "3.1.3"
"should": "3.2.0-beta1"
},

@@ -35,0 +36,0 @@ "engines": { "node": ">= 0.8.0" },

@@ -10,2 +10,5 @@ # urllib [![Build Status](https://secure.travis-ci.org/fengmk2/urllib.png?branch=master)](http://travis-ci.org/fengmk2/urllib)

If you are using [co](https://github.com/visionmedia/co) or [koa](https://github.com/koajs/koa),
please take a look at [co-urllib](https://github.com/dead-horse/co-urllib).
## Install

@@ -50,2 +53,3 @@

- ***auth*** String - `username:password` used in HTTP Basic Authorization.
- ***digestAuth*** String - `username:password` used in HTTP [Digest Authorization](http://en.wikipedia.org/wiki/Digest_access_authentication).
- ***agent*** [http.Agent](http://nodejs.org/api/http.html#http_class_http_agent) - HTTP Agent object.

@@ -213,2 +217,3 @@ Set `false` if you does not use agent.

* [√] Support `Accept-Encoding=gzip` by `options.gzip = true`
* [√] Support [Digest access authentication](http://en.wikipedia.org/wiki/Digest_access_authentication)

@@ -215,0 +220,0 @@ ## Authors

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