git-off

Log

Files

Refs

README

xhr.js (3627B)

     1 var AWS = require('../core');
     2 var EventEmitter = require('events').EventEmitter;
     3 require('../http');
     4 
     5 /**
     6  * @api private
     7  */
     8 AWS.XHRClient = AWS.util.inherit({
     9   handleRequest: function handleRequest(httpRequest, httpOptions, callback, errCallback) {
    10     var self = this;
    11     var endpoint = httpRequest.endpoint;
    12     var emitter = new EventEmitter();
    13     var href = endpoint.protocol + '//' + endpoint.hostname;
    14     if (endpoint.port !== 80 && endpoint.port !== 443) {
    15       href += ':' + endpoint.port;
    16     }
    17     href += httpRequest.path;
    18 
    19     var xhr = new XMLHttpRequest(), headersEmitted = false;
    20     httpRequest.stream = xhr;
    21 
    22     xhr.addEventListener('readystatechange', function() {
    23       try {
    24         if (xhr.status === 0) return; // 0 code is invalid
    25       } catch (e) { return; }
    26 
    27       if (this.readyState >= this.HEADERS_RECEIVED && !headersEmitted) {
    28         try { xhr.responseType = 'arraybuffer'; } catch (e) {}
    29         emitter.statusCode = xhr.status;
    30         emitter.headers = self.parseHeaders(xhr.getAllResponseHeaders());
    31         emitter.emit('headers', emitter.statusCode, emitter.headers);
    32         headersEmitted = true;
    33       }
    34       if (this.readyState === this.DONE) {
    35         self.finishRequest(xhr, emitter);
    36       }
    37     }, false);
    38     xhr.upload.addEventListener('progress', function (evt) {
    39       emitter.emit('sendProgress', evt);
    40     });
    41     xhr.addEventListener('progress', function (evt) {
    42       emitter.emit('receiveProgress', evt);
    43     }, false);
    44     xhr.addEventListener('timeout', function () {
    45       errCallback(AWS.util.error(new Error('Timeout'), {code: 'TimeoutError'}));
    46     }, false);
    47     xhr.addEventListener('error', function () {
    48       errCallback(AWS.util.error(new Error('Network Failure'), {
    49         code: 'NetworkingError'
    50       }));
    51     }, false);
    52 
    53     callback(emitter);
    54     xhr.open(httpRequest.method, href, httpOptions.xhrAsync !== false);
    55     AWS.util.each(httpRequest.headers, function (key, value) {
    56       if (key !== 'Content-Length' && key !== 'User-Agent' && key !== 'Host') {
    57         xhr.setRequestHeader(key, value);
    58       }
    59     });
    60 
    61     if (httpOptions.timeout && httpOptions.xhrAsync !== false) {
    62       xhr.timeout = httpOptions.timeout;
    63     }
    64 
    65     if (httpOptions.xhrWithCredentials) {
    66       xhr.withCredentials = true;
    67     }
    68 
    69     try {
    70       xhr.send(httpRequest.body);
    71     } catch (err) {
    72       if (httpRequest.body && typeof httpRequest.body.buffer === 'object') {
    73         xhr.send(httpRequest.body.buffer); // send ArrayBuffer directly
    74       } else {
    75         throw err;
    76       }
    77     }
    78 
    79     return emitter;
    80   },
    81 
    82   parseHeaders: function parseHeaders(rawHeaders) {
    83     var headers = {};
    84     AWS.util.arrayEach(rawHeaders.split(/\r?\n/), function (line) {
    85       var key = line.split(':', 1)[0];
    86       var value = line.substring(key.length + 2);
    87       if (key.length > 0) headers[key.toLowerCase()] = value;
    88     });
    89     return headers;
    90   },
    91 
    92   finishRequest: function finishRequest(xhr, emitter) {
    93     var buffer;
    94     if (xhr.responseType === 'arraybuffer' && xhr.response) {
    95       var ab = xhr.response;
    96       buffer = new AWS.util.Buffer(ab.byteLength);
    97       var view = new Uint8Array(ab);
    98       for (var i = 0; i < buffer.length; ++i) {
    99         buffer[i] = view[i];
   100       }
   101     }
   102 
   103     try {
   104       if (!buffer && typeof xhr.responseText === 'string') {
   105         buffer = new AWS.util.Buffer(xhr.responseText);
   106       }
   107     } catch (e) {}
   108 
   109     if (buffer) emitter.emit('data', buffer);
   110     emitter.emit('end');
   111   }
   112 });
   113 
   114 /**
   115  * @api private
   116  */
   117 AWS.HttpClient.prototype = AWS.XHRClient.prototype;
   118 
   119 /**
   120  * @api private
   121  */
   122 AWS.HttpClient.streamsApiVersion = 1;