11'use strict' ;
22
3+ /* global ArrayBuffer */
4+
35/**
46 * Node.js `XMLHttpRequest` implementation using `http.request()`.
57 *
@@ -24,7 +26,11 @@ var supportedResponseTypes = Object.freeze({
2426 /** Text response (implicit) */
2527 '' : true ,
2628 /** Text response */
27- 'text' : true
29+ 'text' : true ,
30+ /** Binary-data response */
31+ 'arraybuffer' : true ,
32+ /** JSON response */
33+ 'json' : true
2834} ) ;
2935
3036/**
@@ -139,6 +145,14 @@ module.exports = function () {
139145 * @type {?String }
140146 */
141147 this . _responseText = null ;
148+
149+ /**
150+ * @see https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/response
151+ *
152+ * @private
153+ * @type {ArrayBuffer | String | Object }
154+ */
155+ this . _response = null ;
142156} ;
143157
144158/** @alias module:node-http-xhr */
@@ -297,7 +311,15 @@ NodeHttpXHR.prototype = Object.create(
297311 throw new Error ( 'Unsupported responseType "' + type + '"' ) ;
298312 }
299313
300- return this . _responseText ;
314+ switch ( type ) {
315+ case '' :
316+ case 'text' :
317+ return this . _responseText ;
318+ case 'arraybuffer' :
319+ return this . _response ;
320+ default :
321+ throw new Error ( 'Assertion failed: unsupported response-type: ' + type ) ;
322+ }
301323 }
302324 } ,
303325 /**
@@ -308,10 +330,19 @@ NodeHttpXHR.prototype = Object.create(
308330 * This will be incomplete until the response actually finishes.
309331 *
310332 * @type {?String }
333+ * @throws when `response` not a String
311334 * @readonly
312335 */
313336 responseText : {
314- get : function getResponseText ( ) { return this . _responseText ; }
337+ get : function getResponseText ( ) {
338+
339+ // @see https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseText#Exceptions
340+ if ( this . _responseType !== 'text' && this . _responseType !== '' ) {
341+ throw new Error ( 'InvalidStateError: Response-type is ' + this . _responseType ) ;
342+ }
343+
344+ return this . _responseText ;
345+ }
315346 } ,
316347 /**
317348 * Indicates whether or not cross-site `Access-Control` requests should be
@@ -469,13 +500,35 @@ NodeHttpXHR.prototype.send = function (data) {
469500 this . _resp = resp ;
470501 this . _responseText = '' ;
471502
472- resp . setEncoding ( 'utf8' ) ;
503+ // var contentType = resp.headers['content-type'];
504+ // TODO: adjust responseType from content-type header if applicable
505+
506+ // from Node API docs: The encoding argument is optional and only applies when chunk is a string. Defaults to 'utf8'.
507+ if ( this . _responseType === 'text' || this . _responseType === '' ) {
508+ resp . setEncoding ( 'utf8' ) ;
509+ }
510+
473511 resp . on ( 'data' , function onData ( chunk ) {
474- this . _responseText += chunk ;
512+
513+ if ( typeof chunk === 'string' ) {
514+ this . _responseText += chunk ;
515+ } else if ( typeof chunk === 'object' ) {
516+ // binary data usually comes in one chunk (no chunky transfer-encoding)
517+ // or at least, that's what we'll support here for now
518+ if ( chunk instanceof Buffer ) {
519+ this . _response = chunk . buffer ;
520+ } else if ( chunk instanceof ArrayBuffer ) {
521+ this . _response = chunk ;
522+ } else {
523+ // JSON case
524+ this . _response = chunk ;
525+ }
526+ }
475527
476528 if ( this . readyState !== this . LOADING ) {
477529 this . _setReadyState ( this . LOADING ) ;
478530 }
531+
479532 } . bind ( this ) ) ;
480533
481534 resp . on ( 'end' , function onEnd ( ) {
0 commit comments