Skip to content

Commit 4785a4b

Browse files
committed
experimental: use request/request instead of built-in things to implement following redirects etc
1 parent 0c370c9 commit 4785a4b

File tree

3 files changed

+1142
-153
lines changed

3 files changed

+1142
-153
lines changed

lib/index.js

Lines changed: 101 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,21 @@
88
*/
99

1010
var url = require('url');
11-
var http = require('http');
12-
var https = require('https');
11+
var http = require('follow-redirects').http; // Drop-in replacement for Nodes http and https that automatically follows redirects.
12+
var https = require('follow-redirects').https;
13+
var request = require('request');
1314

1415
var NodeXHREventTarget = require('./node-xhr-event-target');
1516

17+
function utf8StringToArray(str) {
18+
var buf = new ArrayBuffer(str.length); // 2 bytes for each char
19+
var bufView = new Uint8Array(buf);
20+
for (var i=0, strLen=str.length; i < strLen; i++) {
21+
bufView[i] = str.charCodeAt(i);
22+
}
23+
return buf;
24+
}
25+
1626
/**
1727
* Currently-supported response types.
1828
*
@@ -38,16 +48,26 @@ var supportedResponseTypes = Object.freeze({
3848
* @private
3949
* @param {Object} opts - Options for the request.
4050
* @param {Function} cb - Callback for request.
41-
* @returns {ClientRequest} The request.
4251
*/
4352
function makeRequest(opts, cb) {
44-
if (opts.protocol === 'http:') {
45-
return http.request(opts, cb);
46-
} else if (opts.protocol === 'https:') {
47-
return https.request(opts, cb);
48-
}
53+
opts.gzip = true;
54+
return request(opts, cb)
55+
}
4956

50-
throw new Error('Unsupported protocol "' + opts.protcol + '"');
57+
/**
58+
* @param {NodeRequestOptions} opts
59+
* @param {string} reqUrl
60+
*/
61+
function setUrl(opts, reqUrl) {
62+
var urlObj = url.parse(reqUrl);
63+
/*
64+
['protocol', 'hostname', 'port', 'path'].forEach(function (key) {
65+
if (key in urlObj) {
66+
opts[key] = urlObj[key];
67+
}
68+
});
69+
*/
70+
opts.url = urlObj;
5171
}
5272

5373
/**
@@ -436,12 +456,7 @@ NodeHttpXHR.prototype.open = function (method, reqUrl, async) {
436456
var opts = this._reqOpts;
437457
opts.method = method;
438458

439-
var urlObj = url.parse(reqUrl);
440-
['protocol', 'hostname', 'port', 'path'].forEach(function (key) {
441-
if (key in urlObj) {
442-
opts[key] = urlObj[key];
443-
}
444-
});
459+
setUrl(opts, reqUrl);
445460

446461
this._setReadyState(this.OPENED);
447462
};
@@ -496,52 +511,94 @@ NodeHttpXHR.prototype.send = function (data) {
496511
}.bind(this);
497512

498513
var opts = this._reqOpts;
499-
var req = makeRequest(opts, function onResponse(resp) {
514+
515+
var req = makeRequest(opts, function onResponse(err, resp, body) {
516+
517+
if (this.readyState !== this.LOADING) {
518+
this._setReadyState(this.LOADING);
519+
}
520+
521+
if (err) {
522+
if (this._listenerCount('error') < 1) {
523+
// Uncaught error; throw something more meaningful
524+
throw err;
525+
}
526+
527+
// Dispatch an error event. The specification does not provide for any way
528+
// to communicate the failure reason with the event object.
529+
this.dispatchEvent({
530+
type: 'error'
531+
});
532+
533+
this._setReadyState(this.DONE);
534+
return;
535+
}
536+
500537
this._resp = resp;
501538
this._responseText = '';
539+
this._response = null;
540+
541+
if (typeof body === 'string') {
542+
this._responseText = body;
543+
} else if (typeof body === 'object') {
544+
if (!(body instanceof Buffer)) {
545+
throw new Error('Assertion failed: Response-data should be of `Buffer` type');
546+
}
547+
this._response = body;
548+
}
549+
550+
if (this._responseType === 'arraybuffer' && this._responseText) {
551+
this._response = Buffer.from(utf8StringToArray(this._responseText));
552+
}
502553

503554
// var contentType = resp.headers['content-type'];
504555
// TODO: adjust responseType from content-type header if applicable
505556

506557
// from Node API docs: The encoding argument is optional and only applies when chunk is a string. Defaults to 'utf8'.
558+
/*
507559
if (this._responseType === 'text' || this._responseType === '') {
508560
resp.setEncoding('utf8');
509561
}
562+
*/
510563

511-
resp.on('data', function onData(chunk) {
564+
this._setReadyState(this.HEADERS_RECEIVED);
512565

513-
if (typeof chunk === 'string') {
514-
this._responseText += chunk;
515-
} else if (typeof chunk === 'object') {
516-
if (!(chunk instanceof Buffer)) {
517-
throw new Error('Assertion failed: Response-data should be of `Buffer` type');
518-
}
519-
if (this._response) {
520-
this._response = Buffer.concat([this._response, chunk]);
521-
} else {
522-
this._response = chunk;
523-
}
524-
}
566+
this._setReadyState(this.DONE);
525567

526-
if (this.readyState !== this.LOADING) {
527-
this._setReadyState(this.LOADING);
528-
}
568+
this.dispatchEvent({
569+
type: 'load'
570+
});
529571

530-
}.bind(this));
531572

532-
resp.on('end', function onEnd() {
533-
this._setReadyState(this.DONE);
534-
this.dispatchEvent({
535-
type: 'load'
536-
});
537-
}.bind(this));
573+
}.bind(this));
538574

539-
this._setReadyState(this.HEADERS_RECEIVED);
575+
/*
576+
req.on('data', function onData(chunk) {
577+
578+
if (typeof chunk === 'string') {
579+
this._responseText += chunk;
580+
} else if (typeof chunk === 'object') {
581+
if (!(chunk instanceof Buffer)) {
582+
throw new Error('Assertion failed: Response-data should be of `Buffer` type');
583+
}
584+
if (this._response) {
585+
this._response = Buffer.concat([this._response, chunk]);
586+
} else {
587+
this._response = chunk;
588+
}
589+
}
590+
591+
if (this.readyState !== this.LOADING) {
592+
this._setReadyState(this.LOADING);
593+
}
540594
}.bind(this));
595+
*/
541596

542597
// Passing `opts.timeout` doesn't actually seem to set the timeout sometimes,
543598
// so it is set manually here.
544-
req.setTimeout(opts.timeout);
599+
//req.setTimeout(opts.timeout);
600+
601+
/*
545602
546603
req.on('abort', onAbort);
547604
req.on('aborted', onAbort);
@@ -568,11 +625,14 @@ NodeHttpXHR.prototype.send = function (data) {
568625
this._setReadyState(this.DONE);
569626
}.bind(this));
570627
628+
571629
if (data) {
572630
req.write(data);
573631
}
574632
req.end();
575633
634+
*/
635+
576636
this._req = req;
577637
};
578638

0 commit comments

Comments
 (0)