Bug 383430 - Add features to XHR for convenience of background requests. Patch by Manish Singh <manish@flock.com> r/sr=sicking, a1.9=shaver

git-svn-id: svn://10.0.0.236/trunk@248158 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
mattwillis%gmail.com
2008-03-19 00:14:44 +00:00
parent 184b34addf
commit 116d0d6c1b
6 changed files with 195 additions and 7 deletions

View File

@@ -90,7 +90,7 @@ interface nsPIDOMWindow;
* you're aware of all the security implications. And then think twice about
* it.
*/
[scriptable, uuid(f3fb86e6-5914-4b47-a1f6-8907e37e1159)]
[scriptable, uuid(acda85ab-d06c-4176-b834-6d129ca97ca3)]
interface nsIXMLHttpRequest : nsISupports
{
/**
@@ -301,6 +301,15 @@ interface nsIXMLHttpRequest : nsISupports
*/
attribute boolean multipart;
/**
* Set to true if this is a background service request. This will
* prevent a load group being associated with the request, and
* suppress any security dialogs from being shown * to the user.
* In the cases where one of those dialogs would be shown, the request
* will simply fail instead.
*/
attribute boolean mozBackgroundRequest;
/**
* Initialize the object for use from C++ code with the principal, script
* context, and owner window that should be used.

View File

@@ -174,6 +174,8 @@ GQI_SRCS = contentbase.gqi
# static lib.
FORCE_STATIC_LIB = 1
EXTRA_COMPONENTS = $(srcdir)/nsBadCertHandler.js
include $(topsrcdir)/config/rules.mk
INCLUDES += \

View File

@@ -0,0 +1,83 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Update Service.
*
* The Initial Developer of the Original Code is Ben Goodger.
* Portions created by the Initial Developer are Copyright (C) 2004
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Darin Fisher <darin@meer.net>
* Daniel Veditz <dveditz@mozilla.com>
* Manish Singh <manish@flock.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
/**
* This component's job is to prevent "bad cert" security dialogs from
* being shown to the user when in XHR backgroundRequest mode. This
* causes the request to simply fail if the certificate is bad.
*/
function BadCertHandler() {
}
BadCertHandler.prototype = {
// Suppress any certificate errors
notifyCertProblem: function(socketInfo, status, targetSite) {
return true;
},
// Suppress any ssl errors
notifySSLError: function(socketInfo, error, targetSite) {
return true;
},
// nsIInterfaceRequestor
getInterface: function(iid) {
return this.QueryInterface(iid);
},
// nsISupports
QueryInterface: XPCOMUtils.generateQI([Ci.nsIBadCertListener2,
Ci.nsISSLErrorListener,
Ci.nsIInterfaceRequestor]),
classDescription: "XMLHttpRequest Bad Cert Handler",
classID: Components.ID("{dbded6ec-edbf-4054-a834-287b82c260f9}"),
contractID: "@mozilla.org/content/xmlhttprequest-bad-cert-handler;1"
};
function NSGetModule(aCompMgr, aFileSpec) {
return XPCOMUtils.generateModule([BadCertHandler]);
}

View File

@@ -119,6 +119,7 @@
#define XML_HTTP_REQUEST_USE_XSITE_AC (1 << 13) // Internal
#define XML_HTTP_REQUEST_NON_GET (1 << 14) // Internal
#define XML_HTTP_REQUEST_GOT_FINAL_STOP (1 << 15) // Internal
#define XML_HTTP_REQUEST_BACKGROUND (1 << 16) // Internal
#define XML_HTTP_REQUEST_LOADSTATES \
(XML_HTTP_REQUEST_UNINITIALIZED | \
@@ -131,6 +132,9 @@
#define ACCESS_CONTROL_CACHE_SIZE 100
#define NS_BADCERTHANDLER_CONTRACTID \
"@mozilla.org/content/xmlhttprequest-bad-cert-handler;1"
// This helper function adds the given load flags to the request's existing
// load flags.
static void AddLoadFlags(nsIRequest *request, nsLoadFlags newFlags)
@@ -141,6 +145,15 @@ static void AddLoadFlags(nsIRequest *request, nsLoadFlags newFlags)
request->SetLoadFlags(flags);
}
static nsresult IsCapabilityEnabled(const char *capability, PRBool *enabled)
{
nsIScriptSecurityManager *secMan = nsContentUtils::GetSecurityManager();
if (!secMan)
return NS_ERROR_FAILURE;
return secMan->IsCapabilityEnabled(capability, enabled);
}
// Helper proxy class to be used when expecting an
// multipart/x-mixed-replace stream of XML documents.
@@ -1224,6 +1237,10 @@ nsXMLHttpRequest::GetLoadGroup(nsILoadGroup **aLoadGroup)
NS_ENSURE_ARG_POINTER(aLoadGroup);
*aLoadGroup = nsnull;
if (mState & XML_HTTP_REQUEST_BACKGROUND) {
return NS_OK;
}
nsCOMPtr<nsIDocument> doc = GetDocumentFromScriptContext(mScriptContext);
if (doc) {
*aLoadGroup = doc->GetDocumentLoadGroup().get(); // already_AddRefed
@@ -2391,13 +2408,8 @@ nsXMLHttpRequest::SetRequestHeader(const nsACString& header,
// Prevent modification to certain HTTP headers (see bug 302263), unless
// the executing script has UniversalBrowserWrite permission.
nsIScriptSecurityManager *secMan = nsContentUtils::GetSecurityManager();
if (!secMan) {
return NS_ERROR_FAILURE;
}
PRBool privileged;
rv = secMan->IsCapabilityEnabled("UniversalBrowserWrite", &privileged);
rv = IsCapabilityEnabled("UniversalBrowserWrite", &privileged);
if (NS_FAILED(rv))
return NS_ERROR_FAILURE;
@@ -2508,6 +2520,41 @@ nsXMLHttpRequest::SetMultipart(PRBool aMultipart)
return NS_OK;
}
/* attribute boolean mozBackgroundRequest; */
NS_IMETHODIMP
nsXMLHttpRequest::GetMozBackgroundRequest(PRBool *_retval)
{
*_retval = !!(mState & XML_HTTP_REQUEST_BACKGROUND);
return NS_OK;
}
/* attribute boolean mozBackgroundRequest; */
NS_IMETHODIMP
nsXMLHttpRequest::SetMozBackgroundRequest(PRBool aMozBackgroundRequest)
{
PRBool privileged;
nsresult rv = IsCapabilityEnabled("UniversalXPConnect", &privileged);
NS_ENSURE_SUCCESS(rv, rv);
if (!privileged)
return NS_ERROR_DOM_SECURITY_ERR;
if (!(mState & XML_HTTP_REQUEST_UNINITIALIZED)) {
// Can't change this while we're in the middle of something.
return NS_ERROR_IN_PROGRESS;
}
if (aMozBackgroundRequest) {
mState |= XML_HTTP_REQUEST_BACKGROUND;
} else {
mState &= ~XML_HTTP_REQUEST_BACKGROUND;
}
return NS_OK;
}
// nsIDOMEventListener
nsresult
@@ -2748,6 +2795,19 @@ nsXMLHttpRequest::GetInterface(const nsIID & aIID, void **aResult)
}
}
if (mState & XML_HTTP_REQUEST_BACKGROUND) {
nsresult rv;
nsCOMPtr<nsIInterfaceRequestor> badCertHandler(do_CreateInstance(NS_BADCERTHANDLER_CONTRACTID, &rv));
// Ignore failure to get component, we may not have all its dependencies
// available
if (NS_SUCCEEDED(rv)) {
rv = badCertHandler->GetInterface(aIID, aResult);
if (NS_SUCCEEDED(rv))
return rv;
}
}
return QueryInterface(aIID, aResult);
}

View File

@@ -120,6 +120,7 @@ _TEST_FILES = test_bug5141.html \
test_bug375314.html \
test_bug378969.html \
test_bug382113.html \
test_bug383430.html \
test_bug390219.html \
test_bug390735.html \
test_bug392318.html \

View File

@@ -0,0 +1,33 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=383430
-->
<head>
<title>Test for Bug 383430</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=383430">Mozilla Bug 383430</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 383430 **/
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var req = new XMLHttpRequest();
req.mozBackgroundRequest = true;
req.open("GET", window.location.href);
req.send(null);
ok(req.channel.loadGroup == null, "loadGroup is null");
</script>
</pre>
</body>
</html>