From 8bac550475b1f7fa7eac93a3c167ad2bf4d1287d Mon Sep 17 00:00:00 2001 From: Wellington Fernando de Macedo Date: Fri, 28 Oct 2011 19:52:27 -0700 Subject: [PATCH] Bug 664179: Allow EventSource to access cross-origin event streams using CORS. r=smaug,sicking --- content/base/public/nsIEventSource.idl | 14 +- content/base/src/nsEventSource.cpp | 53 +++- content/base/src/nsEventSource.h | 1 + content/base/test/Makefile.in | 1 + .../base/test/accesscontrol.resource^headers^ | 3 +- .../base/test/file_restrictedEventSource.sjs | 44 ++++ content/base/test/test_bug338583.html | 243 ++++++++++++++---- 7 files changed, 302 insertions(+), 57 deletions(-) create mode 100644 content/base/test/file_restrictedEventSource.sjs diff --git a/content/base/public/nsIEventSource.idl b/content/base/public/nsIEventSource.idl index c9512c302095..3d77a952f4e6 100644 --- a/content/base/public/nsIEventSource.idl +++ b/content/base/public/nsIEventSource.idl @@ -51,7 +51,7 @@ interface nsIPrincipal; interface nsIScriptContext; interface nsPIDOMWindow; -[scriptable, uuid(755e2d2d-a836-4539-83f4-16b51156341f)] +[scriptable, uuid(83dc8c2b-376e-42b3-8bed-1ad6dea7d6d7)] interface nsIEventSource : nsISupports { readonly attribute DOMString url; @@ -62,6 +62,11 @@ interface nsIEventSource : nsISupports const unsigned short CLOSED = 2; readonly attribute long readyState; + // if true then cross-site Access-Control requests are made using credentials + // such as cookies and authorization headers. Never affects same-site + // requests. + readonly attribute boolean mozWithCredentials; + // event handler attributes attribute nsIDOMEventListener onopen; attribute nsIDOMEventListener onmessage; @@ -83,9 +88,14 @@ interface nsIEventSource : nsISupports * null. * @param ownerWindow The associated window for the request. May be null. * @param url The EventSource's url. This must not be empty. + * @param withCredentials When set to true attempts to make cross-site + * Access-Control requests with credentials such as + * cookies and authorization headers. Never affects + * same-site requests. */ [noscript] void init(in nsIPrincipal principal, in nsIScriptContext scriptContext, in nsPIDOMWindow ownerWindow, - in DOMString url); + in DOMString url, + in boolean withCredentials); }; diff --git a/content/base/src/nsEventSource.cpp b/content/base/src/nsEventSource.cpp index 1c4d8835d66a..265d8533b8a4 100644 --- a/content/base/src/nsEventSource.cpp +++ b/content/base/src/nsEventSource.cpp @@ -62,6 +62,7 @@ #include "nsContentUtils.h" #include "mozilla/Preferences.h" #include "xpcpublic.h" +#include "nsCrossSiteListenerProxy.h" using namespace mozilla; @@ -85,6 +86,7 @@ nsEventSource::nsEventSource() : mFrozen(false), mErrorLoadOnRedirect(false), mGoingToDispatchAllMessages(false), + mWithCredentials(false), mLastConvertionResult(NS_OK), mReadyState(nsIEventSource::CONNECTING), mScriptLine(0), @@ -165,6 +167,14 @@ nsEventSource::GetReadyState(PRInt32 *aReadyState) return NS_OK; } +NS_IMETHODIMP +nsEventSource::GetMozWithCredentials(bool *aWithCredentials) +{ + NS_ENSURE_ARG_POINTER(aWithCredentials); + *aWithCredentials = mWithCredentials; + return NS_OK; +} + #define NS_EVENTSRC_IMPL_DOMEVENTLISTENER(_eventlistenername, _eventlistener) \ NS_IMETHODIMP \ nsEventSource::GetOn##_eventlistenername(nsIDOMEventListener * *aListener) \ @@ -230,7 +240,8 @@ NS_IMETHODIMP nsEventSource::Init(nsIPrincipal* aPrincipal, nsIScriptContext* aScriptContext, nsPIDOMWindow* aOwnerWindow, - const nsAString& aURL) + const nsAString& aURL, + bool aWithCredentials) { NS_ENSURE_ARG(aPrincipal); @@ -240,6 +251,7 @@ nsEventSource::Init(nsIPrincipal* aPrincipal, mPrincipal = aPrincipal; mScriptContext = aScriptContext; + mWithCredentials = aWithCredentials; if (aOwnerWindow) { mOwner = aOwnerWindow->IsOuterWindow() ? aOwnerWindow->GetCurrentInnerWindow() : aOwnerWindow; @@ -376,7 +388,31 @@ nsEventSource::Initialize(nsISupports* aOwner, nsCOMPtr principal = scriptPrincipal->GetPrincipal(); NS_ENSURE_STATE(principal); - return Init(principal, scriptContext, ownerWindow, urlParam); + bool withCredentialsParam = false; + if (aArgc >= 2) { + NS_ENSURE_TRUE(!JSVAL_IS_PRIMITIVE(aArgv[1]), NS_ERROR_INVALID_ARG); + + JSObject *obj = JSVAL_TO_OBJECT(aArgv[1]); + NS_ASSERTION(obj, "obj shouldn't be null!!"); + + JSBool hasProperty = JS_FALSE; + NS_ENSURE_TRUE(JS_HasProperty(aContext, obj, "mozWithCredentials", + &hasProperty), NS_ERROR_FAILURE); + + if (hasProperty) { + jsval withCredentialsVal; + NS_ENSURE_TRUE(JS_GetProperty(aContext, obj, "mozWithCredentials", + &withCredentialsVal), NS_ERROR_FAILURE); + + JSBool withCredentials = JS_FALSE; + NS_ENSURE_TRUE(JS_ValueToBoolean(aContext, withCredentialsVal, + &withCredentials), NS_ERROR_FAILURE); + withCredentialsParam = !!withCredentials; + } + } + + return Init(principal, scriptContext, ownerWindow, + urlParam, withCredentialsParam); } //----------------------------------------------------------------------------- @@ -886,8 +922,13 @@ nsEventSource::InitChannelAndRequestEventSource() rv = SetupHttpChannel(); NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr listener = + new nsCORSListenerProxy(this, mPrincipal, mHttpChannel, + mWithCredentials, &rv); + NS_ENSURE_SUCCESS(rv, rv); + // Start reading from the channel - return mHttpChannel->AsyncOpen(this, nsnull); + return mHttpChannel->AsyncOpen(listener, nsnull); } void @@ -1173,7 +1214,6 @@ nsEventSource::CheckCanRequestSrc(nsIURI* aSrc) return false; } - bool isSameOrigin = false; bool isValidURI = false; bool isValidContentLoadPolicy = false; bool isValidProtocol = false; @@ -1181,8 +1221,6 @@ nsEventSource::CheckCanRequestSrc(nsIURI* aSrc) nsCOMPtr srcToTest = aSrc ? aSrc : mSrc.get(); NS_ENSURE_TRUE(srcToTest, false); - isSameOrigin = NS_SUCCEEDED(mPrincipal->CheckMayLoad(srcToTest, false)); - PRUint32 aCheckURIFlags = nsIScriptSecurityManager::DISALLOW_INHERIT_PRINCIPAL | nsIScriptSecurityManager::DISALLOW_SCRIPT; @@ -1222,8 +1260,7 @@ nsEventSource::CheckCanRequestSrc(nsIURI* aSrc) targetURIScheme.EqualsLiteral("https"); } - return isSameOrigin && isValidURI && isValidContentLoadPolicy && - isValidProtocol; + return isValidURI && isValidContentLoadPolicy && isValidProtocol; } // static diff --git a/content/base/src/nsEventSource.h b/content/base/src/nsEventSource.h index 950986fc22c6..e6bf37b259ad 100644 --- a/content/base/src/nsEventSource.h +++ b/content/base/src/nsEventSource.h @@ -215,6 +215,7 @@ protected: bool mFrozen; bool mErrorLoadOnRedirect; bool mGoingToDispatchAllMessages; + bool mWithCredentials; // used while reading the input streams nsCOMPtr mUnicodeDecoder; diff --git a/content/base/test/Makefile.in b/content/base/test/Makefile.in index ff89a7c17445..6fd0378e8bd4 100644 --- a/content/base/test/Makefile.in +++ b/content/base/test/Makefile.in @@ -521,6 +521,7 @@ _TEST_FILES2 = \ test_bug692434.html \ file_bug692434.xml \ test_bug693875.html \ + file_restrictedEventSource.sjs \ $(NULL) _CHROME_FILES = \ diff --git a/content/base/test/accesscontrol.resource^headers^ b/content/base/test/accesscontrol.resource^headers^ index 4438d4daeae4..75f1f88972b2 100644 --- a/content/base/test/accesscontrol.resource^headers^ +++ b/content/base/test/accesscontrol.resource^headers^ @@ -1,4 +1,5 @@ -Access-Control-Allow-Origin: http://localhost:8888 +Access-Control-Allow-Origin: http://mochi.test:8888 +Access-Control-Allow-Credentials: true Content-Type: text/event-stream Cache-Control: no-cache, must-revalidate diff --git a/content/base/test/file_restrictedEventSource.sjs b/content/base/test/file_restrictedEventSource.sjs new file mode 100644 index 000000000000..1b442765c5dc --- /dev/null +++ b/content/base/test/file_restrictedEventSource.sjs @@ -0,0 +1,44 @@ +function handleRequest(request, response) +{ + if ((request.queryString == "test=user1_xhr" && + request.hasHeader("Authorization") && + request.getHeader("Authorization") == "Basic dXNlciAxOnBhc3N3b3JkIDE=") || + (request.queryString == "test=user1_evtsrc" && + request.hasHeader("Authorization") && + request.getHeader("Authorization") == "Basic dXNlciAxOnBhc3N3b3JkIDE=" && + request.hasHeader("Cookie") && + request.getHeader("Cookie") == "test=5c")) { + response.setStatusLine(null, 200, "OK"); + response.setHeader("Content-Type", "text/event-stream", false); + response.setHeader("Access-Control-Allow-Origin", "http://mochi.test:8888", false); + response.setHeader("Access-Control-Allow-Credentials", "true", false); + response.setHeader("Cache-Control", "no-cache, must-revalidate", false); + if (request.queryString == "test=user1_xhr") { + response.setHeader("Set-Cookie", "test=5c", false); + } + response.write("event: message\ndata: 1\n\n"); + } else if ((request.queryString == "test=user2_xhr" && + request.hasHeader("Authorization") && + request.getHeader("Authorization") == "Basic dXNlciAyOnBhc3N3b3JkIDI=") || + (request.queryString == "test=user2_evtsrc" && + request.hasHeader("Authorization") && + request.getHeader("Authorization") == "Basic dXNlciAyOnBhc3N3b3JkIDI=" && + request.hasHeader("Cookie") && + request.getHeader("Cookie") == "test=5d")) { + response.setStatusLine(null, 200, "OK"); + response.setHeader("Content-Type", "text/event-stream", false); + response.setHeader("Access-Control-Allow-Origin", "http://mochi.test:8888", false); + response.setHeader("Access-Control-Allow-Credentials", "true", false); + response.setHeader("Cache-Control", "no-cache, must-revalidate", false); + if (request.queryString == "test=user2_xhr") { + response.setHeader("Set-Cookie", "test=5d", false); + } + response.write("event: message\ndata: 1\n\n"); + } else { + response.setStatusLine(null, 401, "Unauthorized"); + response.setHeader("WWW-Authenticate", "basic realm=\"restricted\"", false); + response.setHeader("Access-Control-Allow-Origin", "http://mochi.test:8888", false); + response.setHeader("Access-Control-Allow-Credentials", "true", false); + response.write("Unauthorized"); + } +} \ No newline at end of file diff --git a/content/base/test/test_bug338583.html b/content/base/test/test_bug338583.html index 9d16fc485258..8d3cc4d7f229 100644 --- a/content/base/test/test_bug338583.html +++ b/content/base/test/test_bug338583.html @@ -32,24 +32,36 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=338583 // -- + var gTestsHaveFinished = []; + + function setTestHasFinished(test_id) + { + gTestsHaveFinished[test_id] = true; + for (var i=0; i < gTestsHaveFinished.length; ++i) { + if (!gTestsHaveFinished[i]) { + return; + } + } + SimpleTest.finish(); + } + function runAllTests() { - // these tests run asynchronously - doTest1(); // this will take 8000 ms - doTest2(); // this will take 5000 ms - doTest3(); // this will take 1500 ms - doTest3_b(); // this will take 1500 ms - doTest3_c(); // this will take 1500 ms - doTest3_d(); // this will take 1500 ms - doTest3_e(); // this will take 1500 ms - doTest3_f(); // this will take 1500 ms - doTest3_g(); // this will take 1500 ms - doTest3_h(); // this will take 1500 ms - doTest4(); // this will take 3000 ms - doTest4_b(); // this will take 3000 ms - doTest5(); // this will take 3000 ms - doTest5_b(); // this will take 3000 ms - doTest6(); // this will take 2500 ms - doTest7(); // this will take 8000 ms + // these tests run asynchronously, and they will take 8000 ms + var all_tests = [ + doTest1, doTest1_e, doTest2, doTest3, doTest3_b, doTest3_c, doTest3_d, + doTest3_e, doTest3_f, doTest3_g, doTest3_h, doTest4, doTest4_b, + doTest5, doTest5_b, doTest5_c, doTest5_e, doTest6, doTest7 + ]; + for (var test_id=0; test_id < all_tests.length; ++test_id) { + gTestsHaveFinished[test_id] = false; + var fn = all_tests[test_id]; + fn(test_id); + setTimeout(new Function( + "if (!gTestsHaveFinished[" + test_id + "]) { " + + "ok(false, 'Test " + test_id + " took too long'); " + + "setTestHasFinished(" + test_id + "); " + + "}"), 15000); + } } function fn_onmessage(e) { @@ -70,14 +82,16 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=338583 var domBranch; var oldPrefVal; - var gEventSourceObj1 = null; + var gEventSourceObj1 = null, gEventSourceObj1_e; var gEventSourceObj2 = null; var gEventSourceObj3_a = null, gEventSourceObj3_b = null, gEventSourceObj3_c = null, gEventSourceObj3_d = null, gEventSourceObj3_e = null, gEventSourceObj3_f = null, gEventSourceObj3_g = null, gEventSourceObj3_h = null; var gEventSourceObj4_a = null, gEventSourceObj4_b = null; - var gEventSourceObj5_a = null, gEventSourceObj5_b = null; + var gEventSourceObj5_a = null, gEventSourceObj5_b = null, + gEventSourceObj5_c = null, gEventSourceObj5_d = null, + gEventSourceObj5_e = null, gEventSourceObj5_f = null; var gEventSourceObj6 = null; var gEventSourceObj7 = null; var stress_factor; // used in the setTimeouts in order to help @@ -96,16 +110,17 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=338583 // b) let its fn_onmessage, fn_event_listener_message, and fn_other_event_name functions listeners be hit four times each // c) the close method (we expect readyState == CLOSED) // d) the close method (we expect no message events anymore) +// e) if the ctor throws an exception when the second parameter is null - function doTest1() { + function doTest1(test_id) { gEventSourceObj1 = new EventSource("eventsource.resource"); ok(gEventSourceObj1.url == "http://mochi.test:8888/tests/content/base/test/eventsource.resource", "Test 1.a failed."); ok(gEventSourceObj1.readyState == 0 || gEventSourceObj1.readyState == 1, "Test 1.a failed."); - doTest1_b(); + doTest1_b(test_id); } - function doTest1_b() { + function doTest1_b(test_id) { gEventSourceObj1.hits = []; gEventSourceObj1.hits['fn_onmessage'] = 0; gEventSourceObj1.onmessage = fn_onmessage; @@ -119,18 +134,18 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=338583 bhits = hasBeenHitFor1And2(gEventSourceObj1, 4); ok(bhits, "Test 1.b failed."); - doTest1_c(); + doTest1_c(test_id); }, parseInt(6000*stress_factor)); } - function doTest1_c() { + function doTest1_c(test_id) { gEventSourceObj1.close(); ok(gEventSourceObj1.readyState == 2, "Test 1.c failed."); - doTest1_d(); + doTest1_d(test_id); } - function doTest1_d() { + function doTest1_d(test_id) { gEventSourceObj1.hits['fn_onmessage'] = 0; gEventSourceObj1.hits['fn_event_listener_message'] = 0; gEventSourceObj1.hits['fn_other_event_name'] = 0; @@ -139,14 +154,26 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=338583 bhits = hasBeenHitFor1And2(gEventSourceObj1, 1); ok(!bhits, "Test 1.d failed."); gEventSourceObj1.close(); + setTestHasFinished(test_id); }, parseInt(2000*stress_factor)); } + function doTest1_e(test_id) { + try { + gEventSourceObj1_e = new EventSource("eventsource.resource", null); + ok(false, "Test 1.e failed"); + gEventSourceObj1_e.close(); + } catch (e) { + ok(true, "Test 1.e failed"); + } + setTestHasFinished(test_id); + } + // in order to test (2) // a) set a eventsource that give the dom events messages // b) expect trusted events - function doTest2() { + function doTest2(test_id) { var func = function(e) { ok(e.isTrusted, "Test 2 failed"); gEventSourceObj2.close(); @@ -155,8 +182,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=338583 gEventSourceObj2 = new EventSource("eventsource.resource"); gEventSourceObj2.onmessage = func; - setTimeout(function(){ // just to clean... + setTimeout(function() { // just to clean... gEventSourceObj2.close(); + setTestHasFinished(test_id); }, parseInt(5000*stress_factor)); } @@ -170,7 +198,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=338583 // g) eventsource with invalid NCName char in the event field test // h) DNS error - function doTest3() { + function doTest3(test_id) { gEventSourceObj3_a = new EventSource("http://example.org/tests/content/base/test/eventsource.resource"); gEventSourceObj3_a.onmessage = fn_onmessage; @@ -180,10 +208,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=338583 setTimeout(function() { ok(gEventSourceObj3_a.hits['fn_onmessage'] == 0, "Test 3.a failed"); gEventSourceObj3_a.close(); + setTestHasFinished(test_id); }, parseInt(1500*stress_factor)); } - function doTest3_b() { + function doTest3_b(test_id) { var xhr = new XMLHttpRequest; xhr.open("GET", "/dynamic/getMyDirectory.sjs", false); xhr.send(); @@ -198,6 +227,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=338583 setTimeout(function() { ok(gEventSourceObj3_b.hits['fn_onmessage'] == 0, "Test 3.b failed"); gEventSourceObj3_b.close(); + setTestHasFinished(test_id); }, parseInt(1500*stress_factor)); } @@ -207,7 +237,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=338583 "data: 1\n\n"; } - function doTest3_c() { + function doTest3_c(test_id) { gEventSourceObj3_c = new EventSource("javascript: return jsEvtSource()"); gEventSourceObj3_c.onmessage = fn_onmessage; @@ -217,10 +247,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=338583 setTimeout(function() { ok(gEventSourceObj3_c.hits['fn_onmessage'] == 0, "Test 3.c failed"); gEventSourceObj3_c.close(); + setTestHasFinished(test_id); }, parseInt(1500*stress_factor)); } - function doTest3_d() { + function doTest3_d(test_id) { gEventSourceObj3_d = new EventSource("badContentType.eventsource"); gEventSourceObj3_d.onmessage = fn_onmessage; @@ -230,10 +261,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=338583 setTimeout(function() { ok(gEventSourceObj3_d.hits['fn_onmessage'] == 0, "Test 3.d failed"); gEventSourceObj3_d.close(); + setTestHasFinished(test_id); }, parseInt(1500*stress_factor)); } - function doTest3_e() { + function doTest3_e(test_id) { gEventSourceObj3_e = new EventSource("badHTTPResponseCode.eventsource"); gEventSourceObj3_e.onmessage = fn_onmessage; @@ -243,10 +275,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=338583 setTimeout(function() { ok(gEventSourceObj3_e.hits['fn_onmessage'] == 0, "Test 3.e failed"); gEventSourceObj3_e.close(); + setTestHasFinished(test_id); }, parseInt(1500*stress_factor)); } - function doTest3_f() { + function doTest3_f(test_id) { gEventSourceObj3_f = new EventSource("badMessageEvent.eventsource"); gEventSourceObj3_f.onmessage = fn_onmessage; @@ -256,6 +289,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=338583 setTimeout(function() { ok(gEventSourceObj3_f.hits['fn_onmessage'] == 0, "Test 3.f failed"); gEventSourceObj3_f.close(); + setTestHasFinished(test_id); }, parseInt(1500*stress_factor)); } @@ -263,7 +297,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=338583 fnInvalidNCName.hits++; } - function doTest3_g() { + function doTest3_g(test_id) { gEventSourceObj3_g = new EventSource("badEventFieldName.eventsource"); fnInvalidNCName.hits = 0; @@ -272,10 +306,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=338583 setTimeout(function() { ok(fnInvalidNCName.hits != 0, "Test 3.g failed"); gEventSourceObj3_g.close(); + setTestHasFinished(test_id); }, parseInt(1500*stress_factor)); } - function doTest3_h() { + function doTest3_h(test_id) { gEventSourceObj3_h = new EventSource("http://hdfskjghsbg.jtiyoejowe.dafsgbhjab.com"); gEventSourceObj3_h.onmessage = fn_onmessage; @@ -285,6 +320,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=338583 setTimeout(function() { ok(gEventSourceObj3_h.hits['fn_onmessage'] == 0, "Test 3.h failed"); gEventSourceObj3_h.close(); + setTestHasFinished(test_id); }, parseInt(1500*stress_factor)); } @@ -309,7 +345,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=338583 gEventSourceObj4_b.removeEventListener('message', fn_onmessage4_b, true); } - function doTest4() { + function doTest4(test_id) { gEventSourceObj4_a = new EventSource("forRemoval.resource"); gEventSourceObj4_a.lastData = 0; gEventSourceObj4_a.onmessage = fn_onmessage4_a; @@ -317,10 +353,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=338583 setTimeout(function() { ok(gEventSourceObj4_a.lastData == 2, "Test 4.a failed"); gEventSourceObj4_a.close(); + setTestHasFinished(test_id); }, parseInt(3000*stress_factor)); } - function doTest4_b() + function doTest4_b(test_id) { gEventSourceObj4_b = new EventSource("forRemoval.resource"); gEventSourceObj4_b.lastData = 0; @@ -329,14 +366,19 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=338583 setTimeout(function() { ok(gEventSourceObj4_b.lastData == 2, "Test 4.b failed"); gEventSourceObj4_b.close(); + setTestHasFinished(test_id); }, parseInt(3000*stress_factor)); } // in order to test (5) -// a) valid access-control xsite request (but must fail) +// a) valid access-control xsite request // b) invalid access-control xsite request +// c) valid access-control xsite request on a restricted page with credentials +// d) valid access-control xsite request on a restricted page without credentials +// e) valid access-control xsite request on a restricted page when the parameter mozWithCredentials is a getter +// f) valid access-control xsite request on a restricted page when the parameter mozWithCredentials is missing - function doTest5() + function doTest5(test_id) { gEventSourceObj5_a = new EventSource("http://example.org/tests/content/base/test/accesscontrol.resource"); @@ -345,12 +387,13 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=338583 gEventSourceObj5_a.hits['fn_onmessage'] = 0; setTimeout(function() { - ok(gEventSourceObj5_a.hits['fn_onmessage'] == 0, "Test 5.a failed"); + ok(gEventSourceObj5_a.hits['fn_onmessage'] != 0, "Test 5.a failed"); gEventSourceObj5_a.close(); + setTestHasFinished(test_id); }, parseInt(3000*stress_factor)); } - function doTest5_b() + function doTest5_b(test_id) { gEventSourceObj5_b = new EventSource("http://example.org/tests/content/base/test/invalid_accesscontrol.resource"); @@ -361,10 +404,117 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=338583 setTimeout(function() { ok(gEventSourceObj5_b.hits['fn_onmessage'] == 0, "Test 5.b failed"); gEventSourceObj5_b.close(); + setTestHasFinished(test_id); }, parseInt(3000*stress_factor)); } - function doTest6() + function doTest5_c(test_id) + { + // credentials using the auth cache and cookies + var xhr = SpecialPowers.createSystemXHR(); + xhr.withCredentials = true; + // also, test mixed mode UI + xhr.open("GET", "https://example.com/tests/content/base/test/file_restrictedEventSource.sjs?test=user1_xhr", false, "user 1", "password 1"); + xhr.send(); + ok(xhr.status == 200, "Failed to set credentials in test 5.c"); + + gEventSourceObj5_c = new EventSource("https://example.com/tests/content/base/test/file_restrictedEventSource.sjs?test=user1_evtsrc", + { mozWithCredentials: true } ); + ok(gEventSourceObj5_c.mozWithCredentials, "Wrong mozWithCredentials in test 5.c"); + + gEventSourceObj5_c.onmessage = function(e) { + ok(e.origin == "https://example.com", "Wrong Origin in test 5.c"); + fn_onmessage(e); + }; + gEventSourceObj5_c.hits = []; + gEventSourceObj5_c.hits['fn_onmessage'] = 0; + + setTimeout(function() { + ok(gEventSourceObj5_c.hits['fn_onmessage'] > 0, "Test 5.c failed"); + gEventSourceObj5_c.close(); + doTest5_d(test_id); + }, parseInt(3000*stress_factor)); + } + + function doTest5_d(test_id) + { + var xhr = SpecialPowers.createSystemXHR(); + xhr.withCredentials = true; + xhr.open("GET", "https://example.com/tests/content/base/test/file_restrictedEventSource.sjs?test=user2_xhr", false, "user 2", "password 2"); + xhr.send(); + ok(xhr.status == 200, "Failed to set credentials in test 5.d"); + + gEventSourceObj5_d = new EventSource("https://example.com/tests/content/base/test/file_restrictedEventSource.sjs?test=user2_evtsrc"); + ok(!gEventSourceObj5_d.mozWithCredentials, "Wrong mozWithCredentials in test 5.d"); + + gEventSourceObj5_d.onmessage = function(e) { + ok(e.origin == "https://example.com", "Wrong Origin in test 5.d"); + fn_onmessage(e); + }; + gEventSourceObj5_d.hits = []; + gEventSourceObj5_d.hits['fn_onmessage'] = 0; + + setTimeout(function() { + ok(gEventSourceObj5_d.hits['fn_onmessage'] == 0, "Test 5.d failed"); + gEventSourceObj5_d.close(); + setTestHasFinished(test_id); + }, parseInt(3000*stress_factor)); + } + + function doTest5_e(test_id) + { + // credentials using the auth cache and cookies + var xhr = SpecialPowers.createSystemXHR(); + xhr.withCredentials = true; + xhr.open("GET", "http://example.org/tests/content/base/test/file_restrictedEventSource.sjs?test=user1_xhr", false, "user 1", "password 1"); + xhr.send(); + ok(xhr.status == 200, "Failed to set credentials in test 5.e"); + + gEventSourceObj5_e = new EventSource("http://example.org/tests/content/base/test/file_restrictedEventSource.sjs?test=user1_evtsrc", + { get mozWithCredentials() { return true; } } ); + ok(gEventSourceObj5_e.mozWithCredentials, "Wrong mozWithCredentials in test 5.e"); + + gEventSourceObj5_e.onmessage = function(e) { + ok(e.origin == "http://example.org", "Wrong Origin in test 5.e"); + fn_onmessage(e); + }; + gEventSourceObj5_e.hits = []; + gEventSourceObj5_e.hits['fn_onmessage'] = 0; + + setTimeout(function() { + ok(gEventSourceObj5_e.hits['fn_onmessage'] > 0, "Test 5.e failed"); + gEventSourceObj5_e.close(); + doTest5_f(test_id); + }, parseInt(3000*stress_factor)); + } + + function doTest5_f(test_id) + { + var xhr = SpecialPowers.createSystemXHR(); + xhr.withCredentials = true; + xhr.open("GET", "http://example.org/tests/content/base/test/file_restrictedEventSource.sjs?test=user2_xhr", false, "user 2", "password 2"); + xhr.send(); + ok(xhr.status == 200, "Failed to set credentials in test 5.f"); + + gEventSourceObj5_f = new EventSource("http://example.org/tests/content/base/test/file_restrictedEventSource.sjs?test=user2_evtsrc", + { }); + ok(!gEventSourceObj5_f.mozWithCredentials, "Wrong mozWithCredentials in test 5.f"); + + gEventSourceObj5_f.onmessage = function(e) { + ok(e.origin == "http://example.org", "Wrong Origin in test 5.f"); + fn_onmessage(e); + }; + gEventSourceObj5_f.hits = []; + gEventSourceObj5_f.hits['fn_onmessage'] = 0; + + setTimeout(function() { + ok(gEventSourceObj5_f.hits['fn_onmessage'] == 0, "Test 5.f failed"); + gEventSourceObj5_f.close(); + setTestHasFinished(test_id); + }, parseInt(3000*stress_factor)); + } + + function doTest6(test_id) { gEventSourceObj6 = new EventSource("somedatas.resource"); var fn_somedata = function(e) { @@ -387,10 +537,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=338583 setTimeout(function() { gEventSourceObj6.close(); + setTestHasFinished(test_id); }, parseInt(2500*stress_factor)); } - function doTest7() + function doTest7(test_id) { gEventSourceObj7 = new EventSource("delayedServerEvents.sjs"); gEventSourceObj7.msg_received = []; @@ -408,11 +559,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=338583 SpecialPowers.setBoolPref("dom.server-events.enabled", oldPrefVal); document.getElementById('waitSpan').innerHTML = ''; - SimpleTest.finish(); + setTestHasFinished(test_id); }, parseInt(8000*stress_factor)); } - function doTest() + function doTest(test_id) { oldPrefVal = SpecialPowers.getBoolPref("dom.server-events.enabled"); SpecialPowers.setBoolPref("dom.server-events.enabled", true);