From 843b96d1822a28cee8eed1776aa37b6322432249 Mon Sep 17 00:00:00 2001 From: James Lal Date: Mon, 7 Jan 2013 18:39:12 +0100 Subject: don't hold onto .xhr in request --- caldav.js | 28 ++++------ lib/caldav/request/abstract.js | 3 +- lib/caldav/request/errors.js | 8 +-- lib/caldav/xhr.js | 13 +---- test/caldav/request/abstract_test.js | 4 +- test/caldav/xhr_test.js | 101 +---------------------------------- test/helper.js | 1 + 7 files changed, 19 insertions(+), 139 deletions(-) diff --git a/caldav.js b/caldav.js index 32cfb34..6975f65 100644 --- a/caldav.js +++ b/caldav.js @@ -2039,15 +2039,6 @@ function write (chunk) { return this.data; }, - /** - * Aborts request if its in progress. - */ - abort: function abort() { - if (this.xhr) { - this.xhr.abort(); - } - }, - /** * @param {String} user basic auth user. * @param {String} password basic auth pass. @@ -2078,8 +2069,6 @@ function write (chunk) { xhr = new this.xhrClass(); } - this.xhr = xhr; - // This hack is in place due to some platform // bug in gecko when using mozSystem xhr // the credentials only seem to work as expected @@ -2136,6 +2125,8 @@ function write (chunk) { this.waiting = true; xhr.send(this._seralize()); + + return xhr; } }; @@ -2602,26 +2593,26 @@ function write (chunk) { default: message = this.code; } - Error.call(this, message); } + CaldavHttpError.prototype = { __proto__: Error.prototype, constructor: CaldavHttpError } - + // Unauthenticated error for // Google Calendar function UnauthenticatedError() { var message = "Wrong username or/and password"; Error.call(this, message); } - + UnauthenticatedError.prototype = { __proto__: Error.prototype, constructor: UnauthenticatedError } - + module.exports = { CaldavHttpError: CaldavHttpError, UnauthenticatedError: UnauthenticatedError @@ -2700,8 +2691,7 @@ function write (chunk) { }; // in the future we may stream data somehow - req.send(function xhrResult() { - var xhr = req.xhr; + req.send(function xhrResult(err, xhr) { if (xhr.status > 199 && xhr.status < 300) { // success self.sax.close(); @@ -3021,8 +3011,7 @@ function write (chunk) { content += this.filter.toString(); } - var out = this.template.render(content); - return out; + return this.template.render(content); } }; @@ -3110,6 +3099,7 @@ function write (chunk) { if (!principal) { principal = findProperty('principal-URL', data, true); } + if ('unauthenticated' in principal) { callback(new Errors.UnauthenticatedError()); } else if (principal.href){ diff --git a/lib/caldav/request/abstract.js b/lib/caldav/request/abstract.js index eb6297b..7116217 100644 --- a/lib/caldav/request/abstract.js +++ b/lib/caldav/request/abstract.js @@ -65,8 +65,7 @@ }; // in the future we may stream data somehow - req.send(function xhrResult() { - var xhr = req.xhr; + req.send(function xhrResult(err, xhr) { if (xhr.status > 199 && xhr.status < 300) { // success self.sax.close(); diff --git a/lib/caldav/request/errors.js b/lib/caldav/request/errors.js index c3c166e..700cfba 100644 --- a/lib/caldav/request/errors.js +++ b/lib/caldav/request/errors.js @@ -16,26 +16,26 @@ default: message = this.code; } - Error.call(this, message); } + CaldavHttpError.prototype = { __proto__: Error.prototype, constructor: CaldavHttpError } - + // Unauthenticated error for // Google Calendar function UnauthenticatedError() { var message = "Wrong username or/and password"; Error.call(this, message); } - + UnauthenticatedError.prototype = { __proto__: Error.prototype, constructor: UnauthenticatedError } - + module.exports = { CaldavHttpError: CaldavHttpError, UnauthenticatedError: UnauthenticatedError diff --git a/lib/caldav/xhr.js b/lib/caldav/xhr.js index abeae79..230f656 100644 --- a/lib/caldav/xhr.js +++ b/lib/caldav/xhr.js @@ -57,15 +57,6 @@ return this.data; }, - /** - * Aborts request if its in progress. - */ - abort: function abort() { - if (this.xhr) { - this.xhr.abort(); - } - }, - /** * @param {String} user basic auth user. * @param {String} password basic auth pass. @@ -96,8 +87,6 @@ xhr = new this.xhrClass(); } - this.xhr = xhr; - // This hack is in place due to some platform // bug in gecko when using mozSystem xhr // the credentials only seem to work as expected @@ -154,6 +143,8 @@ this.waiting = true; xhr.send(this._seralize()); + + return xhr; } }; diff --git a/test/caldav/request/abstract_test.js b/test/caldav/request/abstract_test.js index ee70b67..21bde48 100644 --- a/test/caldav/request/abstract_test.js +++ b/test/caldav/request/abstract_test.js @@ -79,11 +79,10 @@ suite('caldav/request/abstract.js', function() { done(); }); - xhr = getXhr(); xhr.respond('NOT XML
', 500); }); - + test('on response', function() { assert.equal(calledWith[0].code, 500); }); @@ -110,7 +109,6 @@ suite('caldav/request/abstract.js', function() { item: { value: 'value' } } }); - assert.equal(calledWith[2].xhr, xhr); }); }); }); diff --git a/test/caldav/xhr_test.js b/test/caldav/xhr_test.js index fdcbe37..aa9b4f2 100644 --- a/test/caldav/xhr_test.js +++ b/test/caldav/xhr_test.js @@ -36,16 +36,6 @@ suite('webacls/xhr', function() { teardown(function() { Xhr.prototype.globalXhrOptions = old; }); - - test('constructed xhr', function() { - var subject = new Xhr({ - method: 'POST', - xhrClass: FakeXhr - }); - subject.send(function() {}); - assert.ok(subject.xhr); - assert.equal(subject.xhr.constructorArgs[0], opts); - }); }); }); @@ -64,33 +54,6 @@ suite('webacls/xhr', function() { ); }); - suite('.abort', function() { - suite('when there is an xhr object', function() { - var aborted; - - setup(function() { - aborted = false; - subject.xhr = { - abort: function() { - aborted = true; - } - }; - subject.abort(); - }); - - test('should call abort on the xhr object', function() { - assert.equal(aborted, true); - }); - }); - - suite('when there is no xhr object', function() { - test('should not fail', function() { - subject.xhr = null; - subject.abort(); - }); - }); - }); - suite('.send', function() { var data = '', @@ -108,65 +71,10 @@ suite('webacls/xhr', function() { subject = new Xhr(options); } - function opensXHR() { - test('should create xhr', function() { - assert.instanceOf(subject.xhr, FakeXhr); - }); - - test('should set headers', function() { - assert.deepEqual(subject.xhr.headers, subject.headers); - }); - - test('should parse and send data', function() { - assert.deepEqual(subject.xhr.sendArgs[0], data); - }); - - test('should open xhr', function() { - assert.deepEqual(subject.xhr.openArgs, [ - subject.method, - subject.url, - subject.async, - subject.user, - subject.password - ]); - }); - } - setup(function() { responseXhr = null; }); - test('with mozSystem', function() { - if (typeof(window) === 'undefined') - return; - - var user = 'user'; - var password = 'pass'; - var url = '/foo'; - - request({ - globalXhrOptions: { mozSystem: true }, - user: user, - password: password, - method: 'GET', - url: url - }); - - - subject.send(function() {}); - var args = subject.xhr.openArgs; - - assert.deepEqual( - args, - ['GET', url, true] - ); - - assert.equal( - subject.xhr.headers['Authorization'], - subject._credentials(user, password) - ); - }); - suite('when xhr is a success and responds /w data', function() { var response = '', cb; @@ -178,12 +86,11 @@ suite('webacls/xhr', function() { method: 'PUT' }); cb = callback.bind(this, done); - subject.send(cb); + xhr = subject.send(cb); //should be waiting inbetween requests assert.equal(subject.waiting, true); - xhr = subject.xhr; xhr.readyState = 4; xhr.responseText = response; xhr.onreadystatechange(); @@ -192,12 +99,6 @@ suite('webacls/xhr', function() { test('should not be waiting after response', function() { assert.equal(subject.waiting, false); }); - - test('should send callback parsed data and xhr', function() { - assert.equal(responseXhr, subject.xhr); - }); - - opensXHR(); }); }); diff --git a/test/helper.js b/test/helper.js index 64346bd..df0c6d9 100644 --- a/test/helper.js +++ b/test/helper.js @@ -173,6 +173,7 @@ testSupport.lib('sax'); testSupport.lib('sax/base'); testSupport.lib('sax/dav_response'); + testSupport.lib('request/errors'); testSupport.lib('request/abstract'); testSupport.lib('template'); testSupport.helper('fake_xhr'); -- cgit From ff00ab9fcaf0f791b1873ca1cd4d80e8a6dd6cda Mon Sep 17 00:00:00 2001 From: James Lal Date: Wed, 9 Jan 2013 11:21:04 +0100 Subject: utilize moz-chunked-text when given the option --- caldav.js | 28 +++++++++++++++------- lib/caldav/xhr.js | 28 +++++++++++++++------- test/caldav/xhr_test.js | 63 ++++++++++++++++++++++++++++++++++++------------- 3 files changed, 86 insertions(+), 33 deletions(-) diff --git a/caldav.js b/caldav.js index 6975f65..7f3d367 100644 --- a/caldav.js +++ b/caldav.js @@ -2068,7 +2068,6 @@ function write (chunk) { } else { xhr = new this.xhrClass(); } - // This hack is in place due to some platform // bug in gecko when using mozSystem xhr // the credentials only seem to work as expected @@ -2083,6 +2082,12 @@ function write (chunk) { )); } + var useMozChunkedText = false; + if (this.globalXhrOptions && this.globalXhrOptions.useMozChunkedText) { + useMozChunkedText = true; + xhr.responseType = 'moz-chunked-text'; + } + for (header in this.headers) { if (Object.hasOwnProperty.call(this.headers, header)) { xhr.setRequestHeader(header, this.headers[header]); @@ -2096,13 +2101,20 @@ function write (chunk) { if ('onprogress' in xhr) { hasProgressEvents = true; var last = 0; - xhr.onprogress = function onProgress(event) { - var chunk = xhr.responseText.substr(last, event.loaded); - last = event.loaded; - if (this.ondata) { - this.ondata(chunk); - } - }.bind(this); + + if (useMozChunkedText) { + xhr.onprogress = function onChunkedProgress(event) { + this.ondata(xhr.responseText); + }.bind(this); + } else { + xhr.onprogress = function onProgress(event) { + var chunk = xhr.responseText.substr(last, event.loaded); + last = event.loaded; + if (this.ondata) { + this.ondata(chunk); + } + }.bind(this); + } } xhr.onreadystatechange = function onReadyStateChange() { diff --git a/lib/caldav/xhr.js b/lib/caldav/xhr.js index 230f656..d49186b 100644 --- a/lib/caldav/xhr.js +++ b/lib/caldav/xhr.js @@ -86,7 +86,6 @@ } else { xhr = new this.xhrClass(); } - // This hack is in place due to some platform // bug in gecko when using mozSystem xhr // the credentials only seem to work as expected @@ -101,6 +100,12 @@ )); } + var useMozChunkedText = false; + if (this.globalXhrOptions && this.globalXhrOptions.useMozChunkedText) { + useMozChunkedText = true; + xhr.responseType = 'moz-chunked-text'; + } + for (header in this.headers) { if (Object.hasOwnProperty.call(this.headers, header)) { xhr.setRequestHeader(header, this.headers[header]); @@ -114,13 +119,20 @@ if ('onprogress' in xhr) { hasProgressEvents = true; var last = 0; - xhr.onprogress = function onProgress(event) { - var chunk = xhr.responseText.substr(last, event.loaded); - last = event.loaded; - if (this.ondata) { - this.ondata(chunk); - } - }.bind(this); + + if (useMozChunkedText) { + xhr.onprogress = function onChunkedProgress(event) { + this.ondata(xhr.responseText); + }.bind(this); + } else { + xhr.onprogress = function onProgress(event) { + var chunk = xhr.responseText.substr(last, event.loaded); + last = event.loaded; + if (this.ondata) { + this.ondata(chunk); + } + }.bind(this); + } } xhr.onreadystatechange = function onReadyStateChange() { diff --git a/test/caldav/xhr_test.js b/test/caldav/xhr_test.js index aa9b4f2..6130346 100644 --- a/test/caldav/xhr_test.js +++ b/test/caldav/xhr_test.js @@ -104,7 +104,7 @@ suite('webacls/xhr', function() { }); suite('requests real files', function() { - function request(path) { + function request(path, globalOptions) { path = 'fixtures/' + path; if (typeof(__dirname) !== 'undefined') { @@ -113,7 +113,7 @@ suite('webacls/xhr', function() { path = '/test/caldav/' + path; } - return new Xhr({ url: path }); + return new Xhr({ url: path, globalXhrOptions: globalOptions }); } test('get', function(done) { @@ -125,27 +125,56 @@ suite('webacls/xhr', function() { }); }); - test('.ondata', function(done) { - var subject = request('long.txt'); - var gotData = ''; + suite('.ondata', function() { + var expected; + var file = 'long.txt'; - subject.ondata = function(chunk) { - gotData += chunk; - }; + setup(function(done) { + if (expected) { + done(); + } + + var req = request(file); + req.send(function(err, xhr) { + expected = xhr.responseText; + done(); + }); + }); - subject.send(function(err, xhr) { - var data = xhr.responseText; + if (this.navigator && navigator.userAgent.indexOf('Mozilla') !== -1) { + test('.ondata with chunked', function(done) { + var subject = request('long.txt', { useMozChunkedText: true }); + var gotData = ''; + + subject.ondata = function(chunk) { + gotData += chunk; + }; + + var xhr = subject.send(function(err, xhr) { + assert.ok(!xhr.responseText); + assert.equal(xhr.responseType, 'moz-chunked-text'); + assert.equal(expected, gotData); + done(); + }); + }); + } - assert.equal( - data.trim(), - gotData.trim(), - 'sends ondata' - ); + test('.ondata', function(done) { + var subject = request(file); + var gotData = ''; - done(); + subject.ondata = function(chunk) { + gotData += chunk; + }; + + subject.send(function(err, xhr) { + assert.equal(expected, gotData); + done(); + }); }); - }); + + }); }); }); -- cgit