зеркало из https://github.com/mozilla/gecko-dev.git
Merge inbound to m-c. a=merge
--HG-- rename : toolkit/modules/tests/browser/browser_AddonWatcher.js => toolkit/components/perfmonitoring/tests/browser/browser_AddonWatcher.js
This commit is contained in:
Коммит
86aee22968
6
CLOBBER
6
CLOBBER
|
@ -22,8 +22,4 @@
|
|||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||
# don't change CLOBBER for WebIDL changes any more.
|
||||
|
||||
Bug 1155082: Merge BluetoothUUID.{cpp,h} variants into single file
|
||||
|
||||
This patch set renames and removes source files. This requires updating
|
||||
the build system's dependency information from scratch. The issue has
|
||||
been reported in bug 1154232.
|
||||
Bug 1148639 - libvpx update moved a bunch of files around.
|
||||
|
|
|
@ -287,6 +287,7 @@ skip-if = os == 'win' || e10s # Bug 1056146 - zoom tests use FullZoomHelper and
|
|||
[browser_bug1070778.js]
|
||||
[browser_canonizeURL.js]
|
||||
skip-if = e10s # Bug 1094510 - test hits the network in e10s mode only
|
||||
[browser_clipboard.js]
|
||||
[browser_contentAreaClick.js]
|
||||
[browser_contextSearchTabPosition.js]
|
||||
skip-if = os == "mac" || e10s # bug 967013; e10s: bug 1094761 - test hits the network in e10s, causing next test to crash
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
// This test is used to check copy and paste in editable areas to ensure that non-text
|
||||
// types (html and images) are copied to and pasted from the clipboard properly.
|
||||
|
||||
let testPage = "<div id='main' contenteditable='true'>Test <b>Bold</b> After Text</div>";
|
||||
|
||||
add_task(function*() {
|
||||
let tab = gBrowser.addTab();
|
||||
let browser = gBrowser.getBrowserForTab(tab);
|
||||
|
||||
gBrowser.selectedTab = tab;
|
||||
|
||||
yield promiseTabLoadEvent(tab, "data:text/html," + escape(testPage));
|
||||
yield SimpleTest.promiseFocus(browser.contentWindowAsCPOW);
|
||||
|
||||
let results = yield ContentTask.spawn(browser, {}, function* () {
|
||||
var doc = content.document;
|
||||
var main = doc.getElementById("main");
|
||||
main.focus();
|
||||
|
||||
const utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIDOMWindowUtils);
|
||||
|
||||
const modifier = (content.navigator.platform.indexOf("Mac") >= 0) ?
|
||||
Components.interfaces.nsIDOMWindowUtils.MODIFIER_META :
|
||||
Components.interfaces.nsIDOMWindowUtils.MODIFIER_CONTROL;
|
||||
|
||||
function sendKey(key)
|
||||
{
|
||||
if (utils.sendKeyEvent("keydown", key, 0, modifier)) {
|
||||
utils.sendKeyEvent("keypress", key, key.charCodeAt(0), modifier);
|
||||
}
|
||||
utils.sendKeyEvent("keyup", key, 0, modifier);
|
||||
}
|
||||
|
||||
let results = [];
|
||||
function is(l, r, v) {
|
||||
results.push(((l === r) ? "PASSED" : "FAILED") + " got: " + l + " expected: " + r + " - " + v);
|
||||
}
|
||||
|
||||
// Select an area of the text.
|
||||
let selection = doc.getSelection();
|
||||
selection.modify("move", "left", "line");
|
||||
selection.modify("move", "right", "character");
|
||||
selection.modify("move", "right", "character");
|
||||
selection.modify("move", "right", "character");
|
||||
selection.modify("extend", "right", "word");
|
||||
selection.modify("extend", "right", "word");
|
||||
|
||||
yield new content.Promise((resolve, reject) => {
|
||||
addEventListener("copy", function copyEvent(event) {
|
||||
removeEventListener("copy", copyEvent, true);
|
||||
// The data is empty as the selection is copied during the event default phase.
|
||||
is(event.clipboardData.mozItemCount, 0, "Zero items on clipboard");
|
||||
resolve();
|
||||
}, true)
|
||||
|
||||
sendKey("c");
|
||||
});
|
||||
|
||||
selection.modify("move", "right", "line");
|
||||
|
||||
yield new content.Promise((resolve, reject) => {
|
||||
addEventListener("paste", function copyEvent(event) {
|
||||
removeEventListener("paste", copyEvent, true);
|
||||
let clipboardData = event.clipboardData;
|
||||
is(clipboardData.mozItemCount, 1, "One item on clipboard");
|
||||
is(clipboardData.types.length, 2, "Two types on clipboard");
|
||||
is(clipboardData.types[0], "text/html", "text/html on clipboard");
|
||||
is(clipboardData.types[1], "text/plain", "text/plain on clipboard");
|
||||
is(clipboardData.getData("text/html"), "t <b>Bold</b>", "text/html value");
|
||||
is(clipboardData.getData("text/plain"), "t Bold", "text/plain value");
|
||||
resolve();
|
||||
}, true)
|
||||
sendKey("v");
|
||||
});
|
||||
|
||||
is(main.innerHTML, "Test <b>Bold</b> After Textt <b>Bold</b>", "Copy and paste html");
|
||||
|
||||
selection.modify("extend", "left", "word");
|
||||
selection.modify("extend", "left", "word");
|
||||
selection.modify("extend", "left", "character");
|
||||
|
||||
yield new content.Promise((resolve, reject) => {
|
||||
addEventListener("cut", function copyEvent(event) {
|
||||
removeEventListener("cut", copyEvent, true);
|
||||
event.clipboardData.setData("text/plain", "Some text");
|
||||
event.clipboardData.setData("text/html", "<i>Italic</i> ");
|
||||
selection.deleteFromDocument();
|
||||
event.preventDefault();
|
||||
resolve();
|
||||
}, true)
|
||||
sendKey("x");
|
||||
});
|
||||
|
||||
selection.modify("move", "left", "line");
|
||||
|
||||
yield new content.Promise((resolve, reject) => {
|
||||
addEventListener("paste", function copyEvent(event) {
|
||||
removeEventListener("paste", copyEvent, true);
|
||||
let clipboardData = event.clipboardData;
|
||||
is(clipboardData.mozItemCount, 1, "One item on clipboard 2");
|
||||
is(clipboardData.types.length, 2, "Two types on clipboard 2");
|
||||
is(clipboardData.types[0], "text/html", "text/html on clipboard 2");
|
||||
is(clipboardData.types[1], "text/plain", "text/plain on clipboard 2");
|
||||
is(clipboardData.getData("text/html"), "<i>Italic</i> ", "text/html value 2");
|
||||
is(clipboardData.getData("text/plain"), "Some text", "text/plain value 2");
|
||||
resolve();
|
||||
}, true)
|
||||
sendKey("v");
|
||||
});
|
||||
|
||||
is(main.innerHTML, "<i>Italic</i> Test <b>Bold</b> After<b></b>", "Copy and paste html 2");
|
||||
return results;
|
||||
});
|
||||
|
||||
is(results.length, 15, "Correct number of results");
|
||||
for (var t = 0; t < results.length; t++) {
|
||||
ok(results[t].startsWith("PASSED"), results[t]);
|
||||
}
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
||||
|
|
@ -246,7 +246,7 @@ var gAdvancedPane = {
|
|||
document.getElementById("submitTelemetryBox").disabled = disabled;
|
||||
if (disabled) {
|
||||
// If we disable FHR, untick the telemetry checkbox.
|
||||
document.getElementById("submitTelemetryBox").checked = false;
|
||||
Services.prefs.setBoolPref("toolkit.telemetry.enabled", false);
|
||||
}
|
||||
document.getElementById("telemetryDataDesc").disabled = disabled;
|
||||
#endif
|
||||
|
|
|
@ -275,7 +275,7 @@ var gAdvancedPane = {
|
|||
document.getElementById("submitTelemetryBox").disabled = disabled;
|
||||
if (disabled) {
|
||||
// If we disable FHR, untick the telemetry checkbox.
|
||||
document.getElementById("submitTelemetryBox").checked = false;
|
||||
Services.prefs.setBoolPref("toolkit.telemetry.enabled", false);
|
||||
}
|
||||
document.getElementById("telemetryDataDesc").disabled = disabled;
|
||||
#endif
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const PREF_TELEMETRY_ENABLED = "toolkit.telemetry.enabled";
|
||||
|
||||
function runPaneTest(fn) {
|
||||
open_preferences((win) => {
|
||||
let doc = win.document;
|
||||
|
@ -28,12 +30,16 @@ function testTelemetryState(win, doc) {
|
|||
let telmetryCheckbox = doc.getElementById("submitTelemetryBox");
|
||||
Assert.ok(!telmetryCheckbox.disabled,
|
||||
"Telemetry checkbox must be enabled if FHR is checked.");
|
||||
Assert.ok(Services.prefs.getBoolPref(PREF_TELEMETRY_ENABLED),
|
||||
"Telemetry must be enabled if the checkbox is ticked.");
|
||||
|
||||
// Uncheck the FHR checkbox and make sure that Telemetry checkbox gets disabled.
|
||||
fhrCheckbox.click();
|
||||
|
||||
Assert.ok(telmetryCheckbox.disabled,
|
||||
"Telemetry checkbox must be disabled if FHR is unchecked.");
|
||||
Assert.ok(!Services.prefs.getBoolPref(PREF_TELEMETRY_ENABLED),
|
||||
"Telemetry must be disabled if the checkbox is unticked.");
|
||||
|
||||
win.close();
|
||||
finish();
|
||||
|
@ -41,5 +47,6 @@ function testTelemetryState(win, doc) {
|
|||
|
||||
function resetPreferences() {
|
||||
Services.prefs.clearUserPref("datareporting.healthreport.uploadEnabled");
|
||||
Services.prefs.clearUserPref(PREF_TELEMETRY_ENABLED);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const PREF_TELEMETRY_ENABLED = "toolkit.telemetry.enabled";
|
||||
|
||||
function runPaneTest(fn) {
|
||||
function observer(win, topic, data) {
|
||||
Services.obs.removeObserver(observer, "advanced-pane-loaded");
|
||||
|
@ -40,12 +42,16 @@ function testTelemetryState(win) {
|
|||
let telmetryCheckbox = doc.getElementById("submitTelemetryBox");
|
||||
Assert.ok(!telmetryCheckbox.disabled,
|
||||
"Telemetry checkbox must be enabled if FHR is checked.");
|
||||
Assert.ok(Services.prefs.getBoolPref(PREF_TELEMETRY_ENABLED),
|
||||
"Telemetry must be enabled if the checkbox is ticked.");
|
||||
|
||||
// Uncheck the FHR checkbox and make sure that Telemetry checkbox gets disabled.
|
||||
fhrCheckbox.click();
|
||||
|
||||
Assert.ok(telmetryCheckbox.disabled,
|
||||
"Telemetry checkbox must be disabled if FHR is unchecked.");
|
||||
Assert.ok(!Services.prefs.getBoolPref(PREF_TELEMETRY_ENABLED),
|
||||
"Telemetry must be disabled if the checkbox is unticked.");
|
||||
|
||||
win.close();
|
||||
finish();
|
||||
|
@ -57,5 +63,6 @@ function resetPreferences() {
|
|||
.wrappedJSObject;
|
||||
service.policy._prefs.resetBranch("datareporting.policy.");
|
||||
service.policy.dataSubmissionPolicyBypassNotification = true;
|
||||
Services.prefs.clearUserPref(PREF_TELEMETRY_ENABLED);
|
||||
}
|
||||
|
||||
|
|
|
@ -243,6 +243,7 @@ def check_style():
|
|||
# - "js/src/vm/String.h" -> "vm/String.h"
|
||||
|
||||
mfbt_inclnames = set() # type: set(inclname)
|
||||
mozalloc_inclnames = set() # type: set(inclname)
|
||||
js_names = dict() # type: dict(filename, inclname)
|
||||
|
||||
# Select the appropriate files.
|
||||
|
@ -251,6 +252,10 @@ def check_style():
|
|||
inclname = 'mozilla/' + filename.split('/')[-1]
|
||||
mfbt_inclnames.add(inclname)
|
||||
|
||||
if filename.startswith('memory/mozalloc/') and filename.endswith('.h'):
|
||||
inclname = 'mozilla/' + filename.split('/')[-1]
|
||||
mozalloc_inclnames.add(inclname)
|
||||
|
||||
if filename.startswith('js/public/') and filename.endswith('.h'):
|
||||
inclname = 'js/' + filename[len('js/public/'):]
|
||||
js_names[filename] = inclname
|
||||
|
@ -261,13 +266,13 @@ def check_style():
|
|||
inclname = filename[len('js/src/'):]
|
||||
js_names[filename] = inclname
|
||||
|
||||
all_inclnames = mfbt_inclnames | set(js_names.values())
|
||||
all_inclnames = mfbt_inclnames | mozalloc_inclnames | set(js_names.values())
|
||||
|
||||
edges = dict() # type: dict(inclname, set(inclname))
|
||||
|
||||
# We don't care what's inside the MFBT files, but because they are
|
||||
# #included from JS files we have to add them to the inclusion graph.
|
||||
for inclname in mfbt_inclnames:
|
||||
# We don't care what's inside the MFBT and MOZALLOC files, but because they
|
||||
# are #included from JS files we have to add them to the inclusion graph.
|
||||
for inclname in mfbt_inclnames | mozalloc_inclnames:
|
||||
edges[inclname] = set()
|
||||
|
||||
# Process all the JS files.
|
||||
|
|
38
configure.in
38
configure.in
|
@ -3436,20 +3436,6 @@ AC_CACHE_CHECK(for __attribute__((always_inline)),
|
|||
ac_cv_attribute_always_inline=yes,
|
||||
ac_cv_attribute_always_inline=no)])
|
||||
|
||||
AC_CACHE_CHECK(for __attribute__((malloc)),
|
||||
ac_cv_attribute_malloc,
|
||||
[AC_TRY_COMPILE([void* f(int) __attribute__((malloc));],
|
||||
[],
|
||||
ac_cv_attribute_malloc=yes,
|
||||
ac_cv_attribute_malloc=no)])
|
||||
|
||||
AC_CACHE_CHECK(for __attribute__((warn_unused_result)),
|
||||
ac_cv_attribute_warn_unused,
|
||||
[AC_TRY_COMPILE([int f(void) __attribute__((warn_unused_result));],
|
||||
[],
|
||||
ac_cv_attribute_warn_unused=yes,
|
||||
ac_cv_attribute_warn_unused=no)])
|
||||
|
||||
dnl End of C++ language/feature checks
|
||||
AC_LANG_C
|
||||
|
||||
|
@ -3481,25 +3467,6 @@ if test -n "${CPU_ARCH}" -a -n "${TARGET_COMPILER_ABI}"; then
|
|||
AC_DEFINE_UNQUOTED(TARGET_XPCOM_ABI, ["${TARGET_XPCOM_ABI}"])
|
||||
fi
|
||||
|
||||
dnl Mozilla specific options
|
||||
dnl ========================================================
|
||||
dnl The macros used for command line options
|
||||
dnl are defined in build/autoconf/altoptions.m4.
|
||||
|
||||
dnl If the compiler supports these attributes, define them as
|
||||
dnl convenience macros.
|
||||
if test "$ac_cv_attribute_malloc" = yes ; then
|
||||
AC_DEFINE(NS_ATTR_MALLOC, [__attribute__((malloc))])
|
||||
else
|
||||
AC_DEFINE(NS_ATTR_MALLOC,)
|
||||
fi
|
||||
|
||||
if test "$ac_cv_attribute_warn_unused" = yes ; then
|
||||
AC_DEFINE(NS_WARN_UNUSED_RESULT, [__attribute__((warn_unused_result))])
|
||||
else
|
||||
AC_DEFINE(NS_WARN_UNUSED_RESULT,)
|
||||
fi
|
||||
|
||||
dnl We can't run TRY_COMPILE tests on Windows, so hard-code some
|
||||
dnl features that Windows actually does support.
|
||||
|
||||
|
@ -3510,6 +3477,11 @@ if test -n "$SKIP_COMPILER_CHECKS"; then
|
|||
AC_DEFINE(HAVE_LOCALECONV)
|
||||
fi # SKIP_COMPILER_CHECKS
|
||||
|
||||
dnl Mozilla specific options
|
||||
dnl ========================================================
|
||||
dnl The macros used for command line options
|
||||
dnl are defined in build/autoconf/altoptions.m4.
|
||||
|
||||
dnl ========================================================
|
||||
dnl =
|
||||
dnl = Check for external package dependencies
|
||||
|
|
|
@ -5023,24 +5023,32 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI* aURI,
|
|||
if (errorClass == nsINSSErrorsService::ERROR_CLASS_BAD_CERT) {
|
||||
error.AssignLiteral("nssBadCert");
|
||||
|
||||
// if this is a Strict-Transport-Security host and the cert
|
||||
// is bad, don't allow overrides (STS Spec section 7.3).
|
||||
uint32_t type = nsISiteSecurityService::HEADER_HSTS;
|
||||
// If this is an HTTP Strict Transport Security host or a pinned host
|
||||
// and the certificate is bad, don't allow overrides (RFC 6797 section
|
||||
// 12.1, HPKP draft spec section 2.6).
|
||||
uint32_t flags =
|
||||
mInPrivateBrowsing ? nsISocketProvider::NO_PERMANENT_STORAGE : 0;
|
||||
bool isStsHost = false;
|
||||
bool isPinnedHost = false;
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Default) {
|
||||
nsCOMPtr<nsISiteSecurityService> sss =
|
||||
do_GetService(NS_SSSERVICE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = sss->IsSecureURI(type, aURI, flags, &isStsHost);
|
||||
rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, aURI,
|
||||
flags, &isStsHost);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HPKP, aURI,
|
||||
flags, &isPinnedHost);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else {
|
||||
mozilla::dom::ContentChild* cc =
|
||||
mozilla::dom::ContentChild::GetSingleton();
|
||||
mozilla::ipc::URIParams uri;
|
||||
SerializeURI(aURI, uri);
|
||||
cc->SendIsSecureURI(type, uri, flags, &isStsHost);
|
||||
cc->SendIsSecureURI(nsISiteSecurityService::HEADER_HSTS, uri, flags,
|
||||
&isStsHost);
|
||||
cc->SendIsSecureURI(nsISiteSecurityService::HEADER_HPKP, uri, flags,
|
||||
&isPinnedHost);
|
||||
}
|
||||
|
||||
if (Preferences::GetBool(
|
||||
|
@ -5048,11 +5056,16 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI* aURI,
|
|||
cssClass.AssignLiteral("expertBadCert");
|
||||
}
|
||||
|
||||
// HSTS takes precedence over the expert bad cert pref. We
|
||||
// never want to show the "Add Exception" button for HSTS sites.
|
||||
// HSTS/pinning takes precedence over the expert bad cert pref. We
|
||||
// never want to show the "Add Exception" button for these sites.
|
||||
// In the future we should differentiate between an HSTS host and a
|
||||
// pinned host and display a more informative message to the user.
|
||||
if (isStsHost || isPinnedHost) {
|
||||
cssClass.AssignLiteral("badStsCert");
|
||||
}
|
||||
|
||||
uint32_t bucketId;
|
||||
if (isStsHost) {
|
||||
cssClass.AssignLiteral("badStsCert");
|
||||
// measuring STS separately allows us to measure click through
|
||||
// rates easily
|
||||
bucketId = nsISecurityUITelemetry::WARNING_BAD_CERT_TOP_STS;
|
||||
|
@ -11461,7 +11474,7 @@ nsDocShell::AddState(JS::Handle<JS::Value> aData, const nsAString& aTitle,
|
|||
nsCOMPtr<nsIPrincipal> origPrincipal = origDocument->NodePrincipal();
|
||||
|
||||
scContainer = new nsStructuredCloneContainer();
|
||||
rv = scContainer->InitFromJSVal(aData);
|
||||
rv = scContainer->InitFromJSVal(aData, aCx);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIDocument> newDocument = GetDocument();
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
[DEFAULT]
|
||||
skip-if = e10s
|
||||
|
||||
support-files =
|
||||
file_empty.html
|
||||
|
||||
|
|
|
@ -456,7 +456,7 @@ FragmentOrElement::Children()
|
|||
|
||||
if (!slots->mChildrenList) {
|
||||
slots->mChildrenList = new nsContentList(this, kNameSpaceID_Wildcard,
|
||||
nsGkAtoms::_asterix, nsGkAtoms::_asterix,
|
||||
nsGkAtoms::_asterisk, nsGkAtoms::_asterisk,
|
||||
false);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include "nsAttrAndChildArray.h" // member
|
||||
#include "nsCycleCollectionParticipant.h" // NS_DECL_CYCLE_*
|
||||
#include "nsIContent.h" // base class
|
||||
#include "nsINodeList.h" // base class
|
||||
#include "nsIWeakReference.h" // base class
|
||||
#include "nsNodeUtils.h" // class member nsNodeUtils::CloneNodeImpl
|
||||
#include "nsIHTMLCollection.h"
|
||||
|
@ -38,50 +37,6 @@ class Element;
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class that implements the nsIDOMNodeList interface (a list of children of
|
||||
* the content), by holding a reference to the content and delegating GetLength
|
||||
* and Item to its existing child list.
|
||||
* @see nsIDOMNodeList
|
||||
*/
|
||||
class nsChildContentList final : public nsINodeList
|
||||
{
|
||||
public:
|
||||
explicit nsChildContentList(nsINode* aNode)
|
||||
: mNode(aNode)
|
||||
{
|
||||
}
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(nsChildContentList)
|
||||
|
||||
// nsWrapperCache
|
||||
virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
// nsIDOMNodeList interface
|
||||
NS_DECL_NSIDOMNODELIST
|
||||
|
||||
// nsINodeList interface
|
||||
virtual int32_t IndexOf(nsIContent* aContent) override;
|
||||
virtual nsIContent* Item(uint32_t aIndex) override;
|
||||
|
||||
void DropReference()
|
||||
{
|
||||
mNode = nullptr;
|
||||
}
|
||||
|
||||
virtual nsINode* GetParentObject() override
|
||||
{
|
||||
return mNode;
|
||||
}
|
||||
|
||||
private:
|
||||
~nsChildContentList() {}
|
||||
|
||||
// The node whose children make up the list (weak reference)
|
||||
nsINode* mNode;
|
||||
};
|
||||
|
||||
/**
|
||||
* A class that implements nsIWeakReference
|
||||
*/
|
||||
|
@ -186,8 +141,8 @@ public:
|
|||
virtual bool TextIsOnlyWhitespace() override;
|
||||
virtual bool HasTextForTranslation() override;
|
||||
virtual void AppendTextTo(nsAString& aResult) override;
|
||||
virtual bool AppendTextTo(nsAString& aResult,
|
||||
const mozilla::fallible_t&) override NS_WARN_UNUSED_RESULT;
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
virtual bool AppendTextTo(nsAString& aResult, const mozilla::fallible_t&) override;
|
||||
virtual nsIContent *GetBindingParent() const override;
|
||||
virtual nsXBLBinding *GetXBLBinding() const override;
|
||||
virtual void SetXBLBinding(nsXBLBinding* aBinding,
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<body><body>
|
||||
<script>
|
||||
s = document.createElement('script');
|
||||
s.src="";
|
||||
document.body.appendChild(s);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -200,3 +200,5 @@ pref(dom.webcomponents.enabled,true) load 1029710.html
|
|||
HTTP(..) load xhr_abortinprogress.html
|
||||
load xhr_empty_datauri.html
|
||||
load xhr_html_nullresponse.html
|
||||
load structured_clone_container_throws.html
|
||||
load 1154598.xhtml
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<iframe></iframe>
|
||||
<script>
|
||||
try { frames[0].history.pushState({ dummy: function() {} }, ''); }
|
||||
catch (e) {}
|
||||
var doc = frames[0].document;
|
||||
var s = doc.createElement("script");
|
||||
s.textContent = "1";
|
||||
doc.body.appendChild(s);
|
||||
</script>
|
|
@ -417,6 +417,7 @@ LOCAL_INCLUDES += [
|
|||
'/dom/xml',
|
||||
'/dom/xslt/xpath',
|
||||
'/dom/xul',
|
||||
'/gfx/2d',
|
||||
'/image/src',
|
||||
'/js/xpconnect/src',
|
||||
'/js/xpconnect/wrappers',
|
||||
|
|
|
@ -404,8 +404,8 @@ nsContentList::nsContentList(nsINode* aRootNode,
|
|||
mFuncMayDependOnAttr(false)
|
||||
{
|
||||
NS_ASSERTION(mRootNode, "Must have root");
|
||||
if (nsGkAtoms::_asterix == mHTMLMatchAtom) {
|
||||
NS_ASSERTION(mXMLMatchAtom == nsGkAtoms::_asterix, "HTML atom and XML atom are not both asterix?");
|
||||
if (nsGkAtoms::_asterisk == mHTMLMatchAtom) {
|
||||
NS_ASSERTION(mXMLMatchAtom == nsGkAtoms::_asterisk, "HTML atom and XML atom are not both asterisk?");
|
||||
mMatchAll = true;
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -171,6 +171,7 @@
|
|||
#include "nsReferencedElement.h"
|
||||
#include "nsSandboxFlags.h"
|
||||
#include "nsScriptSecurityManager.h"
|
||||
#include "nsStreamUtils.h"
|
||||
#include "nsSVGFeatures.h"
|
||||
#include "nsTextEditorState.h"
|
||||
#include "nsTextFragment.h"
|
||||
|
@ -7219,7 +7220,6 @@ nsContentUtils::TransferablesToIPCTransferables(nsISupportsArray* aTransferables
|
|||
mozilla::dom::nsIContentParent* aParent)
|
||||
{
|
||||
aIPC.Clear();
|
||||
MOZ_ASSERT((aChild && !aParent) || (!aChild && aParent));
|
||||
if (aTransferables) {
|
||||
uint32_t transferableCount = 0;
|
||||
aTransferables->Count(&transferableCount);
|
||||
|
@ -7227,75 +7227,135 @@ nsContentUtils::TransferablesToIPCTransferables(nsISupportsArray* aTransferables
|
|||
IPCDataTransfer* dt = aIPC.AppendElement();
|
||||
nsCOMPtr<nsISupports> genericItem;
|
||||
aTransferables->GetElementAt(i, getter_AddRefs(genericItem));
|
||||
nsCOMPtr<nsITransferable> item(do_QueryInterface(genericItem));
|
||||
if (item) {
|
||||
nsCOMPtr<nsISupportsArray> flavorList;
|
||||
item->FlavorsTransferableCanExport(getter_AddRefs(flavorList));
|
||||
if (flavorList) {
|
||||
uint32_t flavorCount = 0;
|
||||
flavorList->Count(&flavorCount);
|
||||
for (uint32_t j = 0; j < flavorCount; ++j) {
|
||||
nsCOMPtr<nsISupportsCString> flavor = do_QueryElementAt(flavorList, j);
|
||||
if (!flavor) {
|
||||
continue;
|
||||
nsCOMPtr<nsITransferable> transferable(do_QueryInterface(genericItem));
|
||||
TransferableToIPCTransferable(transferable, dt, aChild, aParent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsContentUtils::TransferableToIPCTransferable(nsITransferable* aTransferable,
|
||||
IPCDataTransfer* aIPCDataTransfer,
|
||||
mozilla::dom::nsIContentChild* aChild,
|
||||
mozilla::dom::nsIContentParent* aParent)
|
||||
{
|
||||
MOZ_ASSERT((aChild && !aParent) || (!aChild && aParent));
|
||||
|
||||
if (aTransferable) {
|
||||
nsCOMPtr<nsISupportsArray> flavorList;
|
||||
aTransferable->FlavorsTransferableCanExport(getter_AddRefs(flavorList));
|
||||
if (flavorList) {
|
||||
uint32_t flavorCount = 0;
|
||||
flavorList->Count(&flavorCount);
|
||||
for (uint32_t j = 0; j < flavorCount; ++j) {
|
||||
nsCOMPtr<nsISupportsCString> flavor = do_QueryElementAt(flavorList, j);
|
||||
if (!flavor) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsAutoCString flavorStr;
|
||||
flavor->GetData(flavorStr);
|
||||
if (!flavorStr.Length()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupports> data;
|
||||
uint32_t dataLen = 0;
|
||||
aTransferable->GetTransferData(flavorStr.get(), getter_AddRefs(data), &dataLen);
|
||||
|
||||
nsCOMPtr<nsISupportsString> text = do_QueryInterface(data);
|
||||
nsCOMPtr<nsISupportsCString> ctext = do_QueryInterface(data);
|
||||
if (text) {
|
||||
nsAutoString dataAsString;
|
||||
text->GetData(dataAsString);
|
||||
IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement();
|
||||
item->flavor() = nsCString(flavorStr);
|
||||
item->data() = nsString(dataAsString);
|
||||
} else if (ctext) {
|
||||
nsAutoCString dataAsString;
|
||||
ctext->GetData(dataAsString);
|
||||
IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement();
|
||||
item->flavor() = nsCString(flavorStr);
|
||||
item->data() = nsCString(dataAsString);
|
||||
} else {
|
||||
nsCOMPtr<nsISupportsInterfacePointer> sip =
|
||||
do_QueryInterface(data);
|
||||
if (sip) {
|
||||
sip->GetData(getter_AddRefs(data));
|
||||
}
|
||||
|
||||
// Images to be pasted on the clipboard are nsIInputStreams
|
||||
nsCOMPtr<nsIInputStream> stream(do_QueryInterface(data));
|
||||
if (stream) {
|
||||
IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement();
|
||||
item->flavor() = nsCString(flavorStr);
|
||||
|
||||
nsCString imageData;
|
||||
NS_ConsumeStream(stream, UINT32_MAX, imageData);
|
||||
item->data() = imageData;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Images to be placed on the clipboard are imgIContainers.
|
||||
nsCOMPtr<imgIContainer> image(do_QueryInterface(data));
|
||||
if (image) {
|
||||
RefPtr<mozilla::gfx::SourceSurface> surface =
|
||||
image->GetFrame(imgIContainer::FRAME_CURRENT,
|
||||
imgIContainer::FLAG_SYNC_DECODE);
|
||||
|
||||
mozilla::RefPtr<mozilla::gfx::DataSourceSurface> dataSurface =
|
||||
surface->GetDataSurface();
|
||||
size_t length;
|
||||
int32_t stride;
|
||||
mozilla::UniquePtr<char[]> surfaceData =
|
||||
nsContentUtils::GetSurfaceData(dataSurface, &length, &stride);
|
||||
|
||||
IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement();
|
||||
item->flavor() = nsCString(flavorStr);
|
||||
item->data() = nsCString(surfaceData.get(), length);
|
||||
|
||||
IPCDataTransferImage& imageDetails = item->imageDetails();
|
||||
mozilla::gfx::IntSize size = dataSurface->GetSize();
|
||||
imageDetails.width() = size.width;
|
||||
imageDetails.height() = size.height;
|
||||
imageDetails.stride() = stride;
|
||||
imageDetails.format() = static_cast<uint8_t>(dataSurface->GetFormat());
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Otherwise, handle this as a file.
|
||||
nsCOMPtr<FileImpl> fileImpl;
|
||||
nsCOMPtr<nsIFile> file = do_QueryInterface(data);
|
||||
if (file) {
|
||||
fileImpl = new FileImplFile(file, false);
|
||||
ErrorResult rv;
|
||||
fileImpl->GetSize(rv);
|
||||
fileImpl->GetLastModified(rv);
|
||||
} else {
|
||||
fileImpl = do_QueryInterface(data);
|
||||
}
|
||||
if (fileImpl) {
|
||||
IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement();
|
||||
item->flavor() = nsCString(flavorStr);
|
||||
if (aChild) {
|
||||
item->data() =
|
||||
mozilla::dom::BlobChild::GetOrCreate(aChild,
|
||||
static_cast<FileImpl*>(fileImpl.get()));
|
||||
} else if (aParent) {
|
||||
item->data() =
|
||||
mozilla::dom::BlobParent::GetOrCreate(aParent,
|
||||
static_cast<FileImpl*>(fileImpl.get()));
|
||||
}
|
||||
|
||||
nsAutoCString flavorStr;
|
||||
flavor->GetData(flavorStr);
|
||||
if (!flavorStr.Length()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupports> data;
|
||||
uint32_t dataLen = 0;
|
||||
item->GetTransferData(flavorStr.get(), getter_AddRefs(data), &dataLen);
|
||||
|
||||
nsCOMPtr<nsISupportsString> text = do_QueryInterface(data);
|
||||
if (text) {
|
||||
nsAutoString dataAsString;
|
||||
text->GetData(dataAsString);
|
||||
IPCDataTransferItem* item = dt->items().AppendElement();
|
||||
} else {
|
||||
// This is a hack to support kFilePromiseMime.
|
||||
// On Windows there just needs to be an entry for it,
|
||||
// and for OSX we need to create
|
||||
// nsContentAreaDragDropDataProvider as nsIFlavorDataProvider.
|
||||
if (flavorStr.EqualsLiteral(kFilePromiseMime)) {
|
||||
IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement();
|
||||
item->flavor() = nsCString(flavorStr);
|
||||
item->data() = nsString(dataAsString);
|
||||
} else {
|
||||
nsCOMPtr<nsISupportsInterfacePointer> sip =
|
||||
do_QueryInterface(data);
|
||||
if (sip) {
|
||||
sip->GetData(getter_AddRefs(data));
|
||||
}
|
||||
nsCOMPtr<FileImpl> fileImpl;
|
||||
nsCOMPtr<nsIFile> file = do_QueryInterface(data);
|
||||
if (file) {
|
||||
fileImpl = new FileImplFile(file, false);
|
||||
ErrorResult rv;
|
||||
fileImpl->GetSize(rv);
|
||||
fileImpl->GetLastModified(rv);
|
||||
} else {
|
||||
fileImpl = do_QueryInterface(data);
|
||||
}
|
||||
if (fileImpl) {
|
||||
IPCDataTransferItem* item = dt->items().AppendElement();
|
||||
item->flavor() = nsCString(flavorStr);
|
||||
if (aChild) {
|
||||
item->data() =
|
||||
mozilla::dom::BlobChild::GetOrCreate(aChild,
|
||||
static_cast<FileImpl*>(fileImpl.get()));
|
||||
} else if (aParent) {
|
||||
item->data() =
|
||||
mozilla::dom::BlobParent::GetOrCreate(aParent,
|
||||
static_cast<FileImpl*>(fileImpl.get()));
|
||||
}
|
||||
} else {
|
||||
// This is a hack to support kFilePromiseMime.
|
||||
// On Windows there just needs to be an entry for it,
|
||||
// and for OSX we need to create
|
||||
// nsContentAreaDragDropDataProvider as nsIFlavorDataProvider.
|
||||
if (flavorStr.EqualsLiteral(kFilePromiseMime)) {
|
||||
IPCDataTransferItem* item = dt->items().AppendElement();
|
||||
item->flavor() = nsCString(flavorStr);
|
||||
item->data() = NS_ConvertUTF8toUTF16(flavorStr);
|
||||
}
|
||||
}
|
||||
item->data() = NS_ConvertUTF8toUTF16(flavorStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7303,3 +7363,31 @@ nsContentUtils::TransferablesToIPCTransferables(nsISupportsArray* aTransferables
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
mozilla::UniquePtr<char[]>
|
||||
nsContentUtils::GetSurfaceData(mozilla::gfx::DataSourceSurface* aSurface,
|
||||
size_t* aLength, int32_t* aStride)
|
||||
{
|
||||
mozilla::gfx::DataSourceSurface::MappedSurface map;
|
||||
aSurface->Map(mozilla::gfx::DataSourceSurface::MapType::READ, &map);
|
||||
mozilla::gfx::IntSize size = aSurface->GetSize();
|
||||
mozilla::CheckedInt32 requiredBytes =
|
||||
mozilla::CheckedInt32(map.mStride) * mozilla::CheckedInt32(size.height);
|
||||
size_t maxBufLen = requiredBytes.isValid() ? requiredBytes.value() : 0;
|
||||
mozilla::gfx::SurfaceFormat format = aSurface->GetFormat();
|
||||
|
||||
// Surface data handling is totally nuts. This is the magic one needs to
|
||||
// know to access the data.
|
||||
size_t bufLen = maxBufLen - map.mStride + (size.width * BytesPerPixel(format));
|
||||
|
||||
// nsDependentCString wants null-terminated string.
|
||||
mozilla::UniquePtr<char[]> surfaceData(new char[maxBufLen + 1]);
|
||||
memcpy(surfaceData.get(), reinterpret_cast<char*>(map.mData), bufLen);
|
||||
memset(surfaceData.get() + bufLen, 0, maxBufLen - bufLen + 1);
|
||||
|
||||
*aLength = maxBufLen;
|
||||
*aStride = map.mStride;
|
||||
|
||||
aSurface->Unmap();
|
||||
return surfaceData;
|
||||
}
|
||||
|
|
|
@ -103,6 +103,7 @@ class nsTextFragment;
|
|||
class nsViewportInfo;
|
||||
class nsWrapperCache;
|
||||
class nsAttrValue;
|
||||
class nsITransferable;
|
||||
|
||||
struct JSPropertyDescriptor;
|
||||
struct JSRuntime;
|
||||
|
@ -129,6 +130,10 @@ class Selection;
|
|||
class TabParent;
|
||||
} // namespace dom
|
||||
|
||||
namespace gfx {
|
||||
class DataSourceSurface;
|
||||
} // namespace gfx
|
||||
|
||||
namespace layers {
|
||||
class LayerManager;
|
||||
} // namespace layers
|
||||
|
@ -1277,8 +1282,9 @@ public:
|
|||
* @param aResult the result. Out param.
|
||||
* @return false on out of memory errors, true otherwise.
|
||||
*/
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
static bool GetNodeTextContent(nsINode* aNode, bool aDeep,
|
||||
nsAString& aResult) NS_WARN_UNUSED_RESULT;
|
||||
nsAString& aResult);
|
||||
|
||||
/**
|
||||
* Same as GetNodeTextContents but appends the result rather than sets it.
|
||||
|
@ -1753,8 +1759,9 @@ public:
|
|||
* @param aString the string to convert the newlines inside [in/out]
|
||||
*/
|
||||
static void PlatformToDOMLineBreaks(nsString &aString);
|
||||
static NS_WARN_UNUSED_RESULT bool PlatformToDOMLineBreaks(nsString &aString,
|
||||
const mozilla::fallible_t&);
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
static bool PlatformToDOMLineBreaks(nsString &aString,
|
||||
const mozilla::fallible_t&);
|
||||
|
||||
/**
|
||||
* Populates aResultString with the contents of the string-buffer aBuf, up
|
||||
|
@ -2296,6 +2303,19 @@ public:
|
|||
nsTArray<mozilla::dom::IPCDataTransfer>& aIPC,
|
||||
mozilla::dom::nsIContentChild* aChild,
|
||||
mozilla::dom::nsIContentParent* aParent);
|
||||
|
||||
static void TransferableToIPCTransferable(nsITransferable* aTransferable,
|
||||
mozilla::dom::IPCDataTransfer* aIPCDataTransfer,
|
||||
mozilla::dom::nsIContentChild* aChild,
|
||||
mozilla::dom::nsIContentParent* aParent);
|
||||
|
||||
/*
|
||||
* Get the pixel data from the given source surface and return it as a buffer.
|
||||
* The length and stride will be assigned from the surface.
|
||||
*/
|
||||
static mozilla::UniquePtr<char[]> GetSurfaceData(mozilla::gfx::DataSourceSurface* aSurface,
|
||||
size_t* aLength, int32_t* aStride);
|
||||
|
||||
private:
|
||||
static bool InitializeEventTable();
|
||||
|
||||
|
|
|
@ -34,10 +34,10 @@ public:
|
|||
int32_t mNamespaceID;
|
||||
|
||||
/**
|
||||
* The atom for attribute, weak ref. is fine as we only use it for the
|
||||
* hashcode, we never dereference it.
|
||||
* The atom for attribute, stored as void*, to make sure that we only use it
|
||||
* for the hashcode, and we can never dereference it.
|
||||
*/
|
||||
nsIAtom* mLocalName;
|
||||
void* mLocalName;
|
||||
|
||||
nsAttrKey(int32_t aNs, nsIAtom* aName)
|
||||
: mNamespaceID(aNs), mLocalName(aName) {}
|
||||
|
|
|
@ -10831,8 +10831,8 @@ nsIDocument::Children()
|
|||
{
|
||||
if (!mChildrenCollection) {
|
||||
mChildrenCollection = new nsContentList(this, kNameSpaceID_Wildcard,
|
||||
nsGkAtoms::_asterix,
|
||||
nsGkAtoms::_asterix,
|
||||
nsGkAtoms::_asterisk,
|
||||
nsGkAtoms::_asterisk,
|
||||
false);
|
||||
}
|
||||
|
||||
|
|
|
@ -142,8 +142,9 @@ public:
|
|||
virtual bool TextIsOnlyWhitespace() override;
|
||||
virtual bool HasTextForTranslation() override;
|
||||
virtual void AppendTextTo(nsAString& aResult) override;
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
virtual bool AppendTextTo(nsAString& aResult,
|
||||
const mozilla::fallible_t&) override NS_WARN_UNUSED_RESULT;
|
||||
const mozilla::fallible_t&) override;
|
||||
virtual void DestroyContent() override;
|
||||
virtual void SaveSubtreeState() override;
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ GK_ATOM(_moz_original_size, "_moz_original_size")
|
|||
GK_ATOM(_moz_target, "_moz_target")
|
||||
GK_ATOM(menuactive, "_moz-menuactive")
|
||||
GK_ATOM(_poundDefault, "#default")
|
||||
GK_ATOM(_asterix, "*")
|
||||
GK_ATOM(_asterisk, "*")
|
||||
GK_ATOM(a, "a")
|
||||
GK_ATOM(abbr, "abbr")
|
||||
GK_ATOM(abort, "abort")
|
||||
|
|
|
@ -36,7 +36,7 @@ class nsHTMLContentSerializer final : public nsXHTMLContentSerializer {
|
|||
nsAString& aStr) override;
|
||||
protected:
|
||||
|
||||
NS_WARN_UNUSED_RESULT
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
virtual bool SerializeHTMLAttributes(nsIContent* aContent,
|
||||
nsIContent *aOriginalElement,
|
||||
nsAString& aTagPrefix,
|
||||
|
@ -45,7 +45,7 @@ class nsHTMLContentSerializer final : public nsXHTMLContentSerializer {
|
|||
int32_t aNamespace,
|
||||
nsAString& aStr);
|
||||
|
||||
NS_WARN_UNUSED_RESULT
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
virtual bool AppendAndTranslateEntities(const nsAString& aStr,
|
||||
nsAString& aOutputStr) override;
|
||||
|
||||
|
|
|
@ -545,8 +545,8 @@ public:
|
|||
* Append the text content to aResult.
|
||||
* NOTE: This asserts and returns for elements
|
||||
*/
|
||||
virtual bool AppendTextTo(nsAString& aResult,
|
||||
const mozilla::fallible_t&) NS_WARN_UNUSED_RESULT = 0;
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
virtual bool AppendTextTo(nsAString& aResult, const mozilla::fallible_t&) = 0;
|
||||
|
||||
/**
|
||||
* Check if this content is focusable and in the current tab order.
|
||||
|
|
|
@ -113,7 +113,6 @@ nsINode::nsSlots::~nsSlots()
|
|||
{
|
||||
if (mChildNodes) {
|
||||
mChildNodes->DropReference();
|
||||
NS_RELEASE(mChildNodes);
|
||||
}
|
||||
|
||||
if (mWeakReference) {
|
||||
|
@ -133,7 +132,6 @@ nsINode::nsSlots::Unlink()
|
|||
{
|
||||
if (mChildNodes) {
|
||||
mChildNodes->DropReference();
|
||||
NS_RELEASE(mChildNodes);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -371,9 +369,6 @@ nsINode::ChildNodes()
|
|||
nsSlots* slots = Slots();
|
||||
if (!slots->mChildNodes) {
|
||||
slots->mChildNodes = new nsChildContentList(this);
|
||||
if (slots->mChildNodes) {
|
||||
NS_ADDREF(slots->mChildNodes);
|
||||
}
|
||||
}
|
||||
|
||||
return slots->mChildNodes;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "nsGkAtoms.h" // for nsGkAtoms::baseURIProperty
|
||||
#include "nsIDOMNode.h"
|
||||
#include "mozilla/dom/NodeInfo.h" // member (in nsCOMPtr)
|
||||
#include "nsINodeList.h" // base class
|
||||
#include "nsIVariant.h" // for use in GetUserData()
|
||||
#include "nsNodeInfoManager.h" // for use in NodePrincipal()
|
||||
#include "nsPropertyTable.h" // for typedefs
|
||||
|
@ -41,7 +42,7 @@ class nsIDOMNodeList;
|
|||
class nsIEditor;
|
||||
class nsIFrame;
|
||||
class nsIMutationObserver;
|
||||
class nsINodeList;
|
||||
class nsINode;
|
||||
class nsIPresShell;
|
||||
class nsIPrincipal;
|
||||
class nsIURI;
|
||||
|
@ -234,6 +235,50 @@ private:
|
|||
static uint64_t sGeneration;
|
||||
};
|
||||
|
||||
/**
|
||||
* Class that implements the nsIDOMNodeList interface (a list of children of
|
||||
* the content), by holding a reference to the content and delegating GetLength
|
||||
* and Item to its existing child list.
|
||||
* @see nsIDOMNodeList
|
||||
*/
|
||||
class nsChildContentList final : public nsINodeList
|
||||
{
|
||||
public:
|
||||
explicit nsChildContentList(nsINode* aNode)
|
||||
: mNode(aNode)
|
||||
{
|
||||
}
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(nsChildContentList)
|
||||
|
||||
// nsWrapperCache
|
||||
virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
// nsIDOMNodeList interface
|
||||
NS_DECL_NSIDOMNODELIST
|
||||
|
||||
// nsINodeList interface
|
||||
virtual int32_t IndexOf(nsIContent* aContent) override;
|
||||
virtual nsIContent* Item(uint32_t aIndex) override;
|
||||
|
||||
void DropReference()
|
||||
{
|
||||
mNode = nullptr;
|
||||
}
|
||||
|
||||
virtual nsINode* GetParentObject() override
|
||||
{
|
||||
return mNode;
|
||||
}
|
||||
|
||||
private:
|
||||
~nsChildContentList() {}
|
||||
|
||||
// The node whose children make up the list (weak reference)
|
||||
nsINode* mNode;
|
||||
};
|
||||
|
||||
// This should be used for any nsINode sub-class that has fields of its own
|
||||
// that it needs to measure; any sub-class that doesn't use it will inherit
|
||||
// SizeOfExcludingThis from its super-class. SizeOfIncludingThis() need not be
|
||||
|
@ -1021,8 +1066,7 @@ public:
|
|||
{
|
||||
public:
|
||||
nsSlots()
|
||||
: mChildNodes(nullptr),
|
||||
mWeakReference(nullptr)
|
||||
: mWeakReference(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1042,15 +1086,14 @@ public:
|
|||
* An object implementing nsIDOMNodeList for this content (childNodes)
|
||||
* @see nsIDOMNodeList
|
||||
* @see nsGenericHTMLElement::GetChildNodes
|
||||
*
|
||||
* MSVC 7 doesn't like this as an nsRefPtr
|
||||
*/
|
||||
nsChildContentList* mChildNodes;
|
||||
nsRefPtr<nsChildContentList> mChildNodes;
|
||||
|
||||
/**
|
||||
* Weak reference to this node
|
||||
* Weak reference to this node. This is cleared by the destructor of
|
||||
* nsNodeWeakReference.
|
||||
*/
|
||||
nsNodeWeakReference* mWeakReference;
|
||||
nsNodeWeakReference* MOZ_NON_OWNING_REF mWeakReference;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,13 +8,15 @@
|
|||
|
||||
#include "nsIDOMNodeList.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "nsIContent.h"
|
||||
|
||||
// IID for the nsINodeList interface
|
||||
#define NS_INODELIST_IID \
|
||||
{ 0xadb5e54c, 0x6e96, 0x4102, \
|
||||
{ 0x8d, 0x40, 0xe0, 0x12, 0x3d, 0xcf, 0x48, 0x7a } }
|
||||
|
||||
class nsIContent;
|
||||
class nsINode;
|
||||
|
||||
/**
|
||||
* An internal interface for a reasonably fast indexOf.
|
||||
*/
|
||||
|
|
|
@ -129,13 +129,13 @@ private:
|
|||
void *arg);
|
||||
|
||||
PLHashTable *mNodeInfoHash;
|
||||
nsIDocument *mDocument; // WEAK
|
||||
nsIDocument * MOZ_NON_OWNING_REF mDocument; // WEAK
|
||||
uint32_t mNonDocumentNodeInfos;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal; // Never null after Init() succeeds.
|
||||
nsCOMPtr<nsIPrincipal> mDefaultPrincipal; // Never null after Init() succeeds
|
||||
mozilla::dom::NodeInfo *mTextNodeInfo; // WEAK to avoid circular ownership
|
||||
mozilla::dom::NodeInfo *mCommentNodeInfo; // WEAK to avoid circular ownership
|
||||
mozilla::dom::NodeInfo *mDocumentNodeInfo; // WEAK to avoid circular ownership
|
||||
mozilla::dom::NodeInfo * MOZ_NON_OWNING_REF mTextNodeInfo; // WEAK to avoid circular ownership
|
||||
mozilla::dom::NodeInfo * MOZ_NON_OWNING_REF mCommentNodeInfo; // WEAK to avoid circular ownership
|
||||
mozilla::dom::NodeInfo * MOZ_NON_OWNING_REF mDocumentNodeInfo; // WEAK to avoid circular ownership
|
||||
nsRefPtr<nsBindingManager> mBindingManager;
|
||||
};
|
||||
|
||||
|
|
|
@ -76,6 +76,7 @@ nsScriptLoadRequestList::Clear()
|
|||
{
|
||||
while (!isEmpty()) {
|
||||
nsRefPtr<nsScriptLoadRequest> first = StealFirst();
|
||||
first->Cancel();
|
||||
// And just let it go out of scope and die.
|
||||
}
|
||||
}
|
||||
|
@ -1486,6 +1487,10 @@ nsScriptLoader::PrepareLoadedRequest(nsScriptLoadRequest* aRequest,
|
|||
return aStatus;
|
||||
}
|
||||
|
||||
if (aRequest->IsCanceled()) {
|
||||
return NS_BINDING_ABORTED;
|
||||
}
|
||||
|
||||
// If we don't have a document, then we need to abort further
|
||||
// evaluation.
|
||||
if (!mDocument) {
|
||||
|
@ -1556,10 +1561,15 @@ nsScriptLoader::PrepareLoadedRequest(nsScriptLoadRequest* aRequest,
|
|||
// Mark this as loaded
|
||||
aRequest->mLoading = false;
|
||||
|
||||
// And if it's async, move it to the loaded list.
|
||||
// And if it's async, move it to the loaded list. aRequest->mIsAsync really
|
||||
// _should_ be in a list, but the consequences if it's not are bad enough we
|
||||
// want to avoid trying to move it if it's not.
|
||||
if (aRequest->mIsAsync) {
|
||||
nsRefPtr<nsScriptLoadRequest> req = mLoadingAsyncRequests.Steal(aRequest);
|
||||
mLoadedAsyncRequests.AppendElement(req);
|
||||
MOZ_ASSERT(aRequest->isInList());
|
||||
if (aRequest->isInList()) {
|
||||
nsRefPtr<nsScriptLoadRequest> req = mLoadingAsyncRequests.Steal(aRequest);
|
||||
mLoadedAsyncRequests.AppendElement(req);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -1580,7 +1590,10 @@ nsScriptLoader::ParsingComplete(bool aTerminated)
|
|||
mLoadedAsyncRequests.Clear();
|
||||
mNonAsyncExternalScriptInsertedRequests.Clear();
|
||||
mXSLTRequests.Clear();
|
||||
mParserBlockingRequest = nullptr;
|
||||
if (mParserBlockingRequest) {
|
||||
mParserBlockingRequest->Cancel();
|
||||
mParserBlockingRequest = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Have to call this even if aTerminated so we'll correctly unblock
|
||||
|
|
|
@ -64,6 +64,7 @@ public:
|
|||
mIsAsync(false),
|
||||
mIsNonAsyncScriptInserted(false),
|
||||
mIsXSLT(false),
|
||||
mIsCanceled(false),
|
||||
mScriptTextBuf(nullptr),
|
||||
mScriptTextLength(0),
|
||||
mJSVersion(aVersion),
|
||||
|
@ -89,6 +90,16 @@ public:
|
|||
return mElement == nullptr;
|
||||
}
|
||||
|
||||
void Cancel()
|
||||
{
|
||||
mIsCanceled = true;
|
||||
}
|
||||
|
||||
bool IsCanceled() const
|
||||
{
|
||||
return mIsCanceled;
|
||||
}
|
||||
|
||||
using super::getNext;
|
||||
using super::isInList;
|
||||
|
||||
|
@ -100,6 +111,7 @@ public:
|
|||
bool mIsAsync; // True if we live in mLoadingAsyncRequests or mLoadedAsyncRequests.
|
||||
bool mIsNonAsyncScriptInserted; // True if we live in mNonAsyncExternalScriptInsertedRequests
|
||||
bool mIsXSLT; // True if we live in mXSLTRequests.
|
||||
bool mIsCanceled; // True if we have been explicitly canceled.
|
||||
nsString mSourceMapURL; // Holds source map url for loaded scripts
|
||||
char16_t* mScriptTextBuf; // Holds script text for non-inline scripts. Don't
|
||||
size_t mScriptTextLength; // use nsString so we can give ownership to jsapi.
|
||||
|
|
|
@ -42,28 +42,19 @@ nsStructuredCloneContainer::~nsStructuredCloneContainer()
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsStructuredCloneContainer::InitFromJSVal(JS::Handle<JS::Value> aData)
|
||||
nsStructuredCloneContainer::InitFromJSVal(JS::Handle<JS::Value> aData,
|
||||
JSContext* aCx)
|
||||
{
|
||||
NS_ENSURE_STATE(!mData);
|
||||
|
||||
uint64_t* jsBytes = nullptr;
|
||||
bool success = false;
|
||||
if (aData.isPrimitive()) {
|
||||
// |aData| is a primitive, so the structured clone algorithm won't run
|
||||
// script and we can just use AutoJSAPI.
|
||||
dom::AutoJSAPI jsapi;
|
||||
jsapi.Init();
|
||||
success = JS_WriteStructuredClone(jsapi.cx(), aData, &jsBytes, &mSize,
|
||||
success = JS_WriteStructuredClone(aCx, aData, &jsBytes, &mSize,
|
||||
nullptr, nullptr,
|
||||
JS::UndefinedHandleValue);
|
||||
} else {
|
||||
// |aData| is an object and the structured clone algorithm can run script as
|
||||
// part of the "own" "deep clone" sub-steps, so we need an AutoEntryScript.
|
||||
// http://www.whatwg.org/specs/web-apps/current-work/#internal-structured-cloning-algorithm
|
||||
nsIGlobalObject* nativeGlobal =
|
||||
xpc::NativeGlobal(js::GetGlobalForObjectCrossCompartment(&aData.toObject()));
|
||||
dom::AutoEntryScript aes(nativeGlobal);
|
||||
success = JS_WriteStructuredClone(aes.cx(), aData, &jsBytes, &mSize,
|
||||
success = JS_WriteStructuredClone(aCx, aData, &jsBytes, &mSize,
|
||||
nullptr, nullptr,
|
||||
JS::UndefinedHandleValue);
|
||||
}
|
||||
|
|
|
@ -134,8 +134,9 @@ public:
|
|||
* Append the contents of this string fragment to aString
|
||||
* @return false if an out of memory condition is detected, true otherwise
|
||||
*/
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
bool AppendTo(nsAString& aString,
|
||||
const mozilla::fallible_t& aFallible) const NS_WARN_UNUSED_RESULT {
|
||||
const mozilla::fallible_t& aFallible) const {
|
||||
if (mState.mIs2b) {
|
||||
bool ok = aString.Append(m2b, mState.mLength, aFallible);
|
||||
if (!ok) {
|
||||
|
@ -167,8 +168,9 @@ public:
|
|||
* @param aLength the length of the substring
|
||||
* @return false if an out of memory condition is detected, true otherwise
|
||||
*/
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
bool AppendTo(nsAString& aString, int32_t aOffset, int32_t aLength,
|
||||
const mozilla::fallible_t& aFallible) const NS_WARN_UNUSED_RESULT
|
||||
const mozilla::fallible_t& aFallible) const
|
||||
{
|
||||
if (mState.mIs2b) {
|
||||
bool ok = aString.Append(m2b + aOffset, aLength, aFallible);
|
||||
|
|
|
@ -46,13 +46,13 @@ class nsXHTMLContentSerializer : public nsXMLContentSerializer {
|
|||
nsAString& aStr,
|
||||
nsresult& aResult) override;
|
||||
|
||||
NS_WARN_UNUSED_RESULT
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
virtual bool AppendEndOfElementStart(nsIContent *aOriginalElement,
|
||||
nsIAtom * aName,
|
||||
int32_t aNamespaceID,
|
||||
nsAString& aStr) override;
|
||||
|
||||
NS_WARN_UNUSED_RESULT
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
virtual bool AfterElementStart(nsIContent* aContent,
|
||||
nsIContent* aOriginalElement,
|
||||
nsAString& aStr) override;
|
||||
|
@ -75,7 +75,7 @@ class nsXHTMLContentSerializer : public nsXMLContentSerializer {
|
|||
virtual void MaybeEnterInPreContent(nsIContent* aNode) override;
|
||||
virtual void MaybeLeaveFromPreContent(nsIContent* aNode) override;
|
||||
|
||||
NS_WARN_UNUSED_RESULT
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
virtual bool SerializeAttributes(nsIContent* aContent,
|
||||
nsIContent *aOriginalElement,
|
||||
nsAString& aTagPrefix,
|
||||
|
@ -87,13 +87,13 @@ class nsXHTMLContentSerializer : public nsXMLContentSerializer {
|
|||
|
||||
bool IsFirstChildOfOL(nsIContent* aElement);
|
||||
|
||||
NS_WARN_UNUSED_RESULT
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
bool SerializeLIValueAttribute(nsIContent* aElement,
|
||||
nsAString& aStr);
|
||||
bool IsShorthandAttr(const nsIAtom* aAttrName,
|
||||
const nsIAtom* aElementName);
|
||||
|
||||
NS_WARN_UNUSED_RESULT
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
virtual bool AppendAndTranslateEntities(const nsAString& aStr,
|
||||
nsAString& aOutputStr) override;
|
||||
|
||||
|
|
|
@ -72,14 +72,14 @@ class nsXMLContentSerializer : public nsIContentSerializer {
|
|||
/**
|
||||
* Appends a char16_t character and increments the column position
|
||||
*/
|
||||
NS_WARN_UNUSED_RESULT
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
bool AppendToString(const char16_t aChar,
|
||||
nsAString& aOutputStr);
|
||||
|
||||
/**
|
||||
* Appends a nsAString string and increments the column position
|
||||
*/
|
||||
NS_WARN_UNUSED_RESULT
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
bool AppendToString(const nsAString& aStr,
|
||||
nsAString& aOutputStr);
|
||||
|
||||
|
@ -88,7 +88,7 @@ class nsXMLContentSerializer : public nsIContentSerializer {
|
|||
* by mLineBreak, except in the case of raw output.
|
||||
* It increments the column position.
|
||||
*/
|
||||
NS_WARN_UNUSED_RESULT
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
bool AppendToStringConvertLF(const nsAString& aStr,
|
||||
nsAString& aOutputStr);
|
||||
|
||||
|
@ -96,7 +96,7 @@ class nsXMLContentSerializer : public nsIContentSerializer {
|
|||
* Appends a string by wrapping it when necessary.
|
||||
* It updates the column position.
|
||||
*/
|
||||
NS_WARN_UNUSED_RESULT
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
bool AppendToStringWrapped(const nsASingleFragmentString& aStr,
|
||||
nsAString& aOutputStr);
|
||||
|
||||
|
@ -104,12 +104,12 @@ class nsXMLContentSerializer : public nsIContentSerializer {
|
|||
* Appends a string by formating and wrapping it when necessary
|
||||
* It updates the column position.
|
||||
*/
|
||||
NS_WARN_UNUSED_RESULT
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
bool AppendToStringFormatedWrapped(const nsASingleFragmentString& aStr,
|
||||
nsAString& aOutputStr);
|
||||
|
||||
// used by AppendToStringWrapped
|
||||
NS_WARN_UNUSED_RESULT
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
bool AppendWrapped_WhitespaceSequence(
|
||||
nsASingleFragmentString::const_char_iterator &aPos,
|
||||
const nsASingleFragmentString::const_char_iterator aEnd,
|
||||
|
@ -117,7 +117,7 @@ class nsXMLContentSerializer : public nsIContentSerializer {
|
|||
nsAString &aOutputStr);
|
||||
|
||||
// used by AppendToStringFormatedWrapped
|
||||
NS_WARN_UNUSED_RESULT
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
bool AppendFormatedWrapped_WhitespaceSequence(
|
||||
nsASingleFragmentString::const_char_iterator &aPos,
|
||||
const nsASingleFragmentString::const_char_iterator aEnd,
|
||||
|
@ -126,7 +126,7 @@ class nsXMLContentSerializer : public nsIContentSerializer {
|
|||
nsAString &aOutputStr);
|
||||
|
||||
// used by AppendToStringWrapped and AppendToStringFormatedWrapped
|
||||
NS_WARN_UNUSED_RESULT
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
bool AppendWrapped_NonWhitespaceSequence(
|
||||
nsASingleFragmentString::const_char_iterator &aPos,
|
||||
const nsASingleFragmentString::const_char_iterator aEnd,
|
||||
|
@ -139,7 +139,7 @@ class nsXMLContentSerializer : public nsIContentSerializer {
|
|||
* add mLineBreak to the string
|
||||
* It updates the column position and other flags.
|
||||
*/
|
||||
NS_WARN_UNUSED_RESULT
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
bool AppendNewLineToString(nsAString& aOutputStr);
|
||||
|
||||
|
||||
|
@ -147,7 +147,7 @@ class nsXMLContentSerializer : public nsIContentSerializer {
|
|||
* Appends a string by translating entities
|
||||
* It doesn't increment the column position
|
||||
*/
|
||||
NS_WARN_UNUSED_RESULT
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
virtual bool AppendAndTranslateEntities(const nsAString& aStr,
|
||||
nsAString& aOutputStr);
|
||||
|
||||
|
@ -197,7 +197,7 @@ class nsXMLContentSerializer : public nsIContentSerializer {
|
|||
nsIContent *aOriginalElement,
|
||||
const nsAString& aTagNamespaceURI);
|
||||
|
||||
NS_WARN_UNUSED_RESULT
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
virtual bool SerializeAttributes(nsIContent* aContent,
|
||||
nsIContent *aOriginalElement,
|
||||
nsAString& aTagPrefix,
|
||||
|
@ -207,7 +207,7 @@ class nsXMLContentSerializer : public nsIContentSerializer {
|
|||
uint32_t aSkipAttr,
|
||||
bool aAddNSAttr);
|
||||
|
||||
NS_WARN_UNUSED_RESULT
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
bool SerializeAttr(const nsAString& aPrefix,
|
||||
const nsAString& aName,
|
||||
const nsAString& aValue,
|
||||
|
@ -236,7 +236,7 @@ class nsXMLContentSerializer : public nsIContentSerializer {
|
|||
* this method is responsible to finish the start tag,
|
||||
* in particulary to append the "greater than" sign
|
||||
*/
|
||||
NS_WARN_UNUSED_RESULT
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
virtual bool AppendEndOfElementStart(nsIContent *aOriginalElement,
|
||||
nsIAtom * aName,
|
||||
int32_t aNamespaceID,
|
||||
|
@ -247,7 +247,7 @@ class nsXMLContentSerializer : public nsIContentSerializer {
|
|||
* after the serialization ot the start tag.
|
||||
* (called at the end of AppendElementStart)
|
||||
*/
|
||||
NS_WARN_UNUSED_RESULT
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
virtual bool AfterElementStart(nsIContent* aContent,
|
||||
nsIContent* aOriginalElement,
|
||||
nsAString& aStr) { return true; };
|
||||
|
@ -296,16 +296,16 @@ class nsXMLContentSerializer : public nsIContentSerializer {
|
|||
* add intendation. Call only in the case of formating and if the current
|
||||
* position is at 0. It updates the column position.
|
||||
*/
|
||||
NS_WARN_UNUSED_RESULT
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
bool AppendIndentation(nsAString& aStr);
|
||||
|
||||
NS_WARN_UNUSED_RESULT
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
bool IncrIndentation(nsIAtom* aName);
|
||||
void DecrIndentation(nsIAtom* aName);
|
||||
|
||||
// Functions to check for newlines that needs to be added between nodes in
|
||||
// the root of a document. See mAddNewlineForRootNode
|
||||
NS_WARN_UNUSED_RESULT
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
bool MaybeAddNewlineForRootNode(nsAString& aStr);
|
||||
void MaybeFlagNewlineForRootNode(nsINode* aNode);
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
[DEFAULT]
|
||||
skip-if = e10s
|
||||
support-files =
|
||||
file_binary-frames_wsh.py
|
||||
file_check-binary-messages_wsh.py
|
||||
|
@ -11,4 +10,4 @@ skip-if = buildapp == 'b2g' || toolkit == 'android'
|
|||
[test_send-arraybuffer.html]
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android'
|
||||
[test_send-blob.html]
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android'
|
||||
skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s
|
||||
|
|
|
@ -1,5 +1,2 @@
|
|||
[DEFAULT]
|
||||
skip-if = e10s
|
||||
|
||||
[test_battery_basics.html]
|
||||
skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug))
|
||||
|
|
|
@ -10446,7 +10446,7 @@ class CGDOMJSProxyHandler_delete(ClassMethod):
|
|||
# The deleter method has a boolean out-parameter. When a
|
||||
# property is found, the out-param indicates whether it was
|
||||
# successfully deleted.
|
||||
decls = "bool result;\n"
|
||||
decls = ""
|
||||
if foundVar is None:
|
||||
foundVar = "found"
|
||||
decls += "bool found = false;\n"
|
||||
|
|
|
@ -66,16 +66,15 @@ public:
|
|||
}
|
||||
ErrorResult& operator=(ErrorResult&& aRHS);
|
||||
|
||||
explicit ErrorResult(nsresult aRv)
|
||||
: ErrorResult()
|
||||
{
|
||||
AssignErrorCode(aRv);
|
||||
}
|
||||
|
||||
void Throw(nsresult rv) {
|
||||
MOZ_ASSERT(NS_FAILED(rv), "Please don't try throwing success");
|
||||
MOZ_ASSERT(rv != NS_ERROR_TYPE_ERR, "Use ThrowTypeError()");
|
||||
MOZ_ASSERT(rv != NS_ERROR_RANGE_ERR, "Use ThrowRangeError()");
|
||||
MOZ_ASSERT(!IsErrorWithMessage(), "Don't overwrite errors with message");
|
||||
MOZ_ASSERT(rv != NS_ERROR_DOM_JS_EXCEPTION, "Use ThrowJSException()");
|
||||
MOZ_ASSERT(!IsJSException(), "Don't overwrite JS exceptions");
|
||||
MOZ_ASSERT(rv != NS_ERROR_XPC_NOT_ENOUGH_ARGS, "Use ThrowNotEnoughArgsError()");
|
||||
MOZ_ASSERT(!IsNotEnoughArgsError(), "Don't overwrite not enough args error");
|
||||
mResult = rv;
|
||||
AssignErrorCode(rv);
|
||||
}
|
||||
|
||||
void ThrowTypeError(const dom::ErrNum errorNumber, ...);
|
||||
|
@ -141,14 +140,7 @@ public:
|
|||
// Throw() here because people can easily pass success codes to
|
||||
// this.
|
||||
void operator=(nsresult rv) {
|
||||
MOZ_ASSERT(rv != NS_ERROR_TYPE_ERR, "Use ThrowTypeError()");
|
||||
MOZ_ASSERT(rv != NS_ERROR_RANGE_ERR, "Use ThrowRangeError()");
|
||||
MOZ_ASSERT(!IsErrorWithMessage(), "Don't overwrite errors with message");
|
||||
MOZ_ASSERT(rv != NS_ERROR_DOM_JS_EXCEPTION, "Use ThrowJSException()");
|
||||
MOZ_ASSERT(!IsJSException(), "Don't overwrite JS exceptions");
|
||||
MOZ_ASSERT(rv != NS_ERROR_XPC_NOT_ENOUGH_ARGS, "Use ThrowNotEnoughArgsError()");
|
||||
MOZ_ASSERT(!IsNotEnoughArgsError(), "Don't overwrite not enough args error");
|
||||
mResult = rv;
|
||||
AssignErrorCode(rv);
|
||||
}
|
||||
|
||||
bool Failed() const {
|
||||
|
@ -160,6 +152,24 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
friend struct IPC::ParamTraits<ErrorResult>;
|
||||
void SerializeMessage(IPC::Message* aMsg) const;
|
||||
bool DeserializeMessage(const IPC::Message* aMsg, void** aIter);
|
||||
|
||||
void ThrowErrorWithMessage(va_list ap, const dom::ErrNum errorNumber,
|
||||
nsresult errorType);
|
||||
|
||||
void AssignErrorCode(nsresult aRv) {
|
||||
MOZ_ASSERT(aRv != NS_ERROR_TYPE_ERR, "Use ThrowTypeError()");
|
||||
MOZ_ASSERT(aRv != NS_ERROR_RANGE_ERR, "Use ThrowRangeError()");
|
||||
MOZ_ASSERT(!IsErrorWithMessage(), "Don't overwrite errors with message");
|
||||
MOZ_ASSERT(aRv != NS_ERROR_DOM_JS_EXCEPTION, "Use ThrowJSException()");
|
||||
MOZ_ASSERT(!IsJSException(), "Don't overwrite JS exceptions");
|
||||
MOZ_ASSERT(aRv != NS_ERROR_XPC_NOT_ENOUGH_ARGS, "Use ThrowNotEnoughArgsError()");
|
||||
MOZ_ASSERT(!IsNotEnoughArgsError(), "Don't overwrite not enough args error");
|
||||
mResult = aRv;
|
||||
}
|
||||
|
||||
nsresult mResult;
|
||||
struct Message;
|
||||
// mMessage is set by ThrowErrorWithMessage and cleared (and deallocated) by
|
||||
|
@ -171,10 +181,6 @@ private:
|
|||
JS::Value mJSException; // valid when IsJSException()
|
||||
};
|
||||
|
||||
friend struct IPC::ParamTraits<ErrorResult>;
|
||||
void SerializeMessage(IPC::Message* aMsg) const;
|
||||
bool DeserializeMessage(const IPC::Message* aMsg, void** aIter);
|
||||
|
||||
#ifdef DEBUG
|
||||
// Used to keep track of codepaths that might throw JS exceptions,
|
||||
// for assertion purposes.
|
||||
|
@ -189,8 +195,6 @@ private:
|
|||
// reference, not by value.
|
||||
ErrorResult(const ErrorResult&) = delete;
|
||||
void operator=(const ErrorResult&) = delete;
|
||||
void ThrowErrorWithMessage(va_list ap, const dom::ErrNum errorNumber,
|
||||
nsresult errorType);
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "nsHashKeys.h"
|
||||
#include "nsStringGlue.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Move.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -100,7 +101,8 @@ public:
|
|||
this->EnumerateEntries(ValueEnumerator, &args);
|
||||
}
|
||||
|
||||
DataType* AddEntry(const nsAString& aKey) NS_WARN_UNUSED_RESULT
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
DataType* AddEntry(const nsAString& aKey)
|
||||
{
|
||||
EntryType* ent = this->PutEntry(aKey, fallible);
|
||||
if (!ent) {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "mozilla/dom/cache/ActorChild.h"
|
||||
|
||||
#include "mozilla/dom/cache/Feature.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -32,6 +33,7 @@ ActorChild::SetFeature(Feature* aFeature)
|
|||
void
|
||||
ActorChild::RemoveFeature()
|
||||
{
|
||||
MOZ_ASSERT_IF(!NS_IsMainThread(), mFeature);
|
||||
if (mFeature) {
|
||||
mFeature->RemoveActor(this);
|
||||
mFeature = nullptr;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "mozilla/dom/cache/AutoUtils.h"
|
||||
|
||||
#include "mozilla/unused.h"
|
||||
#include "mozilla/dom/cache/CacheParent.h"
|
||||
#include "mozilla/dom/cache/CachePushStreamChild.h"
|
||||
#include "mozilla/dom/cache/CacheStreamControlParent.h"
|
||||
#include "mozilla/dom/cache/ReadStream.h"
|
||||
|
@ -21,8 +22,8 @@ namespace {
|
|||
|
||||
using mozilla::unused;
|
||||
using mozilla::dom::cache::CachePushStreamChild;
|
||||
using mozilla::dom::cache::PCacheReadStream;
|
||||
using mozilla::dom::cache::PCacheReadStreamOrVoid;
|
||||
using mozilla::dom::cache::CacheReadStream;
|
||||
using mozilla::dom::cache::CacheReadStreamOrVoid;
|
||||
using mozilla::ipc::FileDescriptor;
|
||||
using mozilla::ipc::FileDescriptorSetChild;
|
||||
using mozilla::ipc::FileDescriptorSetParent;
|
||||
|
@ -35,7 +36,7 @@ enum CleanupAction
|
|||
};
|
||||
|
||||
void
|
||||
CleanupChildFds(PCacheReadStream& aReadStream, CleanupAction aAction)
|
||||
CleanupChildFds(CacheReadStream& aReadStream, CleanupAction aAction)
|
||||
{
|
||||
if (aReadStream.fds().type() !=
|
||||
OptionalFileDescriptorSet::TPFileDescriptorSetChild) {
|
||||
|
@ -59,7 +60,7 @@ CleanupChildFds(PCacheReadStream& aReadStream, CleanupAction aAction)
|
|||
}
|
||||
|
||||
void
|
||||
CleanupChildPushStream(PCacheReadStream& aReadStream, CleanupAction aAction)
|
||||
CleanupChildPushStream(CacheReadStream& aReadStream, CleanupAction aAction)
|
||||
{
|
||||
if (!aReadStream.pushStreamChild()) {
|
||||
return;
|
||||
|
@ -78,24 +79,24 @@ CleanupChildPushStream(PCacheReadStream& aReadStream, CleanupAction aAction)
|
|||
}
|
||||
|
||||
void
|
||||
CleanupChild(PCacheReadStream& aReadStream, CleanupAction aAction)
|
||||
CleanupChild(CacheReadStream& aReadStream, CleanupAction aAction)
|
||||
{
|
||||
CleanupChildFds(aReadStream, aAction);
|
||||
CleanupChildPushStream(aReadStream, aAction);
|
||||
}
|
||||
|
||||
void
|
||||
CleanupChild(PCacheReadStreamOrVoid& aReadStreamOrVoid, CleanupAction aAction)
|
||||
CleanupChild(CacheReadStreamOrVoid& aReadStreamOrVoid, CleanupAction aAction)
|
||||
{
|
||||
if (aReadStreamOrVoid.type() == PCacheReadStreamOrVoid::Tvoid_t) {
|
||||
if (aReadStreamOrVoid.type() == CacheReadStreamOrVoid::Tvoid_t) {
|
||||
return;
|
||||
}
|
||||
|
||||
CleanupChild(aReadStreamOrVoid.get_PCacheReadStream(), aAction);
|
||||
CleanupChild(aReadStreamOrVoid.get_CacheReadStream(), aAction);
|
||||
}
|
||||
|
||||
void
|
||||
CleanupParentFds(PCacheReadStream& aReadStream, CleanupAction aAction)
|
||||
CleanupParentFds(CacheReadStream& aReadStream, CleanupAction aAction)
|
||||
{
|
||||
if (aReadStream.fds().type() !=
|
||||
OptionalFileDescriptorSet::TPFileDescriptorSetParent) {
|
||||
|
@ -119,13 +120,13 @@ CleanupParentFds(PCacheReadStream& aReadStream, CleanupAction aAction)
|
|||
}
|
||||
|
||||
void
|
||||
CleanupParentFds(PCacheReadStreamOrVoid& aReadStreamOrVoid, CleanupAction aAction)
|
||||
CleanupParentFds(CacheReadStreamOrVoid& aReadStreamOrVoid, CleanupAction aAction)
|
||||
{
|
||||
if (aReadStreamOrVoid.type() == PCacheReadStreamOrVoid::Tvoid_t) {
|
||||
if (aReadStreamOrVoid.type() == CacheReadStreamOrVoid::Tvoid_t) {
|
||||
return;
|
||||
}
|
||||
|
||||
CleanupParentFds(aReadStreamOrVoid.get_PCacheReadStream(), aAction);
|
||||
CleanupParentFds(aReadStreamOrVoid.get_CacheReadStream(), aAction);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
@ -136,171 +137,381 @@ namespace cache {
|
|||
|
||||
using mozilla::ipc::PBackgroundParent;
|
||||
|
||||
AutoChildBase::AutoChildBase(TypeUtils* aTypeUtils)
|
||||
// --------------------------------------------
|
||||
|
||||
AutoChildOpArgs::AutoChildOpArgs(TypeUtils* aTypeUtils,
|
||||
const CacheOpArgs& aOpArgs)
|
||||
: mTypeUtils(aTypeUtils)
|
||||
, mOpArgs(aOpArgs)
|
||||
, mSent(false)
|
||||
{
|
||||
MOZ_ASSERT(mTypeUtils);
|
||||
}
|
||||
|
||||
AutoChildBase::~AutoChildBase()
|
||||
{
|
||||
}
|
||||
|
||||
// --------------------------------------------
|
||||
|
||||
AutoChildRequest::AutoChildRequest(TypeUtils* aTypeUtils)
|
||||
: AutoChildBase(aTypeUtils)
|
||||
{
|
||||
mRequestOrVoid = void_t();
|
||||
}
|
||||
|
||||
AutoChildRequest::~AutoChildRequest()
|
||||
{
|
||||
if (mRequestOrVoid.type() != PCacheRequestOrVoid::TPCacheRequest) {
|
||||
return;
|
||||
}
|
||||
|
||||
CleanupAction action = mSent ? Forget : Delete;
|
||||
CleanupChild(mRequestOrVoid.get_PCacheRequest().body(), action);
|
||||
}
|
||||
|
||||
void
|
||||
AutoChildRequest::Add(InternalRequest* aRequest, BodyAction aBodyAction,
|
||||
ReferrerAction aReferrerAction, SchemeAction aSchemeAction,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
MOZ_ASSERT(mRequestOrVoid.type() == PCacheRequestOrVoid::Tvoid_t);
|
||||
mRequestOrVoid = PCacheRequest();
|
||||
mTypeUtils->ToPCacheRequest(mRequestOrVoid.get_PCacheRequest(), aRequest,
|
||||
aBodyAction, aReferrerAction, aSchemeAction, aRv);
|
||||
}
|
||||
|
||||
const PCacheRequest&
|
||||
AutoChildRequest::SendAsRequest()
|
||||
{
|
||||
MOZ_ASSERT(mRequestOrVoid.type() == PCacheRequestOrVoid::TPCacheRequest);
|
||||
return mRequestOrVoid.get_PCacheRequest();
|
||||
}
|
||||
|
||||
const PCacheRequestOrVoid&
|
||||
AutoChildRequest::SendAsRequestOrVoid()
|
||||
{
|
||||
return mRequestOrVoid;
|
||||
}
|
||||
|
||||
// --------------------------------------------
|
||||
|
||||
AutoChildRequestList::AutoChildRequestList(TypeUtils* aTypeUtils,
|
||||
uint32_t aCapacity)
|
||||
: AutoChildBase(aTypeUtils)
|
||||
{
|
||||
mRequestList.SetCapacity(aCapacity);
|
||||
}
|
||||
|
||||
AutoChildRequestList::~AutoChildRequestList()
|
||||
AutoChildOpArgs::~AutoChildOpArgs()
|
||||
{
|
||||
CleanupAction action = mSent ? Forget : Delete;
|
||||
for (uint32_t i = 0; i < mRequestList.Length(); ++i) {
|
||||
CleanupChild(mRequestList[i].body(), action);
|
||||
|
||||
switch(mOpArgs.type()) {
|
||||
case CacheOpArgs::TCacheMatchArgs:
|
||||
{
|
||||
CacheMatchArgs& args = mOpArgs.get_CacheMatchArgs();
|
||||
CleanupChild(args.request().body(), action);
|
||||
break;
|
||||
}
|
||||
case CacheOpArgs::TCacheMatchAllArgs:
|
||||
{
|
||||
CacheMatchAllArgs& args = mOpArgs.get_CacheMatchAllArgs();
|
||||
if (args.requestOrVoid().type() == CacheRequestOrVoid::Tvoid_t) {
|
||||
break;
|
||||
}
|
||||
CleanupChild(args.requestOrVoid().get_CacheRequest().body(), action);
|
||||
break;
|
||||
}
|
||||
case CacheOpArgs::TCacheAddAllArgs:
|
||||
{
|
||||
CacheAddAllArgs& args = mOpArgs.get_CacheAddAllArgs();
|
||||
auto& list = args.requestList();
|
||||
for (uint32_t i = 0; i < list.Length(); ++i) {
|
||||
CleanupChild(list[i].body(), action);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CacheOpArgs::TCachePutAllArgs:
|
||||
{
|
||||
CachePutAllArgs& args = mOpArgs.get_CachePutAllArgs();
|
||||
auto& list = args.requestResponseList();
|
||||
for (uint32_t i = 0; i < list.Length(); ++i) {
|
||||
CleanupChild(list[i].request().body(), action);
|
||||
CleanupChild(list[i].response().body(), action);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CacheOpArgs::TCacheDeleteArgs:
|
||||
{
|
||||
CacheDeleteArgs& args = mOpArgs.get_CacheDeleteArgs();
|
||||
CleanupChild(args.request().body(), action);
|
||||
break;
|
||||
}
|
||||
case CacheOpArgs::TCacheKeysArgs:
|
||||
{
|
||||
CacheKeysArgs& args = mOpArgs.get_CacheKeysArgs();
|
||||
if (args.requestOrVoid().type() == CacheRequestOrVoid::Tvoid_t) {
|
||||
break;
|
||||
}
|
||||
CleanupChild(args.requestOrVoid().get_CacheRequest().body(), action);
|
||||
break;
|
||||
}
|
||||
case CacheOpArgs::TStorageMatchArgs:
|
||||
{
|
||||
StorageMatchArgs& args = mOpArgs.get_StorageMatchArgs();
|
||||
CleanupChild(args.request().body(), action);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// Other types do not need cleanup
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AutoChildRequestList::Add(InternalRequest* aRequest, BodyAction aBodyAction,
|
||||
ReferrerAction aReferrerAction,
|
||||
SchemeAction aSchemeAction, ErrorResult& aRv)
|
||||
AutoChildOpArgs::Add(InternalRequest* aRequest, BodyAction aBodyAction,
|
||||
ReferrerAction aReferrerAction, SchemeAction aSchemeAction,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
|
||||
// The FileDescriptorSetChild asserts in its destructor that all fds have
|
||||
// been removed. The copy constructor, however, simply duplicates the
|
||||
// fds without removing any. This means each temporary and copy must be
|
||||
// explicitly cleaned up.
|
||||
//
|
||||
// Avoid a lot of this hassle by making sure we only create one here. On
|
||||
// error we remove it.
|
||||
switch(mOpArgs.type()) {
|
||||
case CacheOpArgs::TCacheMatchArgs:
|
||||
{
|
||||
CacheMatchArgs& args = mOpArgs.get_CacheMatchArgs();
|
||||
mTypeUtils->ToCacheRequest(args.request(), aRequest, aBodyAction,
|
||||
aReferrerAction, aSchemeAction, aRv);
|
||||
break;
|
||||
}
|
||||
case CacheOpArgs::TCacheMatchAllArgs:
|
||||
{
|
||||
CacheMatchAllArgs& args = mOpArgs.get_CacheMatchAllArgs();
|
||||
MOZ_ASSERT(args.requestOrVoid().type() == CacheRequestOrVoid::Tvoid_t);
|
||||
args.requestOrVoid() = CacheRequest();
|
||||
mTypeUtils->ToCacheRequest(args.requestOrVoid().get_CacheRequest(),
|
||||
aRequest, aBodyAction, aReferrerAction,
|
||||
aSchemeAction, aRv);
|
||||
break;
|
||||
}
|
||||
case CacheOpArgs::TCacheAddAllArgs:
|
||||
{
|
||||
CacheAddAllArgs& args = mOpArgs.get_CacheAddAllArgs();
|
||||
|
||||
PCacheRequest* request = mRequestList.AppendElement();
|
||||
mTypeUtils->ToPCacheRequest(*request, aRequest, aBodyAction, aReferrerAction,
|
||||
aSchemeAction, aRv);
|
||||
if (aRv.Failed()) {
|
||||
mRequestList.RemoveElementAt(mRequestList.Length() - 1);
|
||||
// The FileDescriptorSetChild asserts in its destructor that all fds have
|
||||
// been removed. The copy constructor, however, simply duplicates the
|
||||
// fds without removing any. This means each temporary and copy must be
|
||||
// explicitly cleaned up.
|
||||
//
|
||||
// Avoid a lot of this hassle by making sure we only create one here. On
|
||||
// error we remove it.
|
||||
CacheRequest& request = *args.requestList().AppendElement();
|
||||
|
||||
mTypeUtils->ToCacheRequest(request, aRequest, aBodyAction,
|
||||
aReferrerAction, aSchemeAction, aRv);
|
||||
if (aRv.Failed()) {
|
||||
args.requestList().RemoveElementAt(args.requestList().Length() - 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CacheOpArgs::TCacheDeleteArgs:
|
||||
{
|
||||
CacheDeleteArgs& args = mOpArgs.get_CacheDeleteArgs();
|
||||
mTypeUtils->ToCacheRequest(args.request(), aRequest, aBodyAction,
|
||||
aReferrerAction, aSchemeAction, aRv);
|
||||
break;
|
||||
}
|
||||
case CacheOpArgs::TCacheKeysArgs:
|
||||
{
|
||||
CacheKeysArgs& args = mOpArgs.get_CacheKeysArgs();
|
||||
MOZ_ASSERT(args.requestOrVoid().type() == CacheRequestOrVoid::Tvoid_t);
|
||||
args.requestOrVoid() = CacheRequest();
|
||||
mTypeUtils->ToCacheRequest(args.requestOrVoid().get_CacheRequest(),
|
||||
aRequest, aBodyAction, aReferrerAction,
|
||||
aSchemeAction, aRv);
|
||||
break;
|
||||
}
|
||||
case CacheOpArgs::TStorageMatchArgs:
|
||||
{
|
||||
StorageMatchArgs& args = mOpArgs.get_StorageMatchArgs();
|
||||
mTypeUtils->ToCacheRequest(args.request(), aRequest, aBodyAction,
|
||||
aReferrerAction, aSchemeAction, aRv);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MOZ_CRASH("Cache args type cannot send a Request!");
|
||||
}
|
||||
}
|
||||
|
||||
const nsTArray<PCacheRequest>&
|
||||
AutoChildRequestList::SendAsRequestList()
|
||||
void
|
||||
AutoChildOpArgs::Add(InternalRequest* aRequest, BodyAction aBodyAction,
|
||||
ReferrerAction aReferrerAction, SchemeAction aSchemeAction,
|
||||
Response& aResponse, ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
|
||||
switch(mOpArgs.type()) {
|
||||
case CacheOpArgs::TCachePutAllArgs:
|
||||
{
|
||||
CachePutAllArgs& args = mOpArgs.get_CachePutAllArgs();
|
||||
|
||||
// The FileDescriptorSetChild asserts in its destructor that all fds have
|
||||
// been removed. The copy constructor, however, simply duplicates the
|
||||
// fds without removing any. This means each temporary and copy must be
|
||||
// explicitly cleaned up.
|
||||
//
|
||||
// Avoid a lot of this hassle by making sure we only create one here. On
|
||||
// error we remove it.
|
||||
CacheRequestResponse& pair = *args.requestResponseList().AppendElement();
|
||||
pair.request().body() = void_t();
|
||||
pair.response().body() = void_t();
|
||||
|
||||
mTypeUtils->ToCacheRequest(pair.request(), aRequest, aBodyAction,
|
||||
aReferrerAction, aSchemeAction, aRv);
|
||||
if (!aRv.Failed()) {
|
||||
mTypeUtils->ToCacheResponse(pair.response(), aResponse, aRv);
|
||||
}
|
||||
|
||||
if (aRv.Failed()) {
|
||||
CleanupChild(pair.request().body(), Delete);
|
||||
args.requestResponseList().RemoveElementAt(
|
||||
args.requestResponseList().Length() - 1);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MOZ_CRASH("Cache args type cannot send a Request/Response pair!");
|
||||
}
|
||||
}
|
||||
|
||||
const CacheOpArgs&
|
||||
AutoChildOpArgs::SendAsOpArgs()
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
mSent = true;
|
||||
return mRequestList;
|
||||
return mOpArgs;
|
||||
}
|
||||
|
||||
// --------------------------------------------
|
||||
|
||||
AutoChildRequestResponse::AutoChildRequestResponse(TypeUtils* aTypeUtils)
|
||||
: AutoChildBase(aTypeUtils)
|
||||
{
|
||||
// Default IPC-generated constructor does not initialize these correctly
|
||||
// and we check them later when cleaning up.
|
||||
mRequestResponse.request().body() = void_t();
|
||||
mRequestResponse.response().body() = void_t();
|
||||
}
|
||||
|
||||
AutoChildRequestResponse::~AutoChildRequestResponse()
|
||||
{
|
||||
CleanupAction action = mSent ? Forget : Delete;
|
||||
CleanupChild(mRequestResponse.request().body(), action);
|
||||
CleanupChild(mRequestResponse.response().body(), action);
|
||||
}
|
||||
|
||||
void
|
||||
AutoChildRequestResponse::Add(InternalRequest* aRequest, BodyAction aBodyAction,
|
||||
ReferrerAction aReferrerAction,
|
||||
SchemeAction aSchemeAction, ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
mTypeUtils->ToPCacheRequest(mRequestResponse.request(), aRequest, aBodyAction,
|
||||
aReferrerAction, aSchemeAction, aRv);
|
||||
}
|
||||
|
||||
void
|
||||
AutoChildRequestResponse::Add(Response& aResponse, ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
mTypeUtils->ToPCacheResponse(mRequestResponse.response(), aResponse, aRv);
|
||||
}
|
||||
|
||||
const CacheRequestResponse&
|
||||
AutoChildRequestResponse::SendAsRequestResponse()
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
mSent = true;
|
||||
return mRequestResponse;
|
||||
}
|
||||
|
||||
// --------------------------------------------
|
||||
|
||||
AutoParentBase::AutoParentBase(PBackgroundParent* aManager)
|
||||
AutoParentOpResult::AutoParentOpResult(mozilla::ipc::PBackgroundParent* aManager,
|
||||
const CacheOpResult& aOpResult)
|
||||
: mManager(aManager)
|
||||
, mOpResult(aOpResult)
|
||||
, mStreamControl(nullptr)
|
||||
, mSent(false)
|
||||
{
|
||||
MOZ_ASSERT(mManager);
|
||||
}
|
||||
|
||||
AutoParentBase::~AutoParentBase()
|
||||
AutoParentOpResult::~AutoParentOpResult()
|
||||
{
|
||||
if (!mSent && mStreamControl) {
|
||||
CleanupAction action = mSent ? Forget : Delete;
|
||||
|
||||
switch (mOpResult.type()) {
|
||||
case CacheOpResult::TCacheMatchResult:
|
||||
{
|
||||
CacheMatchResult& result = mOpResult.get_CacheMatchResult();
|
||||
if (result.responseOrVoid().type() == CacheResponseOrVoid::Tvoid_t) {
|
||||
break;
|
||||
}
|
||||
CleanupParentFds(result.responseOrVoid().get_CacheResponse().body(),
|
||||
action);
|
||||
break;
|
||||
}
|
||||
case CacheOpResult::TCacheMatchAllResult:
|
||||
{
|
||||
CacheMatchAllResult& result = mOpResult.get_CacheMatchAllResult();
|
||||
for (uint32_t i = 0; i < result.responseList().Length(); ++i) {
|
||||
CleanupParentFds(result.responseList()[i].body(), action);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CacheOpResult::TCacheKeysResult:
|
||||
{
|
||||
CacheKeysResult& result = mOpResult.get_CacheKeysResult();
|
||||
for (uint32_t i = 0; i < result.requestList().Length(); ++i) {
|
||||
CleanupParentFds(result.requestList()[i].body(), action);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CacheOpResult::TStorageMatchResult:
|
||||
{
|
||||
StorageMatchResult& result = mOpResult.get_StorageMatchResult();
|
||||
if (result.responseOrVoid().type() == CacheResponseOrVoid::Tvoid_t) {
|
||||
break;
|
||||
}
|
||||
CleanupParentFds(result.responseOrVoid().get_CacheResponse().body(),
|
||||
action);
|
||||
break;
|
||||
}
|
||||
case CacheOpResult::TStorageOpenResult:
|
||||
{
|
||||
StorageOpenResult& result = mOpResult.get_StorageOpenResult();
|
||||
if (action == Forget || result.actorParent() == nullptr) {
|
||||
break;
|
||||
}
|
||||
unused << PCacheParent::Send__delete__(result.actorParent());
|
||||
}
|
||||
default:
|
||||
// other types do not need clean up
|
||||
break;
|
||||
}
|
||||
|
||||
if (action == Delete && mStreamControl) {
|
||||
unused << PCacheStreamControlParent::Send__delete__(mStreamControl);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AutoParentBase::SerializeReadStream(const nsID& aId, StreamList* aStreamList,
|
||||
PCacheReadStream* aReadStreamOut)
|
||||
AutoParentOpResult::Add(CacheId aOpenedCacheId, Manager* aManager)
|
||||
{
|
||||
MOZ_ASSERT(mOpResult.type() == CacheOpResult::TStorageOpenResult);
|
||||
MOZ_ASSERT(mOpResult.get_StorageOpenResult().actorParent() == nullptr);
|
||||
mOpResult.get_StorageOpenResult().actorParent() =
|
||||
mManager->SendPCacheConstructor(new CacheParent(aManager, aOpenedCacheId));
|
||||
}
|
||||
|
||||
void
|
||||
AutoParentOpResult::Add(const SavedResponse& aSavedResponse,
|
||||
StreamList* aStreamList)
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
|
||||
switch (mOpResult.type()) {
|
||||
case CacheOpResult::TCacheMatchResult:
|
||||
{
|
||||
CacheMatchResult& result = mOpResult.get_CacheMatchResult();
|
||||
MOZ_ASSERT(result.responseOrVoid().type() == CacheResponseOrVoid::Tvoid_t);
|
||||
result.responseOrVoid() = aSavedResponse.mValue;
|
||||
SerializeResponseBody(aSavedResponse, aStreamList,
|
||||
&result.responseOrVoid().get_CacheResponse());
|
||||
break;
|
||||
}
|
||||
case CacheOpResult::TCacheMatchAllResult:
|
||||
{
|
||||
CacheMatchAllResult& result = mOpResult.get_CacheMatchAllResult();
|
||||
result.responseList().AppendElement(aSavedResponse.mValue);
|
||||
SerializeResponseBody(aSavedResponse, aStreamList,
|
||||
&result.responseList().LastElement());
|
||||
break;
|
||||
}
|
||||
case CacheOpResult::TStorageMatchResult:
|
||||
{
|
||||
StorageMatchResult& result = mOpResult.get_StorageMatchResult();
|
||||
MOZ_ASSERT(result.responseOrVoid().type() == CacheResponseOrVoid::Tvoid_t);
|
||||
result.responseOrVoid() = aSavedResponse.mValue;
|
||||
SerializeResponseBody(aSavedResponse, aStreamList,
|
||||
&result.responseOrVoid().get_CacheResponse());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MOZ_CRASH("Cache result type cannot handle returning a Response!");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AutoParentOpResult::Add(const SavedRequest& aSavedRequest,
|
||||
StreamList* aStreamList)
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
|
||||
switch (mOpResult.type()) {
|
||||
case CacheOpResult::TCacheKeysResult:
|
||||
{
|
||||
CacheKeysResult& result = mOpResult.get_CacheKeysResult();
|
||||
result.requestList().AppendElement(aSavedRequest.mValue);
|
||||
CacheRequest& request = result.requestList().LastElement();
|
||||
|
||||
if (!aSavedRequest.mHasBodyId) {
|
||||
request.body() = void_t();
|
||||
break;
|
||||
}
|
||||
|
||||
request.body() = CacheReadStream();
|
||||
SerializeReadStream(aSavedRequest.mBodyId, aStreamList,
|
||||
&request.body().get_CacheReadStream());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MOZ_CRASH("Cache result type cannot handle returning a Request!");
|
||||
}
|
||||
}
|
||||
|
||||
const CacheOpResult&
|
||||
AutoParentOpResult::SendAsOpResult()
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
mSent = true;
|
||||
return mOpResult;
|
||||
}
|
||||
|
||||
void
|
||||
AutoParentOpResult::SerializeResponseBody(const SavedResponse& aSavedResponse,
|
||||
StreamList* aStreamList,
|
||||
CacheResponse* aResponseOut)
|
||||
{
|
||||
MOZ_ASSERT(aResponseOut);
|
||||
|
||||
if (!aSavedResponse.mHasBodyId) {
|
||||
aResponseOut->body() = void_t();
|
||||
return;
|
||||
}
|
||||
|
||||
aResponseOut->body() = CacheReadStream();
|
||||
SerializeReadStream(aSavedResponse.mBodyId, aStreamList,
|
||||
&aResponseOut->body().get_CacheReadStream());
|
||||
}
|
||||
|
||||
void
|
||||
AutoParentOpResult::SerializeReadStream(const nsID& aId, StreamList* aStreamList,
|
||||
CacheReadStream* aReadStreamOut)
|
||||
{
|
||||
MOZ_ASSERT(aStreamList);
|
||||
MOZ_ASSERT(aReadStreamOut);
|
||||
|
@ -328,139 +539,6 @@ AutoParentBase::SerializeReadStream(const nsID& aId, StreamList* aStreamList,
|
|||
readStream->Serialize(aReadStreamOut);
|
||||
}
|
||||
|
||||
// --------------------------------------------
|
||||
|
||||
AutoParentRequestList::AutoParentRequestList(PBackgroundParent* aManager,
|
||||
uint32_t aCapacity)
|
||||
: AutoParentBase(aManager)
|
||||
{
|
||||
mRequestList.SetCapacity(aCapacity);
|
||||
}
|
||||
|
||||
AutoParentRequestList::~AutoParentRequestList()
|
||||
{
|
||||
CleanupAction action = mSent ? Forget : Delete;
|
||||
for (uint32_t i = 0; i < mRequestList.Length(); ++i) {
|
||||
CleanupParentFds(mRequestList[i].body(), action);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AutoParentRequestList::Add(const SavedRequest& aSavedRequest,
|
||||
StreamList* aStreamList)
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
|
||||
mRequestList.AppendElement(aSavedRequest.mValue);
|
||||
PCacheRequest& request = mRequestList.LastElement();
|
||||
|
||||
if (!aSavedRequest.mHasBodyId) {
|
||||
request.body() = void_t();
|
||||
return;
|
||||
}
|
||||
|
||||
request.body() = PCacheReadStream();
|
||||
SerializeReadStream(aSavedRequest.mBodyId, aStreamList,
|
||||
&request.body().get_PCacheReadStream());
|
||||
}
|
||||
|
||||
const nsTArray<PCacheRequest>&
|
||||
AutoParentRequestList::SendAsRequestList()
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
mSent = true;
|
||||
return mRequestList;
|
||||
}
|
||||
|
||||
// --------------------------------------------
|
||||
|
||||
AutoParentResponseList::AutoParentResponseList(PBackgroundParent* aManager,
|
||||
uint32_t aCapacity)
|
||||
: AutoParentBase(aManager)
|
||||
{
|
||||
mResponseList.SetCapacity(aCapacity);
|
||||
}
|
||||
|
||||
AutoParentResponseList::~AutoParentResponseList()
|
||||
{
|
||||
CleanupAction action = mSent ? Forget : Delete;
|
||||
for (uint32_t i = 0; i < mResponseList.Length(); ++i) {
|
||||
CleanupParentFds(mResponseList[i].body(), action);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AutoParentResponseList::Add(const SavedResponse& aSavedResponse,
|
||||
StreamList* aStreamList)
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
|
||||
mResponseList.AppendElement(aSavedResponse.mValue);
|
||||
PCacheResponse& response = mResponseList.LastElement();
|
||||
|
||||
if (!aSavedResponse.mHasBodyId) {
|
||||
response.body() = void_t();
|
||||
return;
|
||||
}
|
||||
|
||||
response.body() = PCacheReadStream();
|
||||
SerializeReadStream(aSavedResponse.mBodyId, aStreamList,
|
||||
&response.body().get_PCacheReadStream());
|
||||
}
|
||||
|
||||
const nsTArray<PCacheResponse>&
|
||||
AutoParentResponseList::SendAsResponseList()
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
mSent = true;
|
||||
return mResponseList;
|
||||
}
|
||||
|
||||
// --------------------------------------------
|
||||
|
||||
AutoParentResponseOrVoid::AutoParentResponseOrVoid(ipc::PBackgroundParent* aManager)
|
||||
: AutoParentBase(aManager)
|
||||
{
|
||||
mResponseOrVoid = void_t();
|
||||
}
|
||||
|
||||
AutoParentResponseOrVoid::~AutoParentResponseOrVoid()
|
||||
{
|
||||
if (mResponseOrVoid.type() != PCacheResponseOrVoid::TPCacheResponse) {
|
||||
return;
|
||||
}
|
||||
|
||||
CleanupAction action = mSent ? Forget : Delete;
|
||||
CleanupParentFds(mResponseOrVoid.get_PCacheResponse().body(), action);
|
||||
}
|
||||
|
||||
void
|
||||
AutoParentResponseOrVoid::Add(const SavedResponse& aSavedResponse,
|
||||
StreamList* aStreamList)
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
|
||||
mResponseOrVoid = aSavedResponse.mValue;
|
||||
PCacheResponse& response = mResponseOrVoid.get_PCacheResponse();
|
||||
|
||||
if (!aSavedResponse.mHasBodyId) {
|
||||
response.body() = void_t();
|
||||
return;
|
||||
}
|
||||
|
||||
response.body() = PCacheReadStream();
|
||||
SerializeReadStream(aSavedResponse.mBodyId, aStreamList,
|
||||
&response.body().get_PCacheReadStream());
|
||||
}
|
||||
|
||||
const PCacheResponseOrVoid&
|
||||
AutoParentResponseOrVoid::SendAsResponseOrVoid()
|
||||
{
|
||||
MOZ_ASSERT(!mSent);
|
||||
mSent = true;
|
||||
return mResponseOrVoid;
|
||||
}
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
#define mozilla_dom_cache_AutoUtils_h
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/dom/cache/PCacheTypes.h"
|
||||
#include "mozilla/dom/cache/CacheTypes.h"
|
||||
#include "mozilla/dom/cache/Types.h"
|
||||
#include "mozilla/dom/cache/TypeUtils.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
|
@ -29,6 +30,7 @@ class InternalRequest;
|
|||
namespace cache {
|
||||
|
||||
class CacheStreamControlParent;
|
||||
class Manager;
|
||||
struct SavedRequest;
|
||||
struct SavedResponse;
|
||||
class StreamList;
|
||||
|
@ -41,129 +43,56 @@ class StreamList;
|
|||
// Note, these should only be used when *sending* streams across IPC. The
|
||||
// deserialization case is handled by creating a ReadStream object.
|
||||
|
||||
class MOZ_STACK_CLASS AutoChildBase
|
||||
class MOZ_STACK_CLASS AutoChildOpArgs final
|
||||
{
|
||||
protected:
|
||||
public:
|
||||
typedef TypeUtils::BodyAction BodyAction;
|
||||
typedef TypeUtils::ReferrerAction ReferrerAction;
|
||||
typedef TypeUtils::SchemeAction SchemeAction;
|
||||
|
||||
AutoChildBase(TypeUtils* aTypeUtils);
|
||||
virtual ~AutoChildBase() = 0;
|
||||
AutoChildOpArgs(TypeUtils* aTypeUtils, const CacheOpArgs& aOpArgs);
|
||||
~AutoChildOpArgs();
|
||||
|
||||
void Add(InternalRequest* aRequest, BodyAction aBodyAction,
|
||||
ReferrerAction aReferrerAction, SchemeAction aSchemeAction,
|
||||
ErrorResult& aRv);
|
||||
void Add(InternalRequest* aRequest, BodyAction aBodyAction,
|
||||
ReferrerAction aReferrerAction, SchemeAction aSchemeAction,
|
||||
Response& aResponse, ErrorResult& aRv);
|
||||
|
||||
const CacheOpArgs& SendAsOpArgs();
|
||||
|
||||
private:
|
||||
TypeUtils* mTypeUtils;
|
||||
CacheOpArgs mOpArgs;
|
||||
bool mSent;
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS AutoChildRequest final : public AutoChildBase
|
||||
class MOZ_STACK_CLASS AutoParentOpResult final
|
||||
{
|
||||
public:
|
||||
explicit AutoChildRequest(TypeUtils* aTypeUtils);
|
||||
~AutoChildRequest();
|
||||
|
||||
void Add(InternalRequest* aRequest, BodyAction aBodyAction,
|
||||
ReferrerAction aReferrerAction, SchemeAction aSchemeAction,
|
||||
ErrorResult& aRv);
|
||||
|
||||
const PCacheRequest& SendAsRequest();
|
||||
const PCacheRequestOrVoid& SendAsRequestOrVoid();
|
||||
|
||||
private:
|
||||
PCacheRequestOrVoid mRequestOrVoid;
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS AutoChildRequestList final : public AutoChildBase
|
||||
{
|
||||
public:
|
||||
AutoChildRequestList(TypeUtils* aTypeUtils, uint32_t aCapacity);
|
||||
~AutoChildRequestList();
|
||||
|
||||
void Add(InternalRequest* aRequest, BodyAction aBodyAction,
|
||||
ReferrerAction aReferrerAction, SchemeAction aSchemeAction,
|
||||
ErrorResult& aRv);
|
||||
|
||||
const nsTArray<PCacheRequest>& SendAsRequestList();
|
||||
|
||||
private:
|
||||
// Allocates ~5k inline in the stack-only class
|
||||
nsAutoTArray<PCacheRequest, 32> mRequestList;
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS AutoChildRequestResponse final : public AutoChildBase
|
||||
{
|
||||
public:
|
||||
explicit AutoChildRequestResponse(TypeUtils* aTypeUtils);
|
||||
~AutoChildRequestResponse();
|
||||
|
||||
void Add(InternalRequest* aRequest, BodyAction aBodyAction,
|
||||
ReferrerAction aReferrerAction, SchemeAction aSchemeAction,
|
||||
ErrorResult& aRv);
|
||||
void Add(Response& aResponse, ErrorResult& aRv);
|
||||
|
||||
const CacheRequestResponse& SendAsRequestResponse();
|
||||
|
||||
private:
|
||||
CacheRequestResponse mRequestResponse;
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS AutoParentBase
|
||||
{
|
||||
protected:
|
||||
explicit AutoParentBase(mozilla::ipc::PBackgroundParent* aManager);
|
||||
virtual ~AutoParentBase() = 0;
|
||||
|
||||
void SerializeReadStream(const nsID& aId, StreamList* aStreamList,
|
||||
PCacheReadStream* aReadStreamOut);
|
||||
|
||||
mozilla::ipc::PBackgroundParent* mManager;
|
||||
CacheStreamControlParent* mStreamControl;
|
||||
bool mSent;
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS AutoParentRequestList final : public AutoParentBase
|
||||
{
|
||||
public:
|
||||
AutoParentRequestList(mozilla::ipc::PBackgroundParent* aManager,
|
||||
uint32_t aCapacity);
|
||||
~AutoParentRequestList();
|
||||
AutoParentOpResult(mozilla::ipc::PBackgroundParent* aManager,
|
||||
const CacheOpResult& aOpResult);
|
||||
~AutoParentOpResult();
|
||||
|
||||
void Add(CacheId aOpenedCacheId, Manager* aManager);
|
||||
void Add(const SavedResponse& aSavedResponse, StreamList* aStreamList);
|
||||
void Add(const SavedRequest& aSavedRequest, StreamList* aStreamList);
|
||||
|
||||
const nsTArray<PCacheRequest>& SendAsRequestList();
|
||||
const CacheOpResult& SendAsOpResult();
|
||||
|
||||
private:
|
||||
// Allocates ~5k inline in the stack-only class
|
||||
nsAutoTArray<PCacheRequest, 32> mRequestList;
|
||||
};
|
||||
void SerializeResponseBody(const SavedResponse& aSavedResponse,
|
||||
StreamList* aStreamList,
|
||||
CacheResponse* aResponseOut);
|
||||
|
||||
class MOZ_STACK_CLASS AutoParentResponseList final : public AutoParentBase
|
||||
{
|
||||
public:
|
||||
AutoParentResponseList(mozilla::ipc::PBackgroundParent* aManager,
|
||||
uint32_t aCapacity);
|
||||
~AutoParentResponseList();
|
||||
void SerializeReadStream(const nsID& aId, StreamList* aStreamList,
|
||||
CacheReadStream* aReadStreamOut);
|
||||
|
||||
void Add(const SavedResponse& aSavedResponse, StreamList* aStreamList);
|
||||
|
||||
const nsTArray<PCacheResponse>& SendAsResponseList();
|
||||
|
||||
private:
|
||||
// Allocates ~4k inline in the stack-only class
|
||||
nsAutoTArray<PCacheResponse, 32> mResponseList;
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS AutoParentResponseOrVoid final : public AutoParentBase
|
||||
{
|
||||
public:
|
||||
explicit AutoParentResponseOrVoid(mozilla::ipc::PBackgroundParent* aManager);
|
||||
~AutoParentResponseOrVoid();
|
||||
|
||||
void Add(const SavedResponse& aSavedResponse, StreamList* aStreamList);
|
||||
|
||||
const PCacheResponseOrVoid& SendAsResponseOrVoid();
|
||||
|
||||
private:
|
||||
PCacheResponseOrVoid mResponseOrVoid;
|
||||
mozilla::ipc::PBackgroundParent* mManager;
|
||||
CacheOpResult mOpResult;
|
||||
CacheStreamControlParent* mStreamControl;
|
||||
bool mSent;
|
||||
};
|
||||
|
||||
} // namespace cache
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include "mozilla/dom/cache/CacheChild.h"
|
||||
#include "mozilla/dom/cache/CachePushStreamChild.h"
|
||||
#include "mozilla/dom/cache/ReadStream.h"
|
||||
#include "mozilla/dom/cache/TypeUtils.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/unused.h"
|
||||
|
@ -79,17 +78,7 @@ using mozilla::dom::workers::WorkerPrivate;
|
|||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(mozilla::dom::cache::Cache);
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(mozilla::dom::cache::Cache);
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(mozilla::dom::cache::Cache)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(mozilla::dom::cache::Cache)
|
||||
tmp->DisconnectFromActor();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mGlobal, mRequestPromises)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(mozilla::dom::cache::Cache)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobal, mRequestPromises)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(mozilla::dom::cache::Cache)
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(mozilla::dom::cache::Cache, mGlobal);
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Cache)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
|
@ -111,31 +100,22 @@ Cache::Match(const RequestOrUSVString& aRequest,
|
|||
{
|
||||
MOZ_ASSERT(mActor);
|
||||
|
||||
nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
|
||||
if (!promise) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<InternalRequest> ir = ToInternalRequest(aRequest, IgnoreBody, aRv);
|
||||
if (aRv.Failed()) {
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AutoChildRequest request(this);
|
||||
CacheQueryParams params;
|
||||
ToCacheQueryParams(params, aOptions);
|
||||
|
||||
request.Add(ir, IgnoreBody, PassThroughReferrer, IgnoreInvalidScheme, aRv);
|
||||
if (aRv.Failed()) {
|
||||
AutoChildOpArgs args(this, CacheMatchArgs(CacheRequest(), params));
|
||||
|
||||
args.Add(ir, IgnoreBody, PassThroughReferrer, IgnoreInvalidScheme, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PCacheQueryParams params;
|
||||
ToPCacheQueryParams(params, aOptions);
|
||||
|
||||
RequestId requestId = AddRequestPromise(promise, aRv);
|
||||
|
||||
unused << mActor->SendMatch(requestId, request.SendAsRequest(), params);
|
||||
|
||||
return promise.forget();
|
||||
return ExecuteOp(args, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
|
@ -144,12 +124,10 @@ Cache::MatchAll(const Optional<RequestOrUSVString>& aRequest,
|
|||
{
|
||||
MOZ_ASSERT(mActor);
|
||||
|
||||
nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
|
||||
if (!promise) {
|
||||
return nullptr;
|
||||
}
|
||||
CacheQueryParams params;
|
||||
ToCacheQueryParams(params, aOptions);
|
||||
|
||||
AutoChildRequest request(this);
|
||||
AutoChildOpArgs args(this, CacheMatchAllArgs(void_t(), params));
|
||||
|
||||
if (aRequest.WasPassed()) {
|
||||
nsRefPtr<InternalRequest> ir = ToInternalRequest(aRequest.Value(),
|
||||
|
@ -158,21 +136,13 @@ Cache::MatchAll(const Optional<RequestOrUSVString>& aRequest,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
request.Add(ir, IgnoreBody, PassThroughReferrer, IgnoreInvalidScheme, aRv);
|
||||
args.Add(ir, IgnoreBody, PassThroughReferrer, IgnoreInvalidScheme, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
PCacheQueryParams params;
|
||||
ToPCacheQueryParams(params, aOptions);
|
||||
|
||||
RequestId requestId = AddRequestPromise(promise, aRv);
|
||||
|
||||
unused << mActor->SendMatchAll(requestId, request.SendAsRequestOrVoid(),
|
||||
params);
|
||||
|
||||
return promise.forget();
|
||||
return ExecuteOp(args, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
|
@ -184,27 +154,19 @@ Cache::Add(const RequestOrUSVString& aRequest, ErrorResult& aRv)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
|
||||
if (!promise) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<InternalRequest> ir = ToInternalRequest(aRequest, ReadBody, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AutoChildRequestList requests(this, 1);
|
||||
requests.Add(ir, ReadBody, ExpandReferrer, NetworkErrorOnInvalidScheme, aRv);
|
||||
AutoChildOpArgs args(this, CacheAddAllArgs());
|
||||
|
||||
args.Add(ir, ReadBody, ExpandReferrer, NetworkErrorOnInvalidScheme, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RequestId requestId = AddRequestPromise(promise, aRv);
|
||||
|
||||
unused << mActor->SendAddAll(requestId, requests.SendAsRequestList());
|
||||
|
||||
return promise.forget();
|
||||
return ExecuteOp(args, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
|
@ -213,18 +175,18 @@ Cache::AddAll(const Sequence<OwningRequestOrUSVString>& aRequests,
|
|||
{
|
||||
MOZ_ASSERT(mActor);
|
||||
|
||||
nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
|
||||
if (!promise) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// If there is no work to do, then resolve immediately
|
||||
if (aRequests.IsEmpty()) {
|
||||
nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
|
||||
if (!promise) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
promise->MaybeResolve(JS::UndefinedHandleValue);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
AutoChildRequestList requests(this, aRequests.Length());
|
||||
AutoChildOpArgs args(this, CacheAddAllArgs());
|
||||
|
||||
for (uint32_t i = 0; i < aRequests.Length(); ++i) {
|
||||
if (!IsValidPutRequestMethod(aRequests[i], aRv)) {
|
||||
|
@ -237,18 +199,13 @@ Cache::AddAll(const Sequence<OwningRequestOrUSVString>& aRequests,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
requests.Add(ir, ReadBody, ExpandReferrer, NetworkErrorOnInvalidScheme,
|
||||
aRv);
|
||||
args.Add(ir, ReadBody, ExpandReferrer, NetworkErrorOnInvalidScheme, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
RequestId requestId = AddRequestPromise(promise, aRv);
|
||||
|
||||
unused << mActor->SendAddAll(requestId, requests.SendAsRequestList());
|
||||
|
||||
return promise.forget();
|
||||
return ExecuteOp(args, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
|
@ -261,32 +218,20 @@ Cache::Put(const RequestOrUSVString& aRequest, Response& aResponse,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
|
||||
if (!promise) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<InternalRequest> ir = ToInternalRequest(aRequest, ReadBody, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AutoChildRequestResponse put(this);
|
||||
put.Add(ir, ReadBody, PassThroughReferrer, TypeErrorOnInvalidScheme, aRv);
|
||||
AutoChildOpArgs args(this, CachePutAllArgs());
|
||||
|
||||
args.Add(ir, ReadBody, PassThroughReferrer, TypeErrorOnInvalidScheme,
|
||||
aResponse, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
put.Add(aResponse, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RequestId requestId = AddRequestPromise(promise, aRv);
|
||||
|
||||
unused << mActor->SendPut(requestId, put.SendAsRequestResponse());
|
||||
|
||||
return promise.forget();
|
||||
return ExecuteOp(args, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
|
@ -295,30 +240,22 @@ Cache::Delete(const RequestOrUSVString& aRequest,
|
|||
{
|
||||
MOZ_ASSERT(mActor);
|
||||
|
||||
nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
|
||||
if (!promise) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<InternalRequest> ir = ToInternalRequest(aRequest, IgnoreBody, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AutoChildRequest request(this);
|
||||
request.Add(ir, IgnoreBody, PassThroughReferrer, IgnoreInvalidScheme, aRv);
|
||||
CacheQueryParams params;
|
||||
ToCacheQueryParams(params, aOptions);
|
||||
|
||||
AutoChildOpArgs args(this, CacheDeleteArgs(CacheRequest(), params));
|
||||
|
||||
args.Add(ir, IgnoreBody, PassThroughReferrer, IgnoreInvalidScheme, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PCacheQueryParams params;
|
||||
ToPCacheQueryParams(params, aOptions);
|
||||
|
||||
RequestId requestId = AddRequestPromise(promise, aRv);
|
||||
|
||||
unused << mActor->SendDelete(requestId, request.SendAsRequest(), params);
|
||||
|
||||
return promise.forget();
|
||||
return ExecuteOp(args, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
|
@ -327,12 +264,10 @@ Cache::Keys(const Optional<RequestOrUSVString>& aRequest,
|
|||
{
|
||||
MOZ_ASSERT(mActor);
|
||||
|
||||
nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
|
||||
if (!promise) {
|
||||
return nullptr;
|
||||
}
|
||||
CacheQueryParams params;
|
||||
ToCacheQueryParams(params, aOptions);
|
||||
|
||||
AutoChildRequest request(this);
|
||||
AutoChildOpArgs args(this, CacheKeysArgs(void_t(), params));
|
||||
|
||||
if (aRequest.WasPassed()) {
|
||||
nsRefPtr<InternalRequest> ir = ToInternalRequest(aRequest.Value(),
|
||||
|
@ -341,20 +276,13 @@ Cache::Keys(const Optional<RequestOrUSVString>& aRequest,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
request.Add(ir, IgnoreBody, PassThroughReferrer, IgnoreInvalidScheme, aRv);
|
||||
args.Add(ir, IgnoreBody, PassThroughReferrer, IgnoreInvalidScheme, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
PCacheQueryParams params;
|
||||
ToPCacheQueryParams(params, aOptions);
|
||||
|
||||
RequestId requestId = AddRequestPromise(promise, aRv);
|
||||
|
||||
unused << mActor->SendKeys(requestId, request.SendAsRequestOrVoid(), params);
|
||||
|
||||
return promise.forget();
|
||||
return ExecuteOp(args, aRv);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -401,123 +329,6 @@ Cache::DestroyInternal(CacheChild* aActor)
|
|||
mActor = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
Cache::RecvMatchResponse(RequestId aRequestId, nsresult aRv,
|
||||
const PCacheResponseOrVoid& aResponse)
|
||||
{
|
||||
// Convert the response immediately if its present. This ensures that
|
||||
// any stream actors are cleaned up, even if we error out below.
|
||||
nsRefPtr<Response> response;
|
||||
if (aResponse.type() == PCacheResponseOrVoid::TPCacheResponse) {
|
||||
response = ToResponse(aResponse);
|
||||
}
|
||||
|
||||
nsRefPtr<Promise> promise = RemoveRequestPromise(aRequestId);
|
||||
|
||||
if (NS_FAILED(aRv)) {
|
||||
promise->MaybeReject(aRv);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!response) {
|
||||
promise->MaybeResolve(JS::UndefinedHandleValue);
|
||||
return;
|
||||
}
|
||||
|
||||
promise->MaybeResolve(response);
|
||||
}
|
||||
|
||||
void
|
||||
Cache::RecvMatchAllResponse(RequestId aRequestId, nsresult aRv,
|
||||
const nsTArray<PCacheResponse>& aResponses)
|
||||
{
|
||||
// Convert responses immediately. This ensures that any stream actors are
|
||||
// cleaned up, even if we error out below.
|
||||
nsAutoTArray<nsRefPtr<Response>, 256> responses;
|
||||
responses.SetCapacity(aResponses.Length());
|
||||
|
||||
for (uint32_t i = 0; i < aResponses.Length(); ++i) {
|
||||
nsRefPtr<Response> response = ToResponse(aResponses[i]);
|
||||
responses.AppendElement(response.forget());
|
||||
}
|
||||
|
||||
nsRefPtr<Promise> promise = RemoveRequestPromise(aRequestId);
|
||||
|
||||
if (NS_FAILED(aRv)) {
|
||||
promise->MaybeReject(aRv);
|
||||
return;
|
||||
}
|
||||
|
||||
promise->MaybeResolve(responses);
|
||||
}
|
||||
|
||||
void
|
||||
Cache::RecvAddAllResponse(RequestId aRequestId,
|
||||
const mozilla::ErrorResult& aError)
|
||||
{
|
||||
nsRefPtr<Promise> promise = RemoveRequestPromise(aRequestId);
|
||||
|
||||
if (aError.Failed()) {
|
||||
// TODO: Remove this const_cast (bug 1152078).
|
||||
// It is safe for now since this ErrorResult is handed off to us by IPDL
|
||||
// and is thrown into the trash afterwards.
|
||||
promise->MaybeReject(const_cast<ErrorResult&>(aError));
|
||||
return;
|
||||
}
|
||||
|
||||
promise->MaybeResolve(JS::UndefinedHandleValue);
|
||||
}
|
||||
|
||||
void
|
||||
Cache::RecvPutResponse(RequestId aRequestId, nsresult aRv)
|
||||
{
|
||||
nsRefPtr<Promise> promise = RemoveRequestPromise(aRequestId);
|
||||
|
||||
if (NS_FAILED(aRv)) {
|
||||
promise->MaybeReject(aRv);
|
||||
return;
|
||||
}
|
||||
|
||||
promise->MaybeResolve(JS::UndefinedHandleValue);
|
||||
}
|
||||
|
||||
void
|
||||
Cache::RecvDeleteResponse(RequestId aRequestId, nsresult aRv, bool aSuccess)
|
||||
{
|
||||
nsRefPtr<Promise> promise = RemoveRequestPromise(aRequestId);
|
||||
|
||||
if (NS_FAILED(aRv)) {
|
||||
promise->MaybeReject(aRv);
|
||||
return;
|
||||
}
|
||||
|
||||
promise->MaybeResolve(aSuccess);
|
||||
}
|
||||
|
||||
void
|
||||
Cache::RecvKeysResponse(RequestId aRequestId, nsresult aRv,
|
||||
const nsTArray<PCacheRequest>& aRequests)
|
||||
{
|
||||
// Convert requests immediately. This ensures that any stream actors are
|
||||
// cleaned up, even if we error out below.
|
||||
nsAutoTArray<nsRefPtr<Request>, 256> requests;
|
||||
requests.SetCapacity(aRequests.Length());
|
||||
|
||||
for (uint32_t i = 0; i < aRequests.Length(); ++i) {
|
||||
nsRefPtr<Request> request = ToRequest(aRequests[i]);
|
||||
requests.AppendElement(request.forget());
|
||||
}
|
||||
|
||||
nsRefPtr<Promise> promise = RemoveRequestPromise(aRequestId);
|
||||
|
||||
if (NS_FAILED(aRv)) {
|
||||
promise->MaybeReject(aRv);
|
||||
return;
|
||||
}
|
||||
|
||||
promise->MaybeResolve(requests);
|
||||
}
|
||||
|
||||
nsIGlobalObject*
|
||||
Cache::GetGlobalObject() const
|
||||
{
|
||||
|
@ -538,36 +349,12 @@ Cache::CreatePushStream(nsIAsyncInputStream* aStream)
|
|||
NS_ASSERT_OWNINGTHREAD(Cache);
|
||||
MOZ_ASSERT(mActor);
|
||||
MOZ_ASSERT(aStream);
|
||||
auto actor = mActor->SendPCachePushStreamConstructor(
|
||||
new CachePushStreamChild(mActor->GetFeature(), aStream));
|
||||
MOZ_ASSERT(actor);
|
||||
return static_cast<CachePushStreamChild*>(actor);
|
||||
}
|
||||
|
||||
void
|
||||
Cache::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
|
||||
{
|
||||
// Do nothing. The Promise will automatically drop the ref to us after
|
||||
// calling the callback. This is what we want as we only registered in order
|
||||
// to be held alive via the Promise handle.
|
||||
}
|
||||
|
||||
void
|
||||
Cache::RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
|
||||
{
|
||||
// Do nothing. The Promise will automatically drop the ref to us after
|
||||
// calling the callback. This is what we want as we only registered in order
|
||||
// to be held alive via the Promise handle.
|
||||
return mActor->CreatePushStream(aStream);
|
||||
}
|
||||
|
||||
Cache::~Cache()
|
||||
{
|
||||
DisconnectFromActor();
|
||||
}
|
||||
|
||||
void
|
||||
Cache::DisconnectFromActor()
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(Cache);
|
||||
if (mActor) {
|
||||
mActor->StartDestroy();
|
||||
// DestroyInternal() is called synchronously by StartDestroy(). So we
|
||||
|
@ -576,43 +363,16 @@ Cache::DisconnectFromActor()
|
|||
}
|
||||
}
|
||||
|
||||
RequestId
|
||||
Cache::AddRequestPromise(Promise* aPromise, ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aPromise);
|
||||
MOZ_ASSERT(!mRequestPromises.Contains(aPromise));
|
||||
|
||||
// Register ourself as a promise handler so that the promise will hold us
|
||||
// alive. This allows the client code to drop the ref to the Cache
|
||||
// object and just keep their promise. This is fairly common in promise
|
||||
// chaining code.
|
||||
aPromise->AppendNativeHandler(this);
|
||||
|
||||
mRequestPromises.AppendElement(aPromise);
|
||||
|
||||
// (Ab)use the promise pointer as our request ID. This is a fast, thread-safe
|
||||
// way to get a unique ID for the promise to be resolved later.
|
||||
return reinterpret_cast<RequestId>(aPromise);
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
Cache::RemoveRequestPromise(RequestId aRequestId)
|
||||
Cache::ExecuteOp(AutoChildOpArgs& aOpArgs, ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aRequestId != INVALID_REQUEST_ID);
|
||||
|
||||
for (uint32_t i = 0; i < mRequestPromises.Length(); ++i) {
|
||||
nsRefPtr<Promise>& promise = mRequestPromises.ElementAt(i);
|
||||
// To be safe, only cast promise pointers to our integer RequestId
|
||||
// type and never cast an integer to a pointer.
|
||||
if (aRequestId == reinterpret_cast<RequestId>(promise.get())) {
|
||||
nsRefPtr<Promise> ref;
|
||||
ref.swap(promise);
|
||||
mRequestPromises.RemoveElementAt(i);
|
||||
return ref.forget();
|
||||
}
|
||||
nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
|
||||
if (!promise) {
|
||||
return nullptr;
|
||||
}
|
||||
MOZ_ASSERT_UNREACHABLE("Received response without a matching promise!");
|
||||
return nullptr;
|
||||
|
||||
mActor->ExecuteOp(mGlobal, promise, aOpArgs.SendAsOpArgs());
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
} // namespace cache
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#ifndef mozilla_dom_cache_Cache_h
|
||||
#define mozilla_dom_cache_Cache_h
|
||||
|
||||
#include "mozilla/dom/PromiseNativeHandler.h"
|
||||
#include "mozilla/dom/cache/Types.h"
|
||||
#include "mozilla/dom/cache/TypeUtils.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
@ -33,12 +32,10 @@ template<typename T> class Sequence;
|
|||
|
||||
namespace cache {
|
||||
|
||||
class AutoChildOpArgs;
|
||||
class CacheChild;
|
||||
class PCacheRequest;
|
||||
class PCacheResponse;
|
||||
class PCacheResponseOrVoid;
|
||||
|
||||
class Cache final : public PromiseNativeHandler
|
||||
class Cache final : public nsISupports
|
||||
, public nsWrapperCache
|
||||
, public TypeUtils
|
||||
{
|
||||
|
@ -76,20 +73,6 @@ public:
|
|||
// Called when CacheChild actor is being destroyed
|
||||
void DestroyInternal(CacheChild* aActor);
|
||||
|
||||
// methods forwarded from CacheChild
|
||||
void RecvMatchResponse(RequestId aRequestId, nsresult aRv,
|
||||
const PCacheResponseOrVoid& aResponse);
|
||||
void RecvMatchAllResponse(RequestId aRequestId, nsresult aRv,
|
||||
const nsTArray<PCacheResponse>& aResponses);
|
||||
void RecvAddAllResponse(RequestId aRequestId,
|
||||
const mozilla::ErrorResult& aError);
|
||||
void RecvPutResponse(RequestId aRequestId, nsresult aRv);
|
||||
|
||||
void RecvDeleteResponse(RequestId aRequestId, nsresult aRv,
|
||||
bool aSuccess);
|
||||
void RecvKeysResponse(RequestId aRequestId, nsresult aRv,
|
||||
const nsTArray<PCacheRequest>& aRequests);
|
||||
|
||||
// TypeUtils methods
|
||||
virtual nsIGlobalObject*
|
||||
GetGlobalObject() const override;
|
||||
|
@ -101,26 +84,17 @@ public:
|
|||
virtual CachePushStreamChild*
|
||||
CreatePushStream(nsIAsyncInputStream* aStream) override;
|
||||
|
||||
// PromiseNativeHandler methods
|
||||
virtual void
|
||||
ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override;
|
||||
|
||||
virtual void
|
||||
RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override;
|
||||
|
||||
private:
|
||||
~Cache();
|
||||
|
||||
// Called when we're destroyed or CCed.
|
||||
void DisconnectFromActor();
|
||||
|
||||
// TODO: Replace with actor-per-request model during refactor (bug 1110485)
|
||||
RequestId AddRequestPromise(Promise* aPromise, ErrorResult& aRv);
|
||||
already_AddRefed<Promise> RemoveRequestPromise(RequestId aRequestId);
|
||||
already_AddRefed<Promise>
|
||||
ExecuteOp(AutoChildOpArgs& aOpArgs, ErrorResult& aRv);
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> mGlobal;
|
||||
CacheChild* mActor;
|
||||
nsTArray<nsRefPtr<Promise>> mRequestPromises;
|
||||
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
#include "mozilla/unused.h"
|
||||
#include "mozilla/dom/cache/ActorUtils.h"
|
||||
#include "mozilla/dom/cache/Cache.h"
|
||||
#include "mozilla/dom/cache/PCachePushStreamChild.h"
|
||||
#include "mozilla/dom/cache/StreamUtils.h"
|
||||
#include "mozilla/dom/cache/CacheOpChild.h"
|
||||
#include "mozilla/dom/cache/CachePushStreamChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -32,6 +32,7 @@ DeallocPCacheChild(PCacheChild* aActor)
|
|||
|
||||
CacheChild::CacheChild()
|
||||
: mListener(nullptr)
|
||||
, mNumChildActors(0)
|
||||
{
|
||||
MOZ_COUNT_CTOR(cache::CacheChild);
|
||||
}
|
||||
|
@ -41,6 +42,7 @@ CacheChild::~CacheChild()
|
|||
MOZ_COUNT_DTOR(cache::CacheChild);
|
||||
NS_ASSERT_OWNINGTHREAD(CacheChild);
|
||||
MOZ_ASSERT(!mListener);
|
||||
MOZ_ASSERT(!mNumChildActors);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -60,6 +62,25 @@ CacheChild::ClearListener()
|
|||
mListener = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
CacheChild::ExecuteOp(nsIGlobalObject* aGlobal, Promise* aPromise,
|
||||
const CacheOpArgs& aArgs)
|
||||
{
|
||||
mNumChildActors += 1;
|
||||
MOZ_ALWAYS_TRUE(SendPCacheOpConstructor(
|
||||
new CacheOpChild(GetFeature(), aGlobal, aPromise), aArgs));
|
||||
}
|
||||
|
||||
CachePushStreamChild*
|
||||
CacheChild::CreatePushStream(nsIAsyncInputStream* aStream)
|
||||
{
|
||||
mNumChildActors += 1;
|
||||
auto actor = SendPCachePushStreamConstructor(
|
||||
new CachePushStreamChild(GetFeature(), aStream));
|
||||
MOZ_ASSERT(actor);
|
||||
return static_cast<CachePushStreamChild*>(actor);
|
||||
}
|
||||
|
||||
void
|
||||
CacheChild::StartDestroy()
|
||||
{
|
||||
|
@ -77,6 +98,14 @@ CacheChild::StartDestroy()
|
|||
// Cache listener should call ClearListener() in DestroyInternal()
|
||||
MOZ_ASSERT(!mListener);
|
||||
|
||||
// If we have outstanding child actors, then don't destroy ourself yet.
|
||||
// The child actors should be short lived and we should allow them to complete
|
||||
// if possible. SendTeardown() will be called when the count drops to zero
|
||||
// in NoteDeletedActor().
|
||||
if (mNumChildActors) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Start actor destruction from parent process
|
||||
unused << SendTeardown();
|
||||
}
|
||||
|
@ -95,6 +124,21 @@ CacheChild::ActorDestroy(ActorDestroyReason aReason)
|
|||
RemoveFeature();
|
||||
}
|
||||
|
||||
PCacheOpChild*
|
||||
CacheChild::AllocPCacheOpChild(const CacheOpArgs& aOpArgs)
|
||||
{
|
||||
MOZ_CRASH("CacheOpChild should be manually constructed.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheChild::DeallocPCacheOpChild(PCacheOpChild* aActor)
|
||||
{
|
||||
delete aActor;
|
||||
NoteDeletedActor();
|
||||
return true;
|
||||
}
|
||||
|
||||
PCachePushStreamChild*
|
||||
CacheChild::AllocPCachePushStreamChild()
|
||||
{
|
||||
|
@ -106,96 +150,17 @@ bool
|
|||
CacheChild::DeallocPCachePushStreamChild(PCachePushStreamChild* aActor)
|
||||
{
|
||||
delete aActor;
|
||||
NoteDeletedActor();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheChild::RecvMatchResponse(const RequestId& requestId, const nsresult& aRv,
|
||||
const PCacheResponseOrVoid& aResponse)
|
||||
void
|
||||
CacheChild::NoteDeletedActor()
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheChild);
|
||||
|
||||
AddFeatureToStreamChild(aResponse, GetFeature());
|
||||
|
||||
nsRefPtr<Cache> listener = mListener;
|
||||
if (!listener) {
|
||||
StartDestroyStreamChild(aResponse);
|
||||
return true;
|
||||
mNumChildActors -= 1;
|
||||
if (!mNumChildActors && !mListener) {
|
||||
unused << SendTeardown();
|
||||
}
|
||||
|
||||
listener->RecvMatchResponse(requestId, aRv, aResponse);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheChild::RecvMatchAllResponse(const RequestId& requestId, const nsresult& aRv,
|
||||
nsTArray<PCacheResponse>&& aResponses)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheChild);
|
||||
|
||||
AddFeatureToStreamChild(aResponses, GetFeature());
|
||||
|
||||
nsRefPtr<Cache> listener = mListener;
|
||||
if (!listener) {
|
||||
StartDestroyStreamChild(aResponses);
|
||||
return true;
|
||||
}
|
||||
|
||||
listener->RecvMatchAllResponse(requestId, aRv, aResponses);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheChild::RecvAddAllResponse(const RequestId& requestId,
|
||||
const mozilla::ErrorResult& aError)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheChild);
|
||||
nsRefPtr<Cache> listener = mListener;
|
||||
if (listener) {
|
||||
listener->RecvAddAllResponse(requestId, aError);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheChild::RecvPutResponse(const RequestId& aRequestId, const nsresult& aRv)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheChild);
|
||||
nsRefPtr<Cache> listener = mListener;
|
||||
if (listener) {
|
||||
listener->RecvPutResponse(aRequestId, aRv);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheChild::RecvDeleteResponse(const RequestId& requestId, const nsresult& aRv,
|
||||
const bool& result)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheChild);
|
||||
nsRefPtr<Cache> listener = mListener;
|
||||
if (listener) {
|
||||
listener->RecvDeleteResponse(requestId, aRv, result);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheChild::RecvKeysResponse(const RequestId& requestId, const nsresult& aRv,
|
||||
nsTArray<PCacheRequest>&& aRequests)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheChild);
|
||||
|
||||
AddFeatureToStreamChild(aRequests, GetFeature());
|
||||
|
||||
nsRefPtr<Cache> listener = mListener;
|
||||
if (!listener) {
|
||||
StartDestroyStreamChild(aRequests);
|
||||
return true;
|
||||
}
|
||||
|
||||
listener->RecvKeysResponse(requestId, aRv, aRequests);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace cache
|
||||
|
|
|
@ -10,11 +10,19 @@
|
|||
#include "mozilla/dom/cache/ActorChild.h"
|
||||
#include "mozilla/dom/cache/PCacheChild.h"
|
||||
|
||||
class nsIAsyncInputStream;
|
||||
class nsIGlobalObject;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class Promise;
|
||||
|
||||
namespace cache {
|
||||
|
||||
class Cache;
|
||||
class CacheOpArgs;
|
||||
class CachePushStreamChild;
|
||||
|
||||
class CacheChild final : public PCacheChild
|
||||
, public ActorChild
|
||||
|
@ -30,6 +38,13 @@ public:
|
|||
// trigger ActorDestroy() if it has not been called yet.
|
||||
void ClearListener();
|
||||
|
||||
void
|
||||
ExecuteOp(nsIGlobalObject* aGlobal, Promise* aPromise,
|
||||
const CacheOpArgs& aArgs);
|
||||
|
||||
CachePushStreamChild*
|
||||
CreatePushStream(nsIAsyncInputStream* aStream);
|
||||
|
||||
// ActorChild methods
|
||||
|
||||
// Synchronously call ActorDestroy on our Cache listener and then start the
|
||||
|
@ -41,35 +56,27 @@ private:
|
|||
virtual void
|
||||
ActorDestroy(ActorDestroyReason aReason) override;
|
||||
|
||||
virtual PCacheOpChild*
|
||||
AllocPCacheOpChild(const CacheOpArgs& aOpArgs) override;
|
||||
|
||||
virtual bool
|
||||
DeallocPCacheOpChild(PCacheOpChild* aActor) override;
|
||||
|
||||
virtual PCachePushStreamChild*
|
||||
AllocPCachePushStreamChild() override;
|
||||
|
||||
virtual bool
|
||||
DeallocPCachePushStreamChild(PCachePushStreamChild* aActor) override;
|
||||
|
||||
virtual bool
|
||||
RecvMatchResponse(const RequestId& requestId, const nsresult& aRv,
|
||||
const PCacheResponseOrVoid& aResponse) override;
|
||||
virtual bool
|
||||
RecvMatchAllResponse(const RequestId& requestId, const nsresult& aRv,
|
||||
nsTArray<PCacheResponse>&& responses) override;
|
||||
virtual bool
|
||||
RecvAddAllResponse(const RequestId& requestId,
|
||||
const mozilla::ErrorResult& aError) override;
|
||||
virtual bool
|
||||
RecvPutResponse(const RequestId& aRequestId,
|
||||
const nsresult& aRv) override;
|
||||
virtual bool
|
||||
RecvDeleteResponse(const RequestId& requestId, const nsresult& aRv,
|
||||
const bool& result) override;
|
||||
virtual bool
|
||||
RecvKeysResponse(const RequestId& requestId, const nsresult& aRv,
|
||||
nsTArray<PCacheRequest>&& requests) override;
|
||||
// utility methods
|
||||
void
|
||||
NoteDeletedActor();
|
||||
|
||||
// Use a weak ref so actor does not hold DOM object alive past content use.
|
||||
// The Cache object must call ClearListener() to null this before its
|
||||
// destroyed.
|
||||
Cache* MOZ_NON_OWNING_REF mListener;
|
||||
uint32_t mNumChildActors;
|
||||
|
||||
NS_DECL_OWNINGTHREAD
|
||||
};
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include PBackgroundSharedTypes;
|
||||
|
||||
using mozilla::dom::cache::Namespace from "mozilla/dom/cache/Types.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
// Data needed to initialize a CacheStorage or Cache backend. Don't put
|
||||
// this with the other types in PCacheTypes.ipdlh since we want to import
|
||||
// it into PBackground.ipdl.
|
||||
struct CacheInitData
|
||||
{
|
||||
Namespace namespaceEnum;
|
||||
PrincipalInfo principalInfo;
|
||||
};
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,248 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/cache/CacheOpChild.h"
|
||||
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/Request.h"
|
||||
#include "mozilla/dom/Response.h"
|
||||
#include "mozilla/dom/cache/Cache.h"
|
||||
#include "mozilla/dom/cache/CacheChild.h"
|
||||
#include "mozilla/dom/cache/CacheStreamControlChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
namespace {
|
||||
|
||||
void
|
||||
AddFeatureToStreamChild(const CacheReadStream& aReadStream, Feature* aFeature)
|
||||
{
|
||||
MOZ_ASSERT_IF(!NS_IsMainThread(), aFeature);
|
||||
CacheStreamControlChild* cacheControl =
|
||||
static_cast<CacheStreamControlChild*>(aReadStream.controlChild());
|
||||
if (cacheControl) {
|
||||
cacheControl->SetFeature(aFeature);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AddFeatureToStreamChild(const CacheResponse& aResponse, Feature* aFeature)
|
||||
{
|
||||
MOZ_ASSERT_IF(!NS_IsMainThread(), aFeature);
|
||||
|
||||
if (aResponse.body().type() == CacheReadStreamOrVoid::Tvoid_t) {
|
||||
return;
|
||||
}
|
||||
|
||||
AddFeatureToStreamChild(aResponse.body().get_CacheReadStream(), aFeature);
|
||||
}
|
||||
|
||||
void
|
||||
AddFeatureToStreamChild(const CacheRequest& aRequest, Feature* aFeature)
|
||||
{
|
||||
MOZ_ASSERT_IF(!NS_IsMainThread(), aFeature);
|
||||
|
||||
if (aRequest.body().type() == CacheReadStreamOrVoid::Tvoid_t) {
|
||||
return;
|
||||
}
|
||||
|
||||
AddFeatureToStreamChild(aRequest.body().get_CacheReadStream(), aFeature);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
CacheOpChild::CacheOpChild(Feature* aFeature, nsIGlobalObject* aGlobal,
|
||||
Promise* aPromise)
|
||||
: mGlobal(aGlobal)
|
||||
, mPromise(aPromise)
|
||||
{
|
||||
MOZ_ASSERT(mGlobal);
|
||||
MOZ_ASSERT(mPromise);
|
||||
|
||||
MOZ_ASSERT_IF(!NS_IsMainThread(), aFeature);
|
||||
SetFeature(aFeature);
|
||||
}
|
||||
|
||||
CacheOpChild::~CacheOpChild()
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheOpChild);
|
||||
MOZ_ASSERT(!mPromise);
|
||||
}
|
||||
|
||||
void
|
||||
CacheOpChild::ActorDestroy(ActorDestroyReason aReason)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheOpChild);
|
||||
|
||||
// If the actor was terminated for some unknown reason, then indicate the
|
||||
// operation is dead.
|
||||
if (mPromise) {
|
||||
mPromise->MaybeReject(NS_ERROR_FAILURE);
|
||||
mPromise = nullptr;
|
||||
}
|
||||
|
||||
RemoveFeature();
|
||||
}
|
||||
|
||||
bool
|
||||
CacheOpChild::Recv__delete__(const ErrorResult& aRv,
|
||||
const CacheOpResult& aResult)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheOpChild);
|
||||
|
||||
if (aRv.Failed()) {
|
||||
MOZ_ASSERT(aResult.type() == CacheOpResult::Tvoid_t);
|
||||
// TODO: Remove this const_cast (bug 1152078).
|
||||
// It is safe for now since this ErrorResult is handed off to us by IPDL
|
||||
// and is thrown into the trash afterwards.
|
||||
mPromise->MaybeReject(const_cast<ErrorResult&>(aRv));
|
||||
mPromise = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (aResult.type()) {
|
||||
case CacheOpResult::TCacheMatchResult:
|
||||
{
|
||||
HandleResponse(aResult.get_CacheMatchResult().responseOrVoid());
|
||||
break;
|
||||
}
|
||||
case CacheOpResult::TCacheMatchAllResult:
|
||||
{
|
||||
HandleResponseList(aResult.get_CacheMatchAllResult().responseList());
|
||||
break;
|
||||
}
|
||||
case CacheOpResult::TCacheAddAllResult:
|
||||
case CacheOpResult::TCachePutAllResult:
|
||||
{
|
||||
mPromise->MaybeResolve(JS::UndefinedHandleValue);
|
||||
break;
|
||||
}
|
||||
case CacheOpResult::TCacheDeleteResult:
|
||||
{
|
||||
mPromise->MaybeResolve(aResult.get_CacheDeleteResult().success());
|
||||
break;
|
||||
}
|
||||
case CacheOpResult::TCacheKeysResult:
|
||||
{
|
||||
HandleRequestList(aResult.get_CacheKeysResult().requestList());
|
||||
break;
|
||||
}
|
||||
case CacheOpResult::TStorageMatchResult:
|
||||
{
|
||||
HandleResponse(aResult.get_StorageMatchResult().responseOrVoid());
|
||||
break;
|
||||
}
|
||||
case CacheOpResult::TStorageHasResult:
|
||||
{
|
||||
mPromise->MaybeResolve(aResult.get_StorageHasResult().success());
|
||||
break;
|
||||
}
|
||||
case CacheOpResult::TStorageOpenResult:
|
||||
{
|
||||
auto actor = static_cast<CacheChild*>(
|
||||
aResult.get_StorageOpenResult().actorChild());
|
||||
actor->SetFeature(GetFeature());
|
||||
nsRefPtr<Cache> cache = new Cache(mGlobal, actor);
|
||||
mPromise->MaybeResolve(cache);
|
||||
break;
|
||||
}
|
||||
case CacheOpResult::TStorageDeleteResult:
|
||||
{
|
||||
mPromise->MaybeResolve(aResult.get_StorageDeleteResult().success());
|
||||
break;
|
||||
}
|
||||
case CacheOpResult::TStorageKeysResult:
|
||||
{
|
||||
mPromise->MaybeResolve(aResult.get_StorageKeysResult().keyList());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MOZ_CRASH("Unknown Cache op result type!");
|
||||
}
|
||||
|
||||
mPromise = nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CacheOpChild::StartDestroy()
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheOpChild);
|
||||
|
||||
// Do not cancel on-going operations when Feature calls this. Instead, keep
|
||||
// the Worker alive until we are done.
|
||||
}
|
||||
|
||||
nsIGlobalObject*
|
||||
CacheOpChild::GetGlobalObject() const
|
||||
{
|
||||
return mGlobal;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
CacheOpChild::AssertOwningThread() const
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheOpChild);
|
||||
}
|
||||
#endif
|
||||
|
||||
CachePushStreamChild*
|
||||
CacheOpChild::CreatePushStream(nsIAsyncInputStream* aStream)
|
||||
{
|
||||
MOZ_CRASH("CacheOpChild should never create a push stream actor!");
|
||||
}
|
||||
|
||||
void
|
||||
CacheOpChild::HandleResponse(const CacheResponseOrVoid& aResponseOrVoid)
|
||||
{
|
||||
if (aResponseOrVoid.type() == CacheResponseOrVoid::Tvoid_t) {
|
||||
mPromise->MaybeResolve(JS::UndefinedHandleValue);
|
||||
return;
|
||||
}
|
||||
|
||||
const CacheResponse& cacheResponse = aResponseOrVoid.get_CacheResponse();
|
||||
|
||||
AddFeatureToStreamChild(cacheResponse, GetFeature());
|
||||
nsRefPtr<Response> response = ToResponse(cacheResponse);
|
||||
|
||||
mPromise->MaybeResolve(response);
|
||||
}
|
||||
|
||||
void
|
||||
CacheOpChild::HandleResponseList(const nsTArray<CacheResponse>& aResponseList)
|
||||
{
|
||||
nsAutoTArray<nsRefPtr<Response>, 256> responses;
|
||||
responses.SetCapacity(aResponseList.Length());
|
||||
|
||||
for (uint32_t i = 0; i < aResponseList.Length(); ++i) {
|
||||
AddFeatureToStreamChild(aResponseList[i], GetFeature());
|
||||
responses.AppendElement(ToResponse(aResponseList[i]));
|
||||
}
|
||||
|
||||
mPromise->MaybeResolve(responses);
|
||||
}
|
||||
|
||||
void
|
||||
CacheOpChild::HandleRequestList(const nsTArray<CacheRequest>& aRequestList)
|
||||
{
|
||||
nsAutoTArray<nsRefPtr<Request>, 256> requests;
|
||||
requests.SetCapacity(aRequestList.Length());
|
||||
|
||||
for (uint32_t i = 0; i < aRequestList.Length(); ++i) {
|
||||
AddFeatureToStreamChild(aRequestList[i], GetFeature());
|
||||
requests.AppendElement(ToRequest(aRequestList[i]));
|
||||
}
|
||||
|
||||
mPromise->MaybeResolve(requests);
|
||||
}
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,80 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_cache_CacheOpChild_h
|
||||
#define mozilla_dom_cache_CacheOpChild_h
|
||||
|
||||
#include "mozilla/dom/cache/ActorChild.h"
|
||||
#include "mozilla/dom/cache/PCacheOpChild.h"
|
||||
#include "mozilla/dom/cache/TypeUtils.h"
|
||||
#include "nsRefPtr.h"
|
||||
|
||||
class nsIGlobalObject;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class Promise;
|
||||
|
||||
namespace cache {
|
||||
|
||||
class CacheOpChild final : public PCacheOpChild
|
||||
, public ActorChild
|
||||
, public TypeUtils
|
||||
{
|
||||
friend class CacheChild;
|
||||
friend class CacheStorageChild;
|
||||
|
||||
private:
|
||||
// This class must be constructed by CacheChild or CacheStorageChild using
|
||||
// their ExecuteOp() factory method.
|
||||
CacheOpChild(Feature* aFeature, nsIGlobalObject* aGlobal, Promise* aPromise);
|
||||
~CacheOpChild();
|
||||
|
||||
// PCacheOpChild methods
|
||||
virtual void
|
||||
ActorDestroy(ActorDestroyReason aReason) override;
|
||||
|
||||
virtual bool
|
||||
Recv__delete__(const ErrorResult& aRv, const CacheOpResult& aResult) override;
|
||||
|
||||
// ActorChild methods
|
||||
virtual void
|
||||
StartDestroy() override;
|
||||
|
||||
// TypeUtils methods
|
||||
virtual nsIGlobalObject*
|
||||
GetGlobalObject() const override;
|
||||
|
||||
#ifdef DEBUG
|
||||
virtual void
|
||||
AssertOwningThread() const override;
|
||||
#endif
|
||||
|
||||
virtual CachePushStreamChild*
|
||||
CreatePushStream(nsIAsyncInputStream* aStream) override;
|
||||
|
||||
// Utility methods
|
||||
void
|
||||
HandleResponse(const CacheResponseOrVoid& aResponseOrVoid);
|
||||
|
||||
void
|
||||
HandleResponseList(const nsTArray<CacheResponse>& aResponseList);
|
||||
|
||||
void
|
||||
HandleRequestList(const nsTArray<CacheRequest>& aRequestList);
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> mGlobal;
|
||||
nsRefPtr<Promise> mPromise;
|
||||
|
||||
NS_DECL_OWNINGTHREAD
|
||||
};
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_cache_CacheOpChild_h
|
|
@ -0,0 +1,287 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/cache/CacheOpParent.h"
|
||||
|
||||
#include "mozilla/unused.h"
|
||||
#include "mozilla/dom/cache/AutoUtils.h"
|
||||
#include "mozilla/dom/cache/CachePushStreamParent.h"
|
||||
#include "mozilla/dom/cache/ReadStream.h"
|
||||
#include "mozilla/dom/cache/SavedTypes.h"
|
||||
#include "mozilla/ipc/FileDescriptorSetParent.h"
|
||||
#include "mozilla/ipc/InputStreamUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
using mozilla::ipc::FileDescriptorSetParent;
|
||||
using mozilla::ipc::PBackgroundParent;
|
||||
|
||||
CacheOpParent::CacheOpParent(PBackgroundParent* aIpcManager, CacheId aCacheId,
|
||||
const CacheOpArgs& aOpArgs)
|
||||
: mIpcManager(aIpcManager)
|
||||
, mCacheId(aCacheId)
|
||||
, mNamespace(INVALID_NAMESPACE)
|
||||
, mOpArgs(aOpArgs)
|
||||
{
|
||||
MOZ_ASSERT(mIpcManager);
|
||||
}
|
||||
|
||||
CacheOpParent::CacheOpParent(PBackgroundParent* aIpcManager,
|
||||
Namespace aNamespace, const CacheOpArgs& aOpArgs)
|
||||
: mIpcManager(aIpcManager)
|
||||
, mCacheId(INVALID_CACHE_ID)
|
||||
, mNamespace(aNamespace)
|
||||
, mOpArgs(aOpArgs)
|
||||
{
|
||||
MOZ_ASSERT(mIpcManager);
|
||||
}
|
||||
|
||||
CacheOpParent::~CacheOpParent()
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheOpParent);
|
||||
}
|
||||
|
||||
void
|
||||
CacheOpParent::Execute(ManagerId* aManagerId)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheOpParent);
|
||||
MOZ_ASSERT(!mManager);
|
||||
MOZ_ASSERT(!mVerifier);
|
||||
|
||||
nsRefPtr<Manager> manager;
|
||||
nsresult rv = Manager::GetOrCreate(aManagerId, getter_AddRefs(manager));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
unused << Send__delete__(this, ErrorResult(rv), void_t());
|
||||
return;
|
||||
}
|
||||
|
||||
Execute(manager);
|
||||
}
|
||||
|
||||
void
|
||||
CacheOpParent::Execute(Manager* aManager)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheOpParent);
|
||||
MOZ_ASSERT(!mManager);
|
||||
MOZ_ASSERT(!mVerifier);
|
||||
|
||||
mManager = aManager;
|
||||
|
||||
// Handle add/addAll op with a FetchPut object
|
||||
if (mOpArgs.type() == CacheOpArgs::TCacheAddAllArgs) {
|
||||
MOZ_ASSERT(mCacheId != INVALID_CACHE_ID);
|
||||
|
||||
const CacheAddAllArgs& args = mOpArgs.get_CacheAddAllArgs();
|
||||
const nsTArray<CacheRequest>& list = args.requestList();
|
||||
|
||||
nsAutoTArray<nsCOMPtr<nsIInputStream>, 256> requestStreamList;
|
||||
for (uint32_t i = 0; i < list.Length(); ++i) {
|
||||
requestStreamList.AppendElement(DeserializeCacheStream(list[i].body()));
|
||||
}
|
||||
|
||||
nsRefPtr<FetchPut> fetchPut;
|
||||
nsresult rv = FetchPut::Create(this, mManager, mCacheId, list,
|
||||
requestStreamList, getter_AddRefs(fetchPut));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
OnOpComplete(ErrorResult(rv), CacheAddAllResult());
|
||||
return;
|
||||
}
|
||||
|
||||
mFetchPutList.AppendElement(fetchPut.forget());
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle put op
|
||||
if (mOpArgs.type() == CacheOpArgs::TCachePutAllArgs) {
|
||||
MOZ_ASSERT(mCacheId != INVALID_CACHE_ID);
|
||||
|
||||
const CachePutAllArgs& args = mOpArgs.get_CachePutAllArgs();
|
||||
const nsTArray<CacheRequestResponse>& list = args.requestResponseList();
|
||||
|
||||
nsAutoTArray<nsCOMPtr<nsIInputStream>, 256> requestStreamList;
|
||||
nsAutoTArray<nsCOMPtr<nsIInputStream>, 256> responseStreamList;
|
||||
|
||||
for (uint32_t i = 0; i < list.Length(); ++i) {
|
||||
requestStreamList.AppendElement(
|
||||
DeserializeCacheStream(list[i].request().body()));
|
||||
responseStreamList.AppendElement(
|
||||
DeserializeCacheStream(list[i].response().body()));
|
||||
}
|
||||
|
||||
mManager->ExecutePutAll(this, mCacheId, args.requestResponseList(),
|
||||
requestStreamList, responseStreamList);
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle all other cache ops
|
||||
if (mCacheId != INVALID_CACHE_ID) {
|
||||
MOZ_ASSERT(mNamespace == INVALID_NAMESPACE);
|
||||
mManager->ExecuteCacheOp(this, mCacheId, mOpArgs);
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle all storage ops
|
||||
MOZ_ASSERT(mNamespace != INVALID_NAMESPACE);
|
||||
mManager->ExecuteStorageOp(this, mNamespace, mOpArgs);
|
||||
}
|
||||
|
||||
void
|
||||
CacheOpParent::WaitForVerification(PrincipalVerifier* aVerifier)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheOpParent);
|
||||
MOZ_ASSERT(!mManager);
|
||||
MOZ_ASSERT(!mVerifier);
|
||||
|
||||
mVerifier = aVerifier;
|
||||
mVerifier->AddListener(this);
|
||||
}
|
||||
|
||||
void
|
||||
CacheOpParent::ActorDestroy(ActorDestroyReason aReason)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheOpParent);
|
||||
|
||||
if (mVerifier) {
|
||||
mVerifier->RemoveListener(this);
|
||||
mVerifier = nullptr;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < mFetchPutList.Length(); ++i) {
|
||||
mFetchPutList[i]->ClearListener();
|
||||
}
|
||||
mFetchPutList.Clear();
|
||||
|
||||
if (mManager) {
|
||||
mManager->RemoveListener(this);
|
||||
mManager = nullptr;
|
||||
}
|
||||
|
||||
mIpcManager = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
CacheOpParent::OnPrincipalVerified(nsresult aRv, ManagerId* aManagerId)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheOpParent);
|
||||
|
||||
mVerifier->RemoveListener(this);
|
||||
mVerifier = nullptr;
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(aRv))) {
|
||||
unused << Send__delete__(this, ErrorResult(aRv), void_t());
|
||||
return;
|
||||
}
|
||||
|
||||
Execute(aManagerId);
|
||||
}
|
||||
|
||||
void
|
||||
CacheOpParent::OnOpComplete(ErrorResult&& aRv, const CacheOpResult& aResult,
|
||||
CacheId aOpenedCacheId,
|
||||
const nsTArray<SavedResponse>& aSavedResponseList,
|
||||
const nsTArray<SavedRequest>& aSavedRequestList,
|
||||
StreamList* aStreamList)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheOpParent);
|
||||
MOZ_ASSERT(mIpcManager);
|
||||
MOZ_ASSERT(mManager);
|
||||
|
||||
// Never send an op-specific result if we have an error. Instead, send
|
||||
// void_t() to ensure that we don't leak actors on the child side.
|
||||
if (aRv.Failed()) {
|
||||
unused << Send__delete__(this, aRv, void_t());
|
||||
aRv.ClearMessage(); // This may contain a TypeError.
|
||||
return;
|
||||
}
|
||||
|
||||
// The result must contain the appropriate type at this point. It may
|
||||
// or may not contain the additional result data yet. For types that
|
||||
// do not need special processing, it should already be set. If the
|
||||
// result requires actor-specific operations, then we do that below.
|
||||
// If the type and data types don't match, then we will trigger an
|
||||
// assertion in AutoParentOpResult::Add().
|
||||
AutoParentOpResult result(mIpcManager, aResult);
|
||||
|
||||
if (aOpenedCacheId != INVALID_CACHE_ID) {
|
||||
result.Add(aOpenedCacheId, mManager);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < aSavedResponseList.Length(); ++i) {
|
||||
result.Add(aSavedResponseList[i], aStreamList);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < aSavedRequestList.Length(); ++i) {
|
||||
result.Add(aSavedRequestList[i], aStreamList);
|
||||
}
|
||||
|
||||
unused << Send__delete__(this, aRv, result.SendAsOpResult());
|
||||
}
|
||||
|
||||
void
|
||||
CacheOpParent::OnFetchPut(FetchPut* aFetchPut, ErrorResult&& aRv)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheOpParent);
|
||||
MOZ_ASSERT(aFetchPut);
|
||||
|
||||
aFetchPut->ClearListener();
|
||||
MOZ_ALWAYS_TRUE(mFetchPutList.RemoveElement(aFetchPut));
|
||||
|
||||
OnOpComplete(Move(aRv), CacheAddAllResult());
|
||||
}
|
||||
|
||||
already_AddRefed<nsIInputStream>
|
||||
CacheOpParent::DeserializeCacheStream(const CacheReadStreamOrVoid& aStreamOrVoid)
|
||||
{
|
||||
if (aStreamOrVoid.type() == CacheReadStreamOrVoid::Tvoid_t) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInputStream> stream;
|
||||
const CacheReadStream& readStream = aStreamOrVoid.get_CacheReadStream();
|
||||
|
||||
// Option 1: A push stream actor was sent for nsPipe data
|
||||
if (readStream.pushStreamParent()) {
|
||||
MOZ_ASSERT(!readStream.controlParent());
|
||||
CachePushStreamParent* pushStream =
|
||||
static_cast<CachePushStreamParent*>(readStream.pushStreamParent());
|
||||
stream = pushStream->TakeReader();
|
||||
MOZ_ASSERT(stream);
|
||||
return stream.forget();
|
||||
}
|
||||
|
||||
// Option 2: One of our own ReadStreams was passed back to us with a stream
|
||||
// control actor.
|
||||
stream = ReadStream::Create(readStream);
|
||||
if (stream) {
|
||||
return stream.forget();
|
||||
}
|
||||
|
||||
// Option 3: A stream was serialized using normal methods.
|
||||
nsAutoTArray<FileDescriptor, 4> fds;
|
||||
if (readStream.fds().type() ==
|
||||
OptionalFileDescriptorSet::TPFileDescriptorSetChild) {
|
||||
|
||||
FileDescriptorSetParent* fdSetActor =
|
||||
static_cast<FileDescriptorSetParent*>(readStream.fds().get_PFileDescriptorSetParent());
|
||||
MOZ_ASSERT(fdSetActor);
|
||||
|
||||
fdSetActor->ForgetFileDescriptors(fds);
|
||||
MOZ_ASSERT(!fds.IsEmpty());
|
||||
|
||||
if (!fdSetActor->Send__delete__(fdSetActor)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("Cache failed to delete fd set actor.");
|
||||
}
|
||||
}
|
||||
|
||||
return DeserializeInputStream(readStream.params(), fds);
|
||||
}
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,87 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_cache_CacheOpParent_h
|
||||
#define mozilla_dom_cache_CacheOpParent_h
|
||||
|
||||
#include "mozilla/dom/cache/FetchPut.h"
|
||||
#include "mozilla/dom/cache/Manager.h"
|
||||
#include "mozilla/dom/cache/PCacheOpParent.h"
|
||||
#include "mozilla/dom/cache/PrincipalVerifier.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
class PBackgroundParent;
|
||||
}
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
class CacheOpParent final : public PCacheOpParent
|
||||
, public PrincipalVerifier::Listener
|
||||
, public Manager::Listener
|
||||
, public FetchPut::Listener
|
||||
{
|
||||
// to allow use of convenience overrides
|
||||
using Manager::Listener::OnOpComplete;
|
||||
|
||||
public:
|
||||
CacheOpParent(mozilla::ipc::PBackgroundParent* aIpcManager, CacheId aCacheId,
|
||||
const CacheOpArgs& aOpArgs);
|
||||
CacheOpParent(mozilla::ipc::PBackgroundParent* aIpcManager,
|
||||
Namespace aNamespace, const CacheOpArgs& aOpArgs);
|
||||
~CacheOpParent();
|
||||
|
||||
void
|
||||
Execute(ManagerId* aManagerId);
|
||||
|
||||
void
|
||||
Execute(Manager* aManager);
|
||||
|
||||
void
|
||||
WaitForVerification(PrincipalVerifier* aVerifier);
|
||||
|
||||
private:
|
||||
// PCacheOpParent methods
|
||||
virtual void
|
||||
ActorDestroy(ActorDestroyReason aReason) override;
|
||||
|
||||
// PrincipalVerifier::Listener methods
|
||||
virtual void
|
||||
OnPrincipalVerified(nsresult aRv, ManagerId* aManagerId) override;
|
||||
|
||||
// Manager::Listener methods
|
||||
virtual void
|
||||
OnOpComplete(ErrorResult&& aRv, const CacheOpResult& aResult,
|
||||
CacheId aOpenedCacheId,
|
||||
const nsTArray<SavedResponse>& aSavedResponseList,
|
||||
const nsTArray<SavedRequest>& aSavedRequestList,
|
||||
StreamList* aStreamList) override;
|
||||
|
||||
// FetchPut::Listener methods
|
||||
virtual void
|
||||
OnFetchPut(FetchPut* aFetchPut, ErrorResult&& aRv) override;
|
||||
|
||||
// utility methods
|
||||
already_AddRefed<nsIInputStream>
|
||||
DeserializeCacheStream(const CacheReadStreamOrVoid& aStreamOrVoid);
|
||||
|
||||
mozilla::ipc::PBackgroundParent* mIpcManager;
|
||||
const CacheId mCacheId;
|
||||
const Namespace mNamespace;
|
||||
const CacheOpArgs mOpArgs;
|
||||
nsRefPtr<Manager> mManager;
|
||||
nsRefPtr<PrincipalVerifier> mVerifier;
|
||||
nsTArray<nsRefPtr<FetchPut>> mFetchPutList;
|
||||
|
||||
NS_DECL_OWNINGTHREAD
|
||||
};
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_cache_CacheOpParent_h
|
|
@ -6,27 +6,14 @@
|
|||
|
||||
#include "mozilla/dom/cache/CacheParent.h"
|
||||
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/dom/cache/AutoUtils.h"
|
||||
#include "mozilla/dom/cache/CacheOpParent.h"
|
||||
#include "mozilla/dom/cache/CachePushStreamParent.h"
|
||||
#include "mozilla/dom/cache/CacheStreamControlParent.h"
|
||||
#include "mozilla/dom/cache/ReadStream.h"
|
||||
#include "mozilla/dom/cache/SavedTypes.h"
|
||||
#include "mozilla/dom/cache/StreamList.h"
|
||||
#include "mozilla/ipc/InputStreamUtils.h"
|
||||
#include "mozilla/ipc/PBackgroundParent.h"
|
||||
#include "mozilla/ipc/FileDescriptorSetParent.h"
|
||||
#include "mozilla/ipc/PFileDescriptorSetParent.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
using mozilla::dom::ErrNum;
|
||||
using mozilla::ipc::FileDescriptorSetParent;
|
||||
using mozilla::ipc::PFileDescriptorSetParent;
|
||||
|
||||
// Declared in ActorUtils.h
|
||||
void
|
||||
DeallocPCacheParent(PCacheParent* aActor)
|
||||
|
@ -47,22 +34,48 @@ CacheParent::~CacheParent()
|
|||
{
|
||||
MOZ_COUNT_DTOR(cache::CacheParent);
|
||||
MOZ_ASSERT(!mManager);
|
||||
MOZ_ASSERT(mFetchPutList.IsEmpty());
|
||||
}
|
||||
|
||||
void
|
||||
CacheParent::ActorDestroy(ActorDestroyReason aReason)
|
||||
{
|
||||
MOZ_ASSERT(mManager);
|
||||
for (uint32_t i = 0; i < mFetchPutList.Length(); ++i) {
|
||||
mFetchPutList[i]->ClearListener();
|
||||
}
|
||||
mFetchPutList.Clear();
|
||||
mManager->RemoveListener(this);
|
||||
mManager->ReleaseCacheId(mCacheId);
|
||||
mManager = nullptr;
|
||||
}
|
||||
|
||||
PCacheOpParent*
|
||||
CacheParent::AllocPCacheOpParent(const CacheOpArgs& aOpArgs)
|
||||
{
|
||||
if (aOpArgs.type() != CacheOpArgs::TCacheMatchArgs &&
|
||||
aOpArgs.type() != CacheOpArgs::TCacheMatchAllArgs &&
|
||||
aOpArgs.type() != CacheOpArgs::TCacheAddAllArgs &&
|
||||
aOpArgs.type() != CacheOpArgs::TCachePutAllArgs &&
|
||||
aOpArgs.type() != CacheOpArgs::TCacheDeleteArgs &&
|
||||
aOpArgs.type() != CacheOpArgs::TCacheKeysArgs)
|
||||
{
|
||||
MOZ_CRASH("Invalid operation sent to Cache actor!");
|
||||
}
|
||||
|
||||
return new CacheOpParent(Manager(), mCacheId, aOpArgs);
|
||||
}
|
||||
|
||||
bool
|
||||
CacheParent::DeallocPCacheOpParent(PCacheOpParent* aActor)
|
||||
{
|
||||
delete aActor;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheParent::RecvPCacheOpConstructor(PCacheOpParent* aActor,
|
||||
const CacheOpArgs& aOpArgs)
|
||||
{
|
||||
auto actor = static_cast<CacheOpParent*>(aActor);
|
||||
actor->Execute(mManager);
|
||||
return true;
|
||||
}
|
||||
|
||||
PCachePushStreamParent*
|
||||
CacheParent::AllocPCachePushStreamParent()
|
||||
{
|
||||
|
@ -86,238 +99,6 @@ CacheParent::RecvTeardown()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheParent::RecvMatch(const RequestId& aRequestId, const PCacheRequest& aRequest,
|
||||
const PCacheQueryParams& aParams)
|
||||
{
|
||||
MOZ_ASSERT(mManager);
|
||||
mManager->CacheMatch(this, aRequestId, mCacheId, aRequest,
|
||||
aParams);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheParent::RecvMatchAll(const RequestId& aRequestId,
|
||||
const PCacheRequestOrVoid& aRequest,
|
||||
const PCacheQueryParams& aParams)
|
||||
{
|
||||
MOZ_ASSERT(mManager);
|
||||
mManager->CacheMatchAll(this, aRequestId, mCacheId, aRequest, aParams);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheParent::RecvAddAll(const RequestId& aRequestId,
|
||||
nsTArray<PCacheRequest>&& aRequests)
|
||||
{
|
||||
nsAutoTArray<nsCOMPtr<nsIInputStream>, 256> requestStreams;
|
||||
requestStreams.SetCapacity(aRequests.Length());
|
||||
|
||||
for (uint32_t i = 0; i < aRequests.Length(); ++i) {
|
||||
requestStreams.AppendElement(DeserializeCacheStream(aRequests[i].body()));
|
||||
}
|
||||
|
||||
nsRefPtr<FetchPut> fetchPut;
|
||||
nsresult rv = FetchPut::Create(this, mManager, aRequestId, mCacheId,
|
||||
aRequests, requestStreams,
|
||||
getter_AddRefs(fetchPut));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
MOZ_ASSERT(rv != NS_ERROR_TYPE_ERR);
|
||||
ErrorResult error;
|
||||
error.Throw(rv);
|
||||
if (!SendAddAllResponse(aRequestId, error)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("Cache failed to send AddAll response.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
mFetchPutList.AppendElement(fetchPut.forget());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheParent::RecvPut(const RequestId& aRequestId,
|
||||
const CacheRequestResponse& aPut)
|
||||
{
|
||||
MOZ_ASSERT(mManager);
|
||||
|
||||
nsAutoTArray<CacheRequestResponse, 1> putList;
|
||||
putList.AppendElement(aPut);
|
||||
|
||||
nsAutoTArray<nsCOMPtr<nsIInputStream>, 1> requestStreamList;
|
||||
nsAutoTArray<nsCOMPtr<nsIInputStream>, 1> responseStreamList;
|
||||
|
||||
requestStreamList.AppendElement(
|
||||
DeserializeCacheStream(aPut.request().body()));
|
||||
responseStreamList.AppendElement(
|
||||
DeserializeCacheStream(aPut.response().body()));
|
||||
|
||||
|
||||
mManager->CachePutAll(this, aRequestId, mCacheId, putList, requestStreamList,
|
||||
responseStreamList);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheParent::RecvDelete(const RequestId& aRequestId,
|
||||
const PCacheRequest& aRequest,
|
||||
const PCacheQueryParams& aParams)
|
||||
{
|
||||
MOZ_ASSERT(mManager);
|
||||
mManager->CacheDelete(this, aRequestId, mCacheId, aRequest, aParams);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheParent::RecvKeys(const RequestId& aRequestId,
|
||||
const PCacheRequestOrVoid& aRequest,
|
||||
const PCacheQueryParams& aParams)
|
||||
{
|
||||
MOZ_ASSERT(mManager);
|
||||
mManager->CacheKeys(this, aRequestId, mCacheId, aRequest, aParams);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CacheParent::OnCacheMatch(RequestId aRequestId, nsresult aRv,
|
||||
const SavedResponse* aSavedResponse,
|
||||
StreamList* aStreamList)
|
||||
{
|
||||
AutoParentResponseOrVoid response(Manager());
|
||||
|
||||
// no match
|
||||
if (NS_FAILED(aRv) || !aSavedResponse || !aStreamList) {
|
||||
if (!SendMatchResponse(aRequestId, aRv, response.SendAsResponseOrVoid())) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("Cache failed to send Match response.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (aSavedResponse) {
|
||||
response.Add(*aSavedResponse, aStreamList);
|
||||
}
|
||||
|
||||
if (!SendMatchResponse(aRequestId, aRv, response.SendAsResponseOrVoid())) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("Cache failed to send Match response.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CacheParent::OnCacheMatchAll(RequestId aRequestId, nsresult aRv,
|
||||
const nsTArray<SavedResponse>& aSavedResponses,
|
||||
StreamList* aStreamList)
|
||||
{
|
||||
AutoParentResponseList responses(Manager(), aSavedResponses.Length());
|
||||
|
||||
for (uint32_t i = 0; i < aSavedResponses.Length(); ++i) {
|
||||
responses.Add(aSavedResponses[i], aStreamList);
|
||||
}
|
||||
|
||||
if (!SendMatchAllResponse(aRequestId, aRv, responses.SendAsResponseList())) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("Cache failed to send MatchAll response.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CacheParent::OnCachePutAll(RequestId aRequestId, nsresult aRv)
|
||||
{
|
||||
if (!SendPutResponse(aRequestId, aRv)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("Cache failed to send Put response.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CacheParent::OnCacheDelete(RequestId aRequestId, nsresult aRv, bool aSuccess)
|
||||
{
|
||||
if (!SendDeleteResponse(aRequestId, aRv, aSuccess)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("Cache failed to send Delete response.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CacheParent::OnCacheKeys(RequestId aRequestId, nsresult aRv,
|
||||
const nsTArray<SavedRequest>& aSavedRequests,
|
||||
StreamList* aStreamList)
|
||||
{
|
||||
AutoParentRequestList requests(Manager(), aSavedRequests.Length());
|
||||
|
||||
for (uint32_t i = 0; i < aSavedRequests.Length(); ++i) {
|
||||
requests.Add(aSavedRequests[i], aStreamList);
|
||||
}
|
||||
|
||||
if (!SendKeysResponse(aRequestId, aRv, requests.SendAsRequestList())) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("Cache failed to send Keys response.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CacheParent::OnFetchPut(FetchPut* aFetchPut, RequestId aRequestId, const ErrorResult& aRv)
|
||||
{
|
||||
aFetchPut->ClearListener();
|
||||
mFetchPutList.RemoveElement(aFetchPut);
|
||||
if (!SendAddAllResponse(aRequestId, aRv)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("Cache failed to send AddAll response.");
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<nsIInputStream>
|
||||
CacheParent::DeserializeCacheStream(const PCacheReadStreamOrVoid& aStreamOrVoid)
|
||||
{
|
||||
if (aStreamOrVoid.type() == PCacheReadStreamOrVoid::Tvoid_t) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInputStream> stream;
|
||||
const PCacheReadStream& readStream = aStreamOrVoid.get_PCacheReadStream();
|
||||
|
||||
// Option 1: A push stream actor was sent for nsPipe data
|
||||
if (readStream.pushStreamParent()) {
|
||||
MOZ_ASSERT(!readStream.controlParent());
|
||||
CachePushStreamParent* pushStream =
|
||||
static_cast<CachePushStreamParent*>(readStream.pushStreamParent());
|
||||
stream = pushStream->TakeReader();
|
||||
MOZ_ASSERT(stream);
|
||||
return stream.forget();
|
||||
}
|
||||
|
||||
// Option 2: One of our own ReadStreams was passed back to us with a stream
|
||||
// control actor.
|
||||
stream = ReadStream::Create(readStream);
|
||||
if (stream) {
|
||||
return stream.forget();
|
||||
}
|
||||
|
||||
// Option 3: A stream was serialized using normal methods.
|
||||
nsAutoTArray<FileDescriptor, 4> fds;
|
||||
if (readStream.fds().type() ==
|
||||
OptionalFileDescriptorSet::TPFileDescriptorSetChild) {
|
||||
|
||||
FileDescriptorSetParent* fdSetActor =
|
||||
static_cast<FileDescriptorSetParent*>(readStream.fds().get_PFileDescriptorSetParent());
|
||||
MOZ_ASSERT(fdSetActor);
|
||||
|
||||
fdSetActor->ForgetFileDescriptors(fds);
|
||||
MOZ_ASSERT(!fds.IsEmpty());
|
||||
|
||||
if (!fdSetActor->Send__delete__(fdSetActor)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("Cache failed to delete fd set actor.");
|
||||
}
|
||||
}
|
||||
|
||||
return DeserializeInputStream(readStream.params(), fds);
|
||||
}
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namesapce mozilla
|
||||
|
|
|
@ -7,77 +7,46 @@
|
|||
#ifndef mozilla_dom_cache_CacheParent_h
|
||||
#define mozilla_dom_cache_CacheParent_h
|
||||
|
||||
#include "mozilla/dom/cache/FetchPut.h"
|
||||
#include "mozilla/dom/cache/Manager.h"
|
||||
#include "mozilla/dom/cache/PCacheParent.h"
|
||||
#include "mozilla/dom/cache/Types.h"
|
||||
|
||||
struct nsID;
|
||||
template <class T> class nsRefPtr;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
struct SavedResponse;
|
||||
class Manager;
|
||||
|
||||
class CacheParent final : public PCacheParent
|
||||
, public Manager::Listener
|
||||
, public FetchPut::Listener
|
||||
{
|
||||
public:
|
||||
CacheParent(cache::Manager* aManager, CacheId aCacheId);
|
||||
virtual ~CacheParent();
|
||||
|
||||
private:
|
||||
// PCacheParent method
|
||||
// PCacheParent methods
|
||||
virtual void ActorDestroy(ActorDestroyReason aReason) override;
|
||||
virtual PCachePushStreamParent* AllocPCachePushStreamParent() override;
|
||||
virtual bool DeallocPCachePushStreamParent(PCachePushStreamParent* aActor) override;
|
||||
virtual bool RecvTeardown() override;
|
||||
virtual bool
|
||||
RecvMatch(const RequestId& aRequestId, const PCacheRequest& aRequest,
|
||||
const PCacheQueryParams& aParams) override;
|
||||
virtual bool
|
||||
RecvMatchAll(const RequestId& aRequestId, const PCacheRequestOrVoid& aRequest,
|
||||
const PCacheQueryParams& aParams) override;
|
||||
virtual bool
|
||||
RecvAddAll(const RequestId& aRequestId,
|
||||
nsTArray<PCacheRequest>&& aRequests) override;
|
||||
virtual bool
|
||||
RecvPut(const RequestId& aRequestId,
|
||||
const CacheRequestResponse& aPut) override;
|
||||
virtual bool
|
||||
RecvDelete(const RequestId& aRequestId, const PCacheRequest& aRequest,
|
||||
const PCacheQueryParams& aParams) override;
|
||||
virtual bool
|
||||
RecvKeys(const RequestId& aRequestId, const PCacheRequestOrVoid& aRequest,
|
||||
const PCacheQueryParams& aParams) override;
|
||||
|
||||
// Manager::Listener methods
|
||||
virtual void OnCacheMatch(RequestId aRequestId, nsresult aRv,
|
||||
const SavedResponse* aSavedResponse,
|
||||
StreamList* aStreamList) override;
|
||||
virtual void OnCacheMatchAll(RequestId aRequestId, nsresult aRv,
|
||||
const nsTArray<SavedResponse>& aSavedResponses,
|
||||
StreamList* aStreamList) override;
|
||||
virtual void OnCachePutAll(RequestId aRequestId, nsresult aRv) override;
|
||||
virtual void OnCacheDelete(RequestId aRequestId, nsresult aRv,
|
||||
bool aSuccess) override;
|
||||
virtual void OnCacheKeys(RequestId aRequestId, nsresult aRv,
|
||||
const nsTArray<SavedRequest>& aSavedRequests,
|
||||
StreamList* aStreamList) override;
|
||||
virtual PCacheOpParent*
|
||||
AllocPCacheOpParent(const CacheOpArgs& aOpArgs) override;
|
||||
|
||||
// FetchPut::Listener methods
|
||||
virtual void OnFetchPut(FetchPut* aFetchPut, RequestId aRequestId,
|
||||
const mozilla::ErrorResult& aRv) override;
|
||||
virtual bool
|
||||
DeallocPCacheOpParent(PCacheOpParent* aActor) override;
|
||||
|
||||
already_AddRefed<nsIInputStream>
|
||||
DeserializeCacheStream(const PCacheReadStreamOrVoid& aStreamOrVoid);
|
||||
virtual bool
|
||||
RecvPCacheOpConstructor(PCacheOpParent* actor,
|
||||
const CacheOpArgs& aOpArgs) override;
|
||||
|
||||
virtual PCachePushStreamParent*
|
||||
AllocPCachePushStreamParent() override;
|
||||
|
||||
virtual bool
|
||||
DeallocPCachePushStreamParent(PCachePushStreamParent* aActor) override;
|
||||
|
||||
virtual bool
|
||||
RecvTeardown() override;
|
||||
|
||||
nsRefPtr<cache::Manager> mManager;
|
||||
const CacheId mCacheId;
|
||||
nsTArray<nsRefPtr<FetchPut>> mFetchPutList;
|
||||
};
|
||||
|
||||
} // namespace cache
|
||||
|
|
|
@ -20,17 +20,20 @@ namespace cache {
|
|||
class CachePushStreamChild final : public PCachePushStreamChild
|
||||
, public ActorChild
|
||||
{
|
||||
friend class CacheChild;
|
||||
|
||||
public:
|
||||
CachePushStreamChild(Feature* aFeature, nsIAsyncInputStream* aStream);
|
||||
~CachePushStreamChild();
|
||||
void Start();
|
||||
|
||||
virtual void StartDestroy() override;
|
||||
|
||||
void Start();
|
||||
|
||||
private:
|
||||
class Callback;
|
||||
|
||||
// This class must be constructed using CacheChild::CreatePushStream()
|
||||
CachePushStreamChild(Feature* aFeature, nsIAsyncInputStream* aStream);
|
||||
~CachePushStreamChild();
|
||||
|
||||
// PCachePushStreamChild methods
|
||||
virtual void
|
||||
ActorDestroy(ActorDestroyReason aReason) override;
|
||||
|
|
|
@ -41,24 +41,26 @@ using mozilla::ipc::PrincipalToPrincipalInfo;
|
|||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(mozilla::dom::cache::CacheStorage);
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(mozilla::dom::cache::CacheStorage);
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(mozilla::dom::cache::CacheStorage)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(mozilla::dom::cache::CacheStorage)
|
||||
tmp->DisconnectFromActor();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mGlobal, mRequestPromises)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(mozilla::dom::cache::CacheStorage)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobal, mRequestPromises)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(mozilla::dom::cache::CacheStorage)
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(mozilla::dom::cache::CacheStorage,
|
||||
mGlobal);
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CacheStorage)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIIPCBackgroundChildCreateCallback)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIIPCBackgroundChildCreateCallback)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
// We cannot reference IPC types in a webidl binding implementation header. So
|
||||
// define this in the .cpp and use heap storage in the mPendingRequests list.
|
||||
struct CacheStorage::Entry final
|
||||
{
|
||||
nsRefPtr<Promise> mPromise;
|
||||
CacheOpArgs mArgs;
|
||||
// We cannot add the requests until after the actor is present. So store
|
||||
// the request data separately for now.
|
||||
nsRefPtr<InternalRequest> mRequest;
|
||||
};
|
||||
|
||||
// static
|
||||
already_AddRefed<CacheStorage>
|
||||
CacheStorage::CreateOnMainThread(Namespace aNamespace, nsIGlobalObject* aGlobal,
|
||||
|
@ -175,29 +177,31 @@ CacheStorage::Match(const RequestOrUSVString& aRequest,
|
|||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorage);
|
||||
|
||||
if (mFailedActor) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<InternalRequest> request = ToInternalRequest(aRequest, IgnoreBody,
|
||||
aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
|
||||
if (!promise) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (mFailedActor) {
|
||||
promise->MaybeReject(NS_ERROR_UNEXPECTED);
|
||||
return promise.forget();
|
||||
}
|
||||
CacheQueryParams params;
|
||||
ToCacheQueryParams(params, aOptions);
|
||||
|
||||
RequestId requestId = AddRequestPromise(promise, aRv);
|
||||
|
||||
Entry entry;
|
||||
entry.mRequestId = requestId;
|
||||
entry.mOp = OP_MATCH;
|
||||
entry.mOptions = aOptions;
|
||||
entry.mRequest = ToInternalRequest(aRequest, IgnoreBody, aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mPendingRequests.AppendElement(entry);
|
||||
nsAutoPtr<Entry> entry(new Entry());
|
||||
entry->mPromise = promise;
|
||||
entry->mArgs = StorageMatchArgs(CacheRequest(), params);
|
||||
entry->mRequest = request;
|
||||
|
||||
mPendingRequests.AppendElement(entry.forget());
|
||||
MaybeRunPendingRequests();
|
||||
|
||||
return promise.forget();
|
||||
|
@ -208,23 +212,21 @@ CacheStorage::Has(const nsAString& aKey, ErrorResult& aRv)
|
|||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorage);
|
||||
|
||||
if (mFailedActor) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
|
||||
if (!promise) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (mFailedActor) {
|
||||
promise->MaybeReject(NS_ERROR_UNEXPECTED);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
RequestId requestId = AddRequestPromise(promise, aRv);
|
||||
|
||||
Entry* entry = mPendingRequests.AppendElement();
|
||||
entry->mRequestId = requestId;
|
||||
entry->mOp = OP_HAS;
|
||||
entry->mKey = aKey;
|
||||
nsAutoPtr<Entry> entry(new Entry());
|
||||
entry->mPromise = promise;
|
||||
entry->mArgs = StorageHasArgs(nsString(aKey));
|
||||
|
||||
mPendingRequests.AppendElement(entry.forget());
|
||||
MaybeRunPendingRequests();
|
||||
|
||||
return promise.forget();
|
||||
|
@ -235,23 +237,21 @@ CacheStorage::Open(const nsAString& aKey, ErrorResult& aRv)
|
|||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorage);
|
||||
|
||||
if (mFailedActor) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
|
||||
if (!promise) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (mFailedActor) {
|
||||
promise->MaybeReject(NS_ERROR_UNEXPECTED);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
RequestId requestId = AddRequestPromise(promise, aRv);
|
||||
|
||||
Entry* entry = mPendingRequests.AppendElement();
|
||||
entry->mRequestId = requestId;
|
||||
entry->mOp = OP_OPEN;
|
||||
entry->mKey = aKey;
|
||||
nsAutoPtr<Entry> entry(new Entry());
|
||||
entry->mPromise = promise;
|
||||
entry->mArgs = StorageOpenArgs(nsString(aKey));
|
||||
|
||||
mPendingRequests.AppendElement(entry.forget());
|
||||
MaybeRunPendingRequests();
|
||||
|
||||
return promise.forget();
|
||||
|
@ -262,23 +262,21 @@ CacheStorage::Delete(const nsAString& aKey, ErrorResult& aRv)
|
|||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorage);
|
||||
|
||||
if (mFailedActor) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
|
||||
if (!promise) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (mFailedActor) {
|
||||
promise->MaybeReject(NS_ERROR_UNEXPECTED);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
RequestId requestId = AddRequestPromise(promise, aRv);
|
||||
|
||||
Entry* entry = mPendingRequests.AppendElement();
|
||||
entry->mRequestId = requestId;
|
||||
entry->mOp = OP_DELETE;
|
||||
entry->mKey = aKey;
|
||||
nsAutoPtr<Entry> entry(new Entry());
|
||||
entry->mPromise = promise;
|
||||
entry->mArgs = StorageDeleteArgs(nsString(aKey));
|
||||
|
||||
mPendingRequests.AppendElement(entry.forget());
|
||||
MaybeRunPendingRequests();
|
||||
|
||||
return promise.forget();
|
||||
|
@ -289,22 +287,21 @@ CacheStorage::Keys(ErrorResult& aRv)
|
|||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorage);
|
||||
|
||||
if (mFailedActor) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
|
||||
if (!promise) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (mFailedActor) {
|
||||
promise->MaybeReject(NS_ERROR_UNEXPECTED);
|
||||
return promise.forget();
|
||||
}
|
||||
|
||||
RequestId requestId = AddRequestPromise(promise, aRv);
|
||||
|
||||
Entry* entry = mPendingRequests.AppendElement();
|
||||
entry->mRequestId = requestId;
|
||||
entry->mOp = OP_KEYS;
|
||||
nsAutoPtr<Entry> entry(new Entry());
|
||||
entry->mPromise = promise;
|
||||
entry->mArgs = StorageKeysArgs();
|
||||
|
||||
mPendingRequests.AppendElement(entry.forget());
|
||||
MaybeRunPendingRequests();
|
||||
|
||||
return promise.forget();
|
||||
|
@ -371,9 +368,8 @@ CacheStorage::ActorFailed()
|
|||
mFeature = nullptr;
|
||||
|
||||
for (uint32_t i = 0; i < mPendingRequests.Length(); ++i) {
|
||||
RequestId requestId = mPendingRequests[i].mRequestId;
|
||||
nsRefPtr<Promise> promise = RemoveRequestPromise(requestId);
|
||||
promise->MaybeReject(NS_ERROR_UNEXPECTED);
|
||||
nsAutoPtr<Entry> entry(mPendingRequests[i].forget());
|
||||
entry->mPromise->MaybeReject(NS_ERROR_UNEXPECTED);
|
||||
}
|
||||
mPendingRequests.Clear();
|
||||
}
|
||||
|
@ -392,117 +388,6 @@ CacheStorage::DestroyInternal(CacheStorageChild* aActor)
|
|||
ActorFailed();
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorage::RecvMatchResponse(RequestId aRequestId, nsresult aRv,
|
||||
const PCacheResponseOrVoid& aResponse)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorage);
|
||||
|
||||
// Convert the response immediately if its present. This ensures that
|
||||
// any stream actors are cleaned up, even if we error out below.
|
||||
nsRefPtr<Response> response;
|
||||
if (aResponse.type() == PCacheResponseOrVoid::TPCacheResponse) {
|
||||
response = ToResponse(aResponse);
|
||||
}
|
||||
|
||||
nsRefPtr<Promise> promise = RemoveRequestPromise(aRequestId);
|
||||
|
||||
if (NS_FAILED(aRv)) {
|
||||
promise->MaybeReject(aRv);
|
||||
return;
|
||||
}
|
||||
|
||||
// If cache name was specified in the request options and the cache does
|
||||
// not exist, then an error code will already have been set. If we
|
||||
// still do not have a response, then we just resolve undefined like a
|
||||
// normal Cache::Match.
|
||||
if (!response) {
|
||||
promise->MaybeResolve(JS::UndefinedHandleValue);
|
||||
return;
|
||||
}
|
||||
|
||||
promise->MaybeResolve(response);
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorage::RecvHasResponse(RequestId aRequestId, nsresult aRv, bool aSuccess)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorage);
|
||||
|
||||
nsRefPtr<Promise> promise = RemoveRequestPromise(aRequestId);
|
||||
|
||||
if (NS_FAILED(aRv)) {
|
||||
promise->MaybeReject(aRv);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
promise->MaybeResolve(aSuccess);
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorage::RecvOpenResponse(RequestId aRequestId, nsresult aRv,
|
||||
CacheChild* aActor)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorage);
|
||||
|
||||
// Unlike most of our async callback Recv*() methods, this one gets back
|
||||
// an actor. We need to make sure to clean it up in case of error.
|
||||
|
||||
nsRefPtr<Promise> promise = RemoveRequestPromise(aRequestId);
|
||||
|
||||
if (NS_FAILED(aRv)) {
|
||||
if (aActor) {
|
||||
// We cannot use the CacheChild::StartDestroy() method because there
|
||||
// is no Cache object associated with the actor yet. Instead, just
|
||||
// send the underlying Teardown message.
|
||||
unused << aActor->SendTeardown();
|
||||
}
|
||||
promise->MaybeReject(aRv);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!aActor) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<Cache> cache = new Cache(mGlobal, aActor);
|
||||
promise->MaybeResolve(cache);
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorage::RecvDeleteResponse(RequestId aRequestId, nsresult aRv,
|
||||
bool aSuccess)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorage);
|
||||
|
||||
nsRefPtr<Promise> promise = RemoveRequestPromise(aRequestId);
|
||||
|
||||
if (NS_FAILED(aRv)) {
|
||||
promise->MaybeReject(aRv);
|
||||
return;
|
||||
}
|
||||
|
||||
promise->MaybeResolve(aSuccess);
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorage::RecvKeysResponse(RequestId aRequestId, nsresult aRv,
|
||||
const nsTArray<nsString>& aKeys)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorage);
|
||||
|
||||
nsRefPtr<Promise> promise = RemoveRequestPromise(aRequestId);
|
||||
|
||||
if (NS_FAILED(aRv)) {
|
||||
promise->MaybeReject(aRv);
|
||||
return;
|
||||
}
|
||||
|
||||
promise->MaybeResolve(aKeys);
|
||||
}
|
||||
|
||||
nsIGlobalObject*
|
||||
CacheStorage::GetGlobalObject() const
|
||||
{
|
||||
|
@ -524,32 +409,9 @@ CacheStorage::CreatePushStream(nsIAsyncInputStream* aStream)
|
|||
MOZ_CRASH("CacheStorage should never create a push stream.");
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorage::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
|
||||
{
|
||||
// Do nothing. The Promise will automatically drop the ref to us after
|
||||
// calling the callback. This is what we want as we only registered in order
|
||||
// to be held alive via the Promise handle.
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorage::RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
|
||||
{
|
||||
// Do nothing. The Promise will automatically drop the ref to us after
|
||||
// calling the callback. This is what we want as we only registered in order
|
||||
// to be held alive via the Promise handle.
|
||||
}
|
||||
|
||||
CacheStorage::~CacheStorage()
|
||||
{
|
||||
DisconnectFromActor();
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorage::DisconnectFromActor()
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorage);
|
||||
|
||||
if (mActor) {
|
||||
mActor->StartDestroy();
|
||||
// DestroyInternal() is called synchronously by StartDestroy(). So we
|
||||
|
@ -566,89 +428,22 @@ CacheStorage::MaybeRunPendingRequests()
|
|||
}
|
||||
|
||||
for (uint32_t i = 0; i < mPendingRequests.Length(); ++i) {
|
||||
// Note, the entry can be modified below due to Request/Response body
|
||||
// being marked used.
|
||||
Entry& entry = mPendingRequests[i];
|
||||
RequestId requestId = entry.mRequestId;
|
||||
switch(entry.mOp) {
|
||||
case OP_MATCH:
|
||||
{
|
||||
AutoChildRequest request(this);
|
||||
ErrorResult rv;
|
||||
request.Add(entry.mRequest, IgnoreBody, PassThroughReferrer,
|
||||
IgnoreInvalidScheme, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
nsRefPtr<Promise> promise = RemoveRequestPromise(requestId);
|
||||
promise->MaybeReject(rv);
|
||||
break;
|
||||
}
|
||||
|
||||
PCacheQueryParams params;
|
||||
ToPCacheQueryParams(params, entry.mOptions);
|
||||
|
||||
unused << mActor->SendMatch(requestId, request.SendAsRequest(), params);
|
||||
break;
|
||||
}
|
||||
case OP_HAS:
|
||||
unused << mActor->SendHas(requestId, entry.mKey);
|
||||
break;
|
||||
case OP_OPEN:
|
||||
unused << mActor->SendOpen(requestId, entry.mKey);
|
||||
break;
|
||||
case OP_DELETE:
|
||||
unused << mActor->SendDelete(requestId, entry.mKey);
|
||||
break;
|
||||
case OP_KEYS:
|
||||
unused << mActor->SendKeys(requestId);
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Unknown pending CacheStorage op.");
|
||||
ErrorResult rv;
|
||||
nsAutoPtr<Entry> entry(mPendingRequests[i].forget());
|
||||
AutoChildOpArgs args(this, entry->mArgs);
|
||||
if (entry->mRequest) {
|
||||
args.Add(entry->mRequest, IgnoreBody, PassThroughReferrer,
|
||||
IgnoreInvalidScheme, rv);
|
||||
}
|
||||
if (rv.Failed()) {
|
||||
entry->mPromise->MaybeReject(rv);
|
||||
continue;
|
||||
}
|
||||
mActor->ExecuteOp(mGlobal, entry->mPromise, args.SendAsOpArgs());
|
||||
}
|
||||
mPendingRequests.Clear();
|
||||
}
|
||||
|
||||
RequestId
|
||||
CacheStorage::AddRequestPromise(Promise* aPromise, ErrorResult& aRv)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorage);
|
||||
MOZ_ASSERT(aPromise);
|
||||
MOZ_ASSERT(!mRequestPromises.Contains(aPromise));
|
||||
|
||||
// Register ourself as a promise handler so that the promise will hold us
|
||||
// alive. This allows the client code to drop the ref to the CacheStorage
|
||||
// object and just keep their promise. This is fairly common in promise
|
||||
// chaining code.
|
||||
aPromise->AppendNativeHandler(this);
|
||||
|
||||
mRequestPromises.AppendElement(aPromise);
|
||||
|
||||
// (Ab)use the promise pointer as our request ID. This is a fast, thread-safe
|
||||
// way to get a unique ID for the promise to be resolved later.
|
||||
return reinterpret_cast<RequestId>(aPromise);
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
CacheStorage::RemoveRequestPromise(RequestId aRequestId)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorage);
|
||||
MOZ_ASSERT(aRequestId != INVALID_REQUEST_ID);
|
||||
|
||||
for (uint32_t i = 0; i < mRequestPromises.Length(); ++i) {
|
||||
nsRefPtr<Promise>& promise = mRequestPromises.ElementAt(i);
|
||||
// To be safe, only cast promise pointers to our integer RequestId
|
||||
// type and never cast an integer to a pointer.
|
||||
if (aRequestId == reinterpret_cast<RequestId>(promise.get())) {
|
||||
nsRefPtr<Promise> ref;
|
||||
ref.swap(promise);
|
||||
mRequestPromises.RemoveElementAt(i);
|
||||
return ref.forget();
|
||||
}
|
||||
}
|
||||
MOZ_ASSERT_UNREACHABLE("Received response without a matching promise!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#define mozilla_dom_cache_CacheStorage_h
|
||||
|
||||
#include "mozilla/dom/CacheBinding.h"
|
||||
#include "mozilla/dom/PromiseNativeHandler.h"
|
||||
#include "mozilla/dom/cache/Types.h"
|
||||
#include "mozilla/dom/cache/TypeUtils.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
@ -38,15 +37,12 @@ namespace workers {
|
|||
|
||||
namespace cache {
|
||||
|
||||
class CacheChild;
|
||||
class CacheStorageChild;
|
||||
class Feature;
|
||||
class PCacheResponseOrVoid;
|
||||
|
||||
class CacheStorage final : public nsIIPCBackgroundChildCreateCallback
|
||||
, public nsWrapperCache
|
||||
, public TypeUtils
|
||||
, public PromiseNativeHandler
|
||||
{
|
||||
typedef mozilla::ipc::PBackgroundChild PBackgroundChild;
|
||||
|
||||
|
@ -81,16 +77,6 @@ public:
|
|||
// Called when CacheStorageChild actor is being destroyed
|
||||
void DestroyInternal(CacheStorageChild* aActor);
|
||||
|
||||
// Methods forwarded from CacheStorageChild
|
||||
void RecvMatchResponse(RequestId aRequestId, nsresult aRv,
|
||||
const PCacheResponseOrVoid& aResponse);
|
||||
void RecvHasResponse(RequestId aRequestId, nsresult aRv, bool aSuccess);
|
||||
void RecvOpenResponse(RequestId aRequestId, nsresult aRv,
|
||||
CacheChild* aActor);
|
||||
void RecvDeleteResponse(RequestId aRequestId, nsresult aRv, bool aSuccess);
|
||||
void RecvKeysResponse(RequestId aRequestId, nsresult aRv,
|
||||
const nsTArray<nsString>& aKeys);
|
||||
|
||||
// TypeUtils methods
|
||||
virtual nsIGlobalObject* GetGlobalObject() const override;
|
||||
#ifdef DEBUG
|
||||
|
@ -100,60 +86,24 @@ public:
|
|||
virtual CachePushStreamChild*
|
||||
CreatePushStream(nsIAsyncInputStream* aStream) override;
|
||||
|
||||
// PromiseNativeHandler methods
|
||||
virtual void
|
||||
ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override;
|
||||
|
||||
virtual void
|
||||
RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override;
|
||||
|
||||
private:
|
||||
CacheStorage(Namespace aNamespace, nsIGlobalObject* aGlobal,
|
||||
const mozilla::ipc::PrincipalInfo& aPrincipalInfo, Feature* aFeature);
|
||||
~CacheStorage();
|
||||
|
||||
// Called when we're destroyed or CCed.
|
||||
void DisconnectFromActor();
|
||||
|
||||
void MaybeRunPendingRequests();
|
||||
|
||||
RequestId AddRequestPromise(Promise* aPromise, ErrorResult& aRv);
|
||||
already_AddRefed<Promise> RemoveRequestPromise(RequestId aRequestId);
|
||||
|
||||
// Would like to use CacheInitData here, but we cannot because
|
||||
// its an IPC struct which breaks webidl by including windows.h.
|
||||
const Namespace mNamespace;
|
||||
nsCOMPtr<nsIGlobalObject> mGlobal;
|
||||
UniquePtr<mozilla::ipc::PrincipalInfo> mPrincipalInfo;
|
||||
nsRefPtr<Feature> mFeature;
|
||||
|
||||
// weak ref cleared in DestroyInternal
|
||||
CacheStorageChild* mActor;
|
||||
nsTArray<nsRefPtr<Promise>> mRequestPromises;
|
||||
|
||||
enum Op
|
||||
{
|
||||
OP_MATCH,
|
||||
OP_HAS,
|
||||
OP_OPEN,
|
||||
OP_DELETE,
|
||||
OP_KEYS
|
||||
};
|
||||
struct Entry;
|
||||
nsTArray<nsAutoPtr<Entry>> mPendingRequests;
|
||||
|
||||
struct Entry
|
||||
{
|
||||
RequestId mRequestId;
|
||||
Op mOp;
|
||||
// Would prefer to use PCacheRequest/PCacheCacheQueryOptions, but can't
|
||||
// because they introduce a header dependency on windows.h which
|
||||
// breaks the bindings build.
|
||||
nsRefPtr<InternalRequest> mRequest;
|
||||
CacheQueryOptions mOptions;
|
||||
// It would also be nice to union the key with the match args above,
|
||||
// but VS2013 doesn't like these types in unions because of copy
|
||||
// constructors.
|
||||
nsString mKey;
|
||||
};
|
||||
|
||||
nsTArray<Entry> mPendingRequests;
|
||||
bool mFailedActor;
|
||||
|
||||
public:
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
|
||||
#include "mozilla/unused.h"
|
||||
#include "mozilla/dom/cache/CacheChild.h"
|
||||
#include "mozilla/dom/cache/CacheOpChild.h"
|
||||
#include "mozilla/dom/cache/CacheStorage.h"
|
||||
#include "mozilla/dom/cache/StreamUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -24,6 +24,7 @@ DeallocPCacheStorageChild(PCacheStorageChild* aActor)
|
|||
|
||||
CacheStorageChild::CacheStorageChild(CacheStorage* aListener, Feature* aFeature)
|
||||
: mListener(aListener)
|
||||
, mNumChildActors(0)
|
||||
{
|
||||
MOZ_COUNT_CTOR(cache::CacheStorageChild);
|
||||
MOZ_ASSERT(mListener);
|
||||
|
@ -46,6 +47,15 @@ CacheStorageChild::ClearListener()
|
|||
mListener = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorageChild::ExecuteOp(nsIGlobalObject* aGlobal, Promise* aPromise,
|
||||
const CacheOpArgs& aArgs)
|
||||
{
|
||||
mNumChildActors += 1;
|
||||
unused << SendPCacheOpConstructor(
|
||||
new CacheOpChild(GetFeature(), aGlobal, aPromise), aArgs);
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorageChild::StartDestroy()
|
||||
{
|
||||
|
@ -65,6 +75,14 @@ CacheStorageChild::StartDestroy()
|
|||
// CacheStorage listener should call ClearListener() in DestroyInternal()
|
||||
MOZ_ASSERT(!mListener);
|
||||
|
||||
// If we have outstanding child actors, then don't destroy ourself yet.
|
||||
// The child actors should be short lived and we should allow them to complete
|
||||
// if possible. SendTeardown() will be called when the count drops to zero
|
||||
// in NoteDeletedActor().
|
||||
if (mNumChildActors) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Start actor destruction from parent process
|
||||
unused << SendTeardown();
|
||||
}
|
||||
|
@ -83,92 +101,29 @@ CacheStorageChild::ActorDestroy(ActorDestroyReason aReason)
|
|||
RemoveFeature();
|
||||
}
|
||||
|
||||
bool
|
||||
CacheStorageChild::RecvMatchResponse(const RequestId& aRequestId,
|
||||
const nsresult& aRv,
|
||||
const PCacheResponseOrVoid& aResponseOrVoid)
|
||||
PCacheOpChild*
|
||||
CacheStorageChild::AllocPCacheOpChild(const CacheOpArgs& aOpArgs)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorageChild);
|
||||
|
||||
AddFeatureToStreamChild(aResponseOrVoid, GetFeature());
|
||||
|
||||
nsRefPtr<CacheStorage> listener = mListener;
|
||||
if (!listener) {
|
||||
StartDestroyStreamChild(aResponseOrVoid);
|
||||
return true;
|
||||
}
|
||||
|
||||
listener->RecvMatchResponse(aRequestId, aRv, aResponseOrVoid);
|
||||
|
||||
return true;
|
||||
MOZ_CRASH("CacheOpChild should be manually constructed.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheStorageChild::RecvHasResponse(const RequestId& aRequestId,
|
||||
const nsresult& aRv,
|
||||
const bool& aSuccess)
|
||||
CacheStorageChild::DeallocPCacheOpChild(PCacheOpChild* aActor)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorageChild);
|
||||
nsRefPtr<CacheStorage> listener = mListener;
|
||||
if (listener) {
|
||||
listener->RecvHasResponse(aRequestId, aRv, aSuccess);
|
||||
}
|
||||
delete aActor;
|
||||
NoteDeletedActor();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheStorageChild::RecvOpenResponse(const RequestId& aRequestId,
|
||||
const nsresult& aRv,
|
||||
PCacheChild* aActor)
|
||||
void
|
||||
CacheStorageChild::NoteDeletedActor()
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorageChild);
|
||||
|
||||
nsRefPtr<CacheStorage> listener = mListener;
|
||||
if (!listener || FeatureNotified()) {
|
||||
if (aActor) {
|
||||
unused << aActor->SendTeardown();
|
||||
}
|
||||
return true;
|
||||
MOZ_ASSERT(mNumChildActors);
|
||||
mNumChildActors -= 1;
|
||||
if (!mNumChildActors && !mListener) {
|
||||
unused << SendTeardown();
|
||||
}
|
||||
|
||||
CacheChild* cacheChild = static_cast<CacheChild*>(aActor);
|
||||
|
||||
// Since FeatureNotified() returned false above, we are guaranteed that
|
||||
// the feature won't try to shutdown the actor until after we create the
|
||||
// Cache DOM object in the listener's RecvOpenResponse() method. This
|
||||
// is important because StartShutdown() expects a Cache object listener.
|
||||
if (cacheChild) {
|
||||
cacheChild->SetFeature(GetFeature());
|
||||
}
|
||||
|
||||
listener->RecvOpenResponse(aRequestId, aRv, cacheChild);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheStorageChild::RecvDeleteResponse(const RequestId& aRequestId,
|
||||
const nsresult& aRv,
|
||||
const bool& aResult)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorageChild);
|
||||
nsRefPtr<CacheStorage> listener = mListener;
|
||||
if (listener) {
|
||||
listener->RecvDeleteResponse(aRequestId, aRv, aResult);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheStorageChild::RecvKeysResponse(const RequestId& aRequestId,
|
||||
const nsresult& aRv,
|
||||
nsTArray<nsString>&& aKeys)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStorageChild);
|
||||
nsRefPtr<CacheStorage> listener = mListener;
|
||||
if (listener) {
|
||||
listener->RecvKeysResponse(aRequestId, aRv, aKeys);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace cache
|
||||
|
|
|
@ -11,10 +11,16 @@
|
|||
#include "mozilla/dom/cache/Types.h"
|
||||
#include "mozilla/dom/cache/PCacheStorageChild.h"
|
||||
|
||||
class nsIGlobalObject;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class Promise;
|
||||
|
||||
namespace cache {
|
||||
|
||||
class CacheOpArgs;
|
||||
class CacheStorage;
|
||||
class PCacheChild;
|
||||
class Feature;
|
||||
|
@ -27,11 +33,15 @@ public:
|
|||
~CacheStorageChild();
|
||||
|
||||
// Must be called by the associated CacheStorage listener in its
|
||||
// ActorDestroy() method. Also, CacheStorage must Send__delete__() the
|
||||
// ActorDestroy() method. Also, CacheStorage must call SendDestroy() on the
|
||||
// actor in its destructor to trigger ActorDestroy() if it has not been
|
||||
// called yet.
|
||||
void ClearListener();
|
||||
|
||||
void
|
||||
ExecuteOp(nsIGlobalObject* aGlobal, Promise* aPromise,
|
||||
const CacheOpArgs& aArgs);
|
||||
|
||||
// ActorChild methods
|
||||
|
||||
// Synchronously call ActorDestroy on our CacheStorage listener and then start
|
||||
|
@ -42,26 +52,21 @@ private:
|
|||
// PCacheStorageChild methods
|
||||
virtual void ActorDestroy(ActorDestroyReason aReason) override;
|
||||
|
||||
virtual bool RecvMatchResponse(const RequestId& aRequestId,
|
||||
const nsresult& aRv,
|
||||
const PCacheResponseOrVoid& response) override;
|
||||
virtual bool RecvHasResponse(const cache::RequestId& aRequestId,
|
||||
const nsresult& aRv,
|
||||
const bool& aSuccess) override;
|
||||
virtual bool RecvOpenResponse(const cache::RequestId& aRequestId,
|
||||
const nsresult& aRv,
|
||||
PCacheChild* aActor) override;
|
||||
virtual bool RecvDeleteResponse(const cache::RequestId& aRequestId,
|
||||
const nsresult& aRv,
|
||||
const bool& aResult) override;
|
||||
virtual bool RecvKeysResponse(const cache::RequestId& aRequestId,
|
||||
const nsresult& aRv,
|
||||
nsTArray<nsString>&& aKeys) override;
|
||||
virtual PCacheOpChild*
|
||||
AllocPCacheOpChild(const CacheOpArgs& aOpArgs) override;
|
||||
|
||||
virtual bool
|
||||
DeallocPCacheOpChild(PCacheOpChild* aActor) override;
|
||||
|
||||
// utility methods
|
||||
void
|
||||
NoteDeletedActor();
|
||||
|
||||
// Use a weak ref so actor does not hold DOM object alive past content use.
|
||||
// The CacheStorage object must call ClearListener() to null this before its
|
||||
// destroyed.
|
||||
CacheStorage* MOZ_NON_OWNING_REF mListener;
|
||||
uint32_t mNumChildActors;
|
||||
|
||||
NS_DECL_OWNINGTHREAD
|
||||
};
|
||||
|
|
|
@ -6,28 +6,18 @@
|
|||
|
||||
#include "mozilla/dom/cache/CacheStorageParent.h"
|
||||
|
||||
#include "mozilla/unused.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/dom/cache/ActorUtils.h"
|
||||
#include "mozilla/dom/cache/AutoUtils.h"
|
||||
#include "mozilla/dom/cache/CacheParent.h"
|
||||
#include "mozilla/dom/cache/CacheStreamControlParent.h"
|
||||
#include "mozilla/dom/cache/Manager.h"
|
||||
#include "mozilla/dom/cache/CacheOpParent.h"
|
||||
#include "mozilla/dom/cache/ManagerId.h"
|
||||
#include "mozilla/dom/cache/ReadStream.h"
|
||||
#include "mozilla/dom/cache/SavedTypes.h"
|
||||
#include "mozilla/dom/cache/StreamList.h"
|
||||
#include "mozilla/ipc/PBackgroundParent.h"
|
||||
#include "mozilla/ipc/InputStreamUtils.h"
|
||||
#include "mozilla/ipc/PFileDescriptorSetParent.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
using mozilla::ipc::PBackgroundParent;
|
||||
using mozilla::ipc::PFileDescriptorSetParent;
|
||||
using mozilla::ipc::PrincipalInfo;
|
||||
|
||||
// declared in ActorUtils.h
|
||||
|
@ -65,22 +55,60 @@ CacheStorageParent::~CacheStorageParent()
|
|||
{
|
||||
MOZ_COUNT_DTOR(cache::CacheStorageParent);
|
||||
MOZ_ASSERT(!mVerifier);
|
||||
MOZ_ASSERT(!mManager);
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorageParent::ActorDestroy(ActorDestroyReason aReason)
|
||||
{
|
||||
if (mVerifier) {
|
||||
mVerifier->ClearListener();
|
||||
mVerifier->RemoveListener(this);
|
||||
mVerifier = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (mManager) {
|
||||
MOZ_ASSERT(!mActiveRequests.IsEmpty());
|
||||
mManager->RemoveListener(this);
|
||||
mManager = nullptr;
|
||||
PCacheOpParent*
|
||||
CacheStorageParent::AllocPCacheOpParent(const CacheOpArgs& aOpArgs)
|
||||
{
|
||||
if (aOpArgs.type() != CacheOpArgs::TStorageMatchArgs &&
|
||||
aOpArgs.type() != CacheOpArgs::TStorageHasArgs &&
|
||||
aOpArgs.type() != CacheOpArgs::TStorageOpenArgs &&
|
||||
aOpArgs.type() != CacheOpArgs::TStorageDeleteArgs &&
|
||||
aOpArgs.type() != CacheOpArgs::TStorageKeysArgs)
|
||||
{
|
||||
MOZ_CRASH("Invalid operation sent to CacheStorage actor!");
|
||||
}
|
||||
|
||||
return new CacheOpParent(Manager(), mNamespace, aOpArgs);
|
||||
}
|
||||
|
||||
bool
|
||||
CacheStorageParent::DeallocPCacheOpParent(PCacheOpParent* aActor)
|
||||
{
|
||||
delete aActor;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheStorageParent::RecvPCacheOpConstructor(PCacheOpParent* aActor,
|
||||
const CacheOpArgs& aOpArgs)
|
||||
{
|
||||
auto actor = static_cast<CacheOpParent*>(aActor);
|
||||
|
||||
if (mVerifier) {
|
||||
MOZ_ASSERT(!mManagerId);
|
||||
actor->WaitForVerification(mVerifier);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (NS_FAILED(mVerifiedStatus)) {
|
||||
unused << CacheOpParent::Send__delete__(actor, ErrorResult(mVerifiedStatus),
|
||||
void_t());
|
||||
return true;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mManagerId);
|
||||
actor->Execute(mManagerId);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -93,190 +121,11 @@ CacheStorageParent::RecvTeardown()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheStorageParent::RecvMatch(const RequestId& aRequestId,
|
||||
const PCacheRequest& aRequest,
|
||||
const PCacheQueryParams& aParams)
|
||||
{
|
||||
if (NS_WARN_IF(NS_FAILED(mVerifiedStatus))) {
|
||||
if (!SendMatchResponse(aRequestId, mVerifiedStatus, void_t())) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Match response.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// queue requests if we are still waiting for principal verification
|
||||
if (!mManagerId) {
|
||||
Entry* entry = mPendingRequests.AppendElement();
|
||||
entry->mOp = OP_MATCH;
|
||||
entry->mRequestId = aRequestId;
|
||||
entry->mRequest = aRequest;
|
||||
entry->mParams = aParams;
|
||||
return true;
|
||||
}
|
||||
|
||||
nsRefPtr<cache::Manager> manager;
|
||||
nsresult rv = RequestManager(aRequestId, getter_AddRefs(manager));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
if (!SendMatchResponse(aRequestId, rv, void_t())) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Match response.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
manager->StorageMatch(this, aRequestId, mNamespace, aRequest,
|
||||
aParams);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheStorageParent::RecvHas(const RequestId& aRequestId, const nsString& aKey)
|
||||
{
|
||||
if (NS_WARN_IF(NS_FAILED(mVerifiedStatus))) {
|
||||
if (!SendHasResponse(aRequestId, mVerifiedStatus, false)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Has response.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// queue requests if we are still waiting for principal verification
|
||||
if (!mManagerId) {
|
||||
Entry* entry = mPendingRequests.AppendElement();
|
||||
entry->mOp = OP_HAS;
|
||||
entry->mRequestId = aRequestId;
|
||||
entry->mKey = aKey;
|
||||
return true;
|
||||
}
|
||||
|
||||
nsRefPtr<cache::Manager> manager;
|
||||
nsresult rv = RequestManager(aRequestId, getter_AddRefs(manager));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
if (!SendHasResponse(aRequestId, rv, false)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Has response.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
manager->StorageHas(this, aRequestId, mNamespace, aKey);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheStorageParent::RecvOpen(const RequestId& aRequestId, const nsString& aKey)
|
||||
{
|
||||
if (NS_WARN_IF(NS_FAILED(mVerifiedStatus))) {
|
||||
if (!SendOpenResponse(aRequestId, mVerifiedStatus, nullptr)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Open response.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// queue requests if we are still waiting for principal verification
|
||||
if (!mManagerId) {
|
||||
Entry* entry = mPendingRequests.AppendElement();
|
||||
entry->mOp = OP_OPEN;
|
||||
entry->mRequestId = aRequestId;
|
||||
entry->mKey = aKey;
|
||||
return true;
|
||||
}
|
||||
|
||||
nsRefPtr<cache::Manager> manager;
|
||||
nsresult rv = RequestManager(aRequestId, getter_AddRefs(manager));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
if (!SendOpenResponse(aRequestId, rv, nullptr)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Open response.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
manager->StorageOpen(this, aRequestId, mNamespace, aKey);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheStorageParent::RecvDelete(const RequestId& aRequestId,
|
||||
const nsString& aKey)
|
||||
{
|
||||
if (NS_WARN_IF(NS_FAILED(mVerifiedStatus))) {
|
||||
if (!SendDeleteResponse(aRequestId, mVerifiedStatus, false)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Delete response.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// queue requests if we are still waiting for principal verification
|
||||
if (!mManagerId) {
|
||||
Entry* entry = mPendingRequests.AppendElement();
|
||||
entry->mOp = OP_DELETE;
|
||||
entry->mRequestId = aRequestId;
|
||||
entry->mKey = aKey;
|
||||
return true;
|
||||
}
|
||||
|
||||
nsRefPtr<cache::Manager> manager;
|
||||
nsresult rv = RequestManager(aRequestId, getter_AddRefs(manager));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
if (!SendDeleteResponse(aRequestId, rv, false)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Delete response.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
manager->StorageDelete(this, aRequestId, mNamespace, aKey);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CacheStorageParent::RecvKeys(const RequestId& aRequestId)
|
||||
{
|
||||
if (NS_WARN_IF(NS_FAILED(mVerifiedStatus))) {
|
||||
if (!SendKeysResponse(aRequestId, mVerifiedStatus, nsTArray<nsString>())) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Keys response.");
|
||||
}
|
||||
}
|
||||
|
||||
// queue requests if we are still waiting for principal verification
|
||||
if (!mManagerId) {
|
||||
Entry* entry = mPendingRequests.AppendElement();
|
||||
entry->mOp = OP_DELETE;
|
||||
entry->mRequestId = aRequestId;
|
||||
return true;
|
||||
}
|
||||
|
||||
nsRefPtr<cache::Manager> manager;
|
||||
nsresult rv = RequestManager(aRequestId, getter_AddRefs(manager));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
if (!SendKeysResponse(aRequestId, rv, nsTArray<nsString>())) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Keys response.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
manager->StorageKeys(this, aRequestId, mNamespace);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorageParent::OnPrincipalVerified(nsresult aRv, ManagerId* aManagerId)
|
||||
{
|
||||
MOZ_ASSERT(mVerifier);
|
||||
MOZ_ASSERT(!mManagerId);
|
||||
MOZ_ASSERT(!mManager);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(mVerifiedStatus));
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(aRv))) {
|
||||
|
@ -284,165 +133,8 @@ CacheStorageParent::OnPrincipalVerified(nsresult aRv, ManagerId* aManagerId)
|
|||
}
|
||||
|
||||
mManagerId = aManagerId;
|
||||
mVerifier->ClearListener();
|
||||
mVerifier->RemoveListener(this);
|
||||
mVerifier = nullptr;
|
||||
|
||||
RetryPendingRequests();
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorageParent::OnStorageMatch(RequestId aRequestId, nsresult aRv,
|
||||
const SavedResponse* aSavedResponse,
|
||||
StreamList* aStreamList)
|
||||
{
|
||||
PCacheResponseOrVoid responseOrVoid;
|
||||
|
||||
ReleaseManager(aRequestId);
|
||||
|
||||
AutoParentResponseOrVoid response(Manager());
|
||||
|
||||
// no match
|
||||
if (NS_FAILED(aRv) || !aSavedResponse) {
|
||||
if (!SendMatchResponse(aRequestId, aRv, response.SendAsResponseOrVoid())) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Match response.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (aSavedResponse) {
|
||||
response.Add(*aSavedResponse, aStreamList);
|
||||
}
|
||||
|
||||
if (!SendMatchResponse(aRequestId, aRv, response.SendAsResponseOrVoid())) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Match response.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorageParent::OnStorageHas(RequestId aRequestId, nsresult aRv,
|
||||
bool aCacheFound)
|
||||
{
|
||||
ReleaseManager(aRequestId);
|
||||
if (!SendHasResponse(aRequestId, aRv, aCacheFound)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Has response.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorageParent::OnStorageOpen(RequestId aRequestId, nsresult aRv,
|
||||
CacheId aCacheId)
|
||||
{
|
||||
if (NS_FAILED(aRv)) {
|
||||
ReleaseManager(aRequestId);
|
||||
if (!SendOpenResponse(aRequestId, aRv, nullptr)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Open response.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mManager);
|
||||
CacheParent* actor = new CacheParent(mManager, aCacheId);
|
||||
|
||||
ReleaseManager(aRequestId);
|
||||
|
||||
PCacheParent* base = Manager()->SendPCacheConstructor(actor);
|
||||
actor = static_cast<CacheParent*>(base);
|
||||
if (!SendOpenResponse(aRequestId, aRv, actor)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Open response.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorageParent::OnStorageDelete(RequestId aRequestId, nsresult aRv,
|
||||
bool aCacheDeleted)
|
||||
{
|
||||
ReleaseManager(aRequestId);
|
||||
if (!SendDeleteResponse(aRequestId, aRv, aCacheDeleted)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Delete response.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorageParent::OnStorageKeys(RequestId aRequestId, nsresult aRv,
|
||||
const nsTArray<nsString>& aKeys)
|
||||
{
|
||||
ReleaseManager(aRequestId);
|
||||
if (!SendKeysResponse(aRequestId, aRv, aKeys)) {
|
||||
// child process is gone, warn and allow actor to clean up normally
|
||||
NS_WARNING("CacheStorage failed to send Keys response.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorageParent::RetryPendingRequests()
|
||||
{
|
||||
MOZ_ASSERT(mManagerId || NS_FAILED(mVerifiedStatus));
|
||||
for (uint32_t i = 0; i < mPendingRequests.Length(); ++i) {
|
||||
const Entry& entry = mPendingRequests[i];
|
||||
switch(entry.mOp) {
|
||||
case OP_MATCH:
|
||||
RecvMatch(entry.mRequestId, entry.mRequest, entry.mParams);
|
||||
break;
|
||||
case OP_HAS:
|
||||
RecvHas(entry.mRequestId, entry.mKey);
|
||||
break;
|
||||
case OP_OPEN:
|
||||
RecvOpen(entry.mRequestId, entry.mKey);
|
||||
break;
|
||||
case OP_DELETE:
|
||||
RecvDelete(entry.mRequestId, entry.mKey);
|
||||
break;
|
||||
case OP_KEYS:
|
||||
RecvKeys(entry.mRequestId);
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Pending request within unknown op");
|
||||
}
|
||||
}
|
||||
mPendingRequests.Clear();
|
||||
mPendingRequests.Compact();
|
||||
}
|
||||
|
||||
nsresult
|
||||
CacheStorageParent::RequestManager(RequestId aRequestId,
|
||||
cache::Manager** aManagerOut)
|
||||
{
|
||||
MOZ_ASSERT(!mActiveRequests.Contains(aRequestId));
|
||||
nsRefPtr<cache::Manager> ref = mManager;
|
||||
if (!ref) {
|
||||
MOZ_ASSERT(mActiveRequests.IsEmpty());
|
||||
nsresult rv = cache::Manager::GetOrCreate(mManagerId, getter_AddRefs(ref));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
mManager = ref;
|
||||
}
|
||||
mActiveRequests.AppendElement(aRequestId);
|
||||
ref.forget(aManagerOut);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
CacheStorageParent::ReleaseManager(RequestId aRequestId)
|
||||
{
|
||||
// Note that if the child process dies we also clean up the mManager in
|
||||
// ActorDestroy(). There is no race with this method, however, because
|
||||
// ActorDestroy removes this object from the Manager's listener list.
|
||||
// Therefore ReleaseManager() should never be called after ActorDestroy()
|
||||
// runs.
|
||||
MOZ_ASSERT(mManager);
|
||||
MOZ_ASSERT(!mActiveRequests.IsEmpty());
|
||||
|
||||
MOZ_ALWAYS_TRUE(mActiveRequests.RemoveElement(aRequestId));
|
||||
|
||||
if (mActiveRequests.IsEmpty()) {
|
||||
mManager->RemoveListener(this);
|
||||
mManager = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace cache
|
||||
|
|
|
@ -7,24 +7,18 @@
|
|||
#ifndef mozilla_dom_cache_CacheStorageParent_h
|
||||
#define mozilla_dom_cache_CacheStorageParent_h
|
||||
|
||||
#include "mozilla/dom/cache/CacheInitData.h"
|
||||
#include "mozilla/dom/cache/PCacheStorageParent.h"
|
||||
#include "mozilla/dom/cache/Manager.h"
|
||||
#include "mozilla/dom/cache/PrincipalVerifier.h"
|
||||
#include "mozilla/dom/cache/Types.h"
|
||||
|
||||
template <class T> class nsRefPtr;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
class CacheStreamControlParent;
|
||||
class ManagerId;
|
||||
|
||||
class CacheStorageParent final : public PCacheStorageParent
|
||||
, public PrincipalVerifier::Listener
|
||||
, public Manager::Listener
|
||||
{
|
||||
public:
|
||||
CacheStorageParent(PBackgroundParent* aManagingActor, Namespace aNamespace,
|
||||
|
@ -33,72 +27,30 @@ public:
|
|||
|
||||
private:
|
||||
// PCacheStorageParent methods
|
||||
virtual void ActorDestroy(ActorDestroyReason aReason) override;
|
||||
virtual bool RecvTeardown() override;
|
||||
virtual bool RecvMatch(const RequestId& aRequestId,
|
||||
const PCacheRequest& aRequest,
|
||||
const PCacheQueryParams& aParams) override;
|
||||
virtual bool RecvHas(const RequestId& aRequestId,
|
||||
const nsString& aKey) override;
|
||||
virtual bool RecvOpen(const RequestId& aRequestId,
|
||||
const nsString& aKey) override;
|
||||
virtual bool RecvDelete(const RequestId& aRequestId,
|
||||
const nsString& aKey) override;
|
||||
virtual bool RecvKeys(const RequestId& aRequestId) override;
|
||||
virtual void
|
||||
ActorDestroy(ActorDestroyReason aReason) override;
|
||||
|
||||
virtual PCacheOpParent*
|
||||
AllocPCacheOpParent(const CacheOpArgs& aOpArgs) override;
|
||||
|
||||
virtual bool
|
||||
DeallocPCacheOpParent(PCacheOpParent* aActor) override;
|
||||
|
||||
virtual bool
|
||||
RecvPCacheOpConstructor(PCacheOpParent* actor,
|
||||
const CacheOpArgs& aOpArgs) override;
|
||||
|
||||
virtual bool
|
||||
RecvTeardown() override;
|
||||
|
||||
// PrincipalVerifier::Listener methods
|
||||
virtual void OnPrincipalVerified(nsresult aRv,
|
||||
ManagerId* aManagerId) override;
|
||||
|
||||
// Manager::Listener methods
|
||||
virtual void OnStorageMatch(RequestId aRequestId, nsresult aRv,
|
||||
const SavedResponse* aResponse,
|
||||
StreamList* aStreamList) override;
|
||||
virtual void OnStorageHas(RequestId aRequestId, nsresult aRv,
|
||||
bool aCacheFound) override;
|
||||
virtual void OnStorageOpen(RequestId aRequestId, nsresult aRv,
|
||||
CacheId aCacheId) override;
|
||||
virtual void OnStorageDelete(RequestId aRequestId, nsresult aRv,
|
||||
bool aCacheDeleted) override;
|
||||
virtual void OnStorageKeys(RequestId aRequestId, nsresult aRv,
|
||||
const nsTArray<nsString>& aKeys) override;
|
||||
|
||||
CacheStreamControlParent*
|
||||
SerializeReadStream(CacheStreamControlParent *aStreamControl, const nsID& aId,
|
||||
StreamList* aStreamList,
|
||||
PCacheReadStream* aReadStreamOut);
|
||||
|
||||
void RetryPendingRequests();
|
||||
|
||||
nsresult RequestManager(RequestId aRequestId, cache::Manager** aManagerOut);
|
||||
void ReleaseManager(RequestId aRequestId);
|
||||
|
||||
const Namespace mNamespace;
|
||||
nsRefPtr<PrincipalVerifier> mVerifier;
|
||||
nsresult mVerifiedStatus;
|
||||
nsRefPtr<ManagerId> mManagerId;
|
||||
nsRefPtr<cache::Manager> mManager;
|
||||
|
||||
enum Op
|
||||
{
|
||||
OP_MATCH,
|
||||
OP_HAS,
|
||||
OP_OPEN,
|
||||
OP_DELETE,
|
||||
OP_KEYS
|
||||
};
|
||||
|
||||
struct Entry
|
||||
{
|
||||
Op mOp;
|
||||
RequestId mRequestId;
|
||||
nsString mKey;
|
||||
PCacheRequest mRequest;
|
||||
PCacheQueryParams mParams;
|
||||
};
|
||||
|
||||
nsTArray<Entry> mPendingRequests;
|
||||
nsTArray<RequestId> mActiveRequests;
|
||||
};
|
||||
|
||||
} // namesapce cache
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "mozilla/dom/cache/ActorUtils.h"
|
||||
#include "mozilla/dom/cache/PCacheTypes.h"
|
||||
#include "mozilla/dom/cache/CacheTypes.h"
|
||||
#include "mozilla/dom/cache/ReadStream.h"
|
||||
#include "mozilla/ipc/FileDescriptorSetChild.h"
|
||||
#include "mozilla/ipc/PBackgroundChild.h"
|
||||
|
@ -41,6 +41,7 @@ DeallocPCacheStreamControlChild(PCacheStreamControlChild* aActor)
|
|||
|
||||
CacheStreamControlChild::CacheStreamControlChild()
|
||||
: mDestroyStarted(false)
|
||||
, mDestroyDelayed(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(cache::CacheStreamControlChild);
|
||||
}
|
||||
|
@ -63,13 +64,28 @@ CacheStreamControlChild::StartDestroy()
|
|||
}
|
||||
mDestroyStarted = true;
|
||||
|
||||
// If any of the streams have started to be read, then wait for them to close
|
||||
// naturally.
|
||||
if (HasEverBeenRead()) {
|
||||
// Note that we are delaying so that we can re-check for active streams
|
||||
// in NoteClosedAfterForget().
|
||||
mDestroyDelayed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, if the streams have not been touched then just pre-emptively
|
||||
// close them now. This handles the case where someone retrieves a Response
|
||||
// from the Cache, but never accesses the body. We should not keep the
|
||||
// Worker alive until that Response is GC'd just because of its ignored
|
||||
// body stream.
|
||||
|
||||
// Begin shutting down all streams. This is the same as if the parent had
|
||||
// asked us to shutdown. So simulate the CloseAll IPC message.
|
||||
RecvCloseAll();
|
||||
}
|
||||
|
||||
void
|
||||
CacheStreamControlChild::SerializeControl(PCacheReadStream* aReadStreamOut)
|
||||
CacheStreamControlChild::SerializeControl(CacheReadStream* aReadStreamOut)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStreamControlChild);
|
||||
aReadStreamOut->controlParent() = nullptr;
|
||||
|
@ -77,7 +93,7 @@ CacheStreamControlChild::SerializeControl(PCacheReadStream* aReadStreamOut)
|
|||
}
|
||||
|
||||
void
|
||||
CacheStreamControlChild::SerializeFds(PCacheReadStream* aReadStreamOut,
|
||||
CacheStreamControlChild::SerializeFds(CacheReadStream* aReadStreamOut,
|
||||
const nsTArray<FileDescriptor>& aFds)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStreamControlChild);
|
||||
|
@ -97,7 +113,7 @@ CacheStreamControlChild::SerializeFds(PCacheReadStream* aReadStreamOut,
|
|||
}
|
||||
|
||||
void
|
||||
CacheStreamControlChild::DeserializeFds(const PCacheReadStream& aReadStream,
|
||||
CacheStreamControlChild::DeserializeFds(const CacheReadStream& aReadStream,
|
||||
nsTArray<FileDescriptor>& aFdsOut)
|
||||
{
|
||||
if (aReadStream.fds().type() !=
|
||||
|
@ -120,6 +136,15 @@ CacheStreamControlChild::NoteClosedAfterForget(const nsID& aId)
|
|||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStreamControlChild);
|
||||
unused << SendNoteClosed(aId);
|
||||
|
||||
// A stream has closed. If we delayed StartDestry() due to this stream
|
||||
// being read, then we should check to see if any of the remaining streams
|
||||
// are active. If none of our other streams have been read, then we can
|
||||
// proceed with the shutdown now.
|
||||
if (mDestroyDelayed && !HasEverBeenRead()) {
|
||||
mDestroyDelayed = false;
|
||||
RecvCloseAll();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
|
|
@ -31,14 +31,14 @@ public:
|
|||
|
||||
// StreamControl methods
|
||||
virtual void
|
||||
SerializeControl(PCacheReadStream* aReadStreamOut) override;
|
||||
SerializeControl(CacheReadStream* aReadStreamOut) override;
|
||||
|
||||
virtual void
|
||||
SerializeFds(PCacheReadStream* aReadStreamOut,
|
||||
SerializeFds(CacheReadStream* aReadStreamOut,
|
||||
const nsTArray<mozilla::ipc::FileDescriptor>& aFds) override;
|
||||
|
||||
virtual void
|
||||
DeserializeFds(const PCacheReadStream& aReadStream,
|
||||
DeserializeFds(const CacheReadStream& aReadStream,
|
||||
nsTArray<mozilla::ipc::FileDescriptor>& aFdsOut) override;
|
||||
|
||||
private:
|
||||
|
@ -56,6 +56,7 @@ private:
|
|||
virtual bool RecvCloseAll() override;
|
||||
|
||||
bool mDestroyStarted;
|
||||
bool mDestroyDelayed;
|
||||
|
||||
NS_DECL_OWNINGTHREAD
|
||||
};
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "mozilla/dom/cache/PCacheTypes.h"
|
||||
#include "mozilla/dom/cache/CacheTypes.h"
|
||||
#include "mozilla/dom/cache/ReadStream.h"
|
||||
#include "mozilla/dom/cache/StreamList.h"
|
||||
#include "mozilla/ipc/FileDescriptorSetParent.h"
|
||||
|
@ -45,7 +45,7 @@ CacheStreamControlParent::~CacheStreamControlParent()
|
|||
}
|
||||
|
||||
void
|
||||
CacheStreamControlParent::SerializeControl(PCacheReadStream* aReadStreamOut)
|
||||
CacheStreamControlParent::SerializeControl(CacheReadStream* aReadStreamOut)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStreamControlParent);
|
||||
aReadStreamOut->controlChild() = nullptr;
|
||||
|
@ -53,7 +53,7 @@ CacheStreamControlParent::SerializeControl(PCacheReadStream* aReadStreamOut)
|
|||
}
|
||||
|
||||
void
|
||||
CacheStreamControlParent::SerializeFds(PCacheReadStream* aReadStreamOut,
|
||||
CacheStreamControlParent::SerializeFds(CacheReadStream* aReadStreamOut,
|
||||
const nsTArray<FileDescriptor>& aFds)
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(CacheStreamControlParent);
|
||||
|
@ -73,7 +73,7 @@ CacheStreamControlParent::SerializeFds(PCacheReadStream* aReadStreamOut,
|
|||
}
|
||||
|
||||
void
|
||||
CacheStreamControlParent::DeserializeFds(const PCacheReadStream& aReadStream,
|
||||
CacheStreamControlParent::DeserializeFds(const CacheReadStream& aReadStream,
|
||||
nsTArray<FileDescriptor>& aFdsOut)
|
||||
{
|
||||
if (aReadStream.fds().type() !=
|
||||
|
|
|
@ -32,14 +32,14 @@ public:
|
|||
|
||||
// StreamControl methods
|
||||
virtual void
|
||||
SerializeControl(PCacheReadStream* aReadStreamOut) override;
|
||||
SerializeControl(CacheReadStream* aReadStreamOut) override;
|
||||
|
||||
virtual void
|
||||
SerializeFds(PCacheReadStream* aReadStreamOut,
|
||||
SerializeFds(CacheReadStream* aReadStreamOut,
|
||||
const nsTArray<mozilla::ipc::FileDescriptor>& aFds) override;
|
||||
|
||||
virtual void
|
||||
DeserializeFds(const PCacheReadStream& aReadStream,
|
||||
DeserializeFds(const CacheReadStream& aReadStream,
|
||||
nsTArray<mozilla::ipc::FileDescriptor>& aFdsOut) override;
|
||||
|
||||
private:
|
||||
|
|
|
@ -0,0 +1,244 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PCache;
|
||||
include protocol PCachePushStream;
|
||||
include protocol PCacheStreamControl;
|
||||
include InputStreamParams;
|
||||
|
||||
using HeadersGuardEnum from "mozilla/dom/cache/IPCUtils.h";
|
||||
using RequestCredentials from "mozilla/dom/cache/IPCUtils.h";
|
||||
using RequestMode from "mozilla/dom/cache/IPCUtils.h";
|
||||
using RequestCache from "mozilla/dom/cache/IPCUtils.h";
|
||||
using RequestContext from "mozilla/dom/cache/IPCUtils.h";
|
||||
using ResponseType from "mozilla/dom/cache/IPCUtils.h";
|
||||
using mozilla::void_t from "ipc/IPCMessageUtils.h";
|
||||
using struct nsID from "nsID.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
struct CacheQueryParams
|
||||
{
|
||||
bool ignoreSearch;
|
||||
bool ignoreMethod;
|
||||
bool ignoreVary;
|
||||
bool cacheNameSet;
|
||||
nsString cacheName;
|
||||
};
|
||||
|
||||
struct CacheReadStream
|
||||
{
|
||||
nsID id;
|
||||
OptionalInputStreamParams params;
|
||||
OptionalFileDescriptorSet fds;
|
||||
nullable PCacheStreamControl control;
|
||||
nullable PCachePushStream pushStream;
|
||||
};
|
||||
|
||||
union CacheReadStreamOrVoid
|
||||
{
|
||||
void_t;
|
||||
CacheReadStream;
|
||||
};
|
||||
|
||||
struct HeadersEntry
|
||||
{
|
||||
nsCString name;
|
||||
nsCString value;
|
||||
};
|
||||
|
||||
struct CacheRequest
|
||||
{
|
||||
nsCString method;
|
||||
nsString url;
|
||||
nsString urlWithoutQuery;
|
||||
HeadersEntry[] headers;
|
||||
HeadersGuardEnum headersGuard;
|
||||
nsString referrer;
|
||||
RequestMode mode;
|
||||
RequestCredentials credentials;
|
||||
CacheReadStreamOrVoid body;
|
||||
uint32_t contentPolicyType;
|
||||
RequestContext context;
|
||||
RequestCache requestCache;
|
||||
};
|
||||
|
||||
union CacheRequestOrVoid
|
||||
{
|
||||
void_t;
|
||||
CacheRequest;
|
||||
};
|
||||
|
||||
struct CacheResponse
|
||||
{
|
||||
ResponseType type;
|
||||
nsString url;
|
||||
uint32_t status;
|
||||
nsCString statusText;
|
||||
HeadersEntry[] headers;
|
||||
HeadersGuardEnum headersGuard;
|
||||
CacheReadStreamOrVoid body;
|
||||
nsCString securityInfo;
|
||||
};
|
||||
|
||||
union CacheResponseOrVoid
|
||||
{
|
||||
void_t;
|
||||
CacheResponse;
|
||||
};
|
||||
|
||||
struct CacheRequestResponse
|
||||
{
|
||||
CacheRequest request;
|
||||
CacheResponse response;
|
||||
};
|
||||
|
||||
struct CacheMatchArgs
|
||||
{
|
||||
CacheRequest request;
|
||||
CacheQueryParams params;
|
||||
};
|
||||
|
||||
struct CacheMatchAllArgs
|
||||
{
|
||||
CacheRequestOrVoid requestOrVoid;
|
||||
CacheQueryParams params;
|
||||
};
|
||||
|
||||
struct CacheAddAllArgs
|
||||
{
|
||||
CacheRequest[] requestList;
|
||||
};
|
||||
|
||||
struct CachePutAllArgs
|
||||
{
|
||||
CacheRequestResponse[] requestResponseList;
|
||||
};
|
||||
|
||||
struct CacheDeleteArgs
|
||||
{
|
||||
CacheRequest request;
|
||||
CacheQueryParams params;
|
||||
};
|
||||
|
||||
struct CacheKeysArgs
|
||||
{
|
||||
CacheRequestOrVoid requestOrVoid;
|
||||
CacheQueryParams params;
|
||||
};
|
||||
|
||||
struct StorageMatchArgs
|
||||
{
|
||||
CacheRequest request;
|
||||
CacheQueryParams params;
|
||||
};
|
||||
|
||||
struct StorageHasArgs
|
||||
{
|
||||
nsString key;
|
||||
};
|
||||
|
||||
struct StorageOpenArgs
|
||||
{
|
||||
nsString key;
|
||||
};
|
||||
|
||||
struct StorageDeleteArgs
|
||||
{
|
||||
nsString key;
|
||||
};
|
||||
|
||||
struct StorageKeysArgs
|
||||
{
|
||||
};
|
||||
|
||||
union CacheOpArgs
|
||||
{
|
||||
CacheMatchArgs;
|
||||
CacheMatchAllArgs;
|
||||
CacheAddAllArgs;
|
||||
CachePutAllArgs;
|
||||
CacheDeleteArgs;
|
||||
CacheKeysArgs;
|
||||
StorageMatchArgs;
|
||||
StorageHasArgs;
|
||||
StorageOpenArgs;
|
||||
StorageDeleteArgs;
|
||||
StorageKeysArgs;
|
||||
};
|
||||
|
||||
struct CacheMatchResult
|
||||
{
|
||||
CacheResponseOrVoid responseOrVoid;
|
||||
};
|
||||
|
||||
struct CacheMatchAllResult
|
||||
{
|
||||
CacheResponse[] responseList;
|
||||
};
|
||||
|
||||
struct CacheAddAllResult
|
||||
{
|
||||
};
|
||||
|
||||
struct CachePutAllResult
|
||||
{
|
||||
};
|
||||
|
||||
struct CacheDeleteResult
|
||||
{
|
||||
bool success;
|
||||
};
|
||||
|
||||
struct CacheKeysResult
|
||||
{
|
||||
CacheRequest[] requestList;
|
||||
};
|
||||
|
||||
struct StorageMatchResult
|
||||
{
|
||||
CacheResponseOrVoid responseOrVoid;
|
||||
};
|
||||
|
||||
struct StorageHasResult
|
||||
{
|
||||
bool success;
|
||||
};
|
||||
|
||||
struct StorageOpenResult
|
||||
{
|
||||
nullable PCache actor;
|
||||
};
|
||||
|
||||
struct StorageDeleteResult
|
||||
{
|
||||
bool success;
|
||||
};
|
||||
|
||||
struct StorageKeysResult
|
||||
{
|
||||
nsString[] keyList;
|
||||
};
|
||||
|
||||
union CacheOpResult
|
||||
{
|
||||
void_t;
|
||||
CacheMatchResult;
|
||||
CacheMatchAllResult;
|
||||
CacheAddAllResult;
|
||||
CachePutAllResult;
|
||||
CacheDeleteResult;
|
||||
CacheKeysResult;
|
||||
StorageMatchResult;
|
||||
StorageHasResult;
|
||||
StorageOpenResult;
|
||||
StorageDeleteResult;
|
||||
StorageKeysResult;
|
||||
};
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
|
@ -732,6 +732,7 @@ Context::Dispatch(nsIEventTarget* aTarget, Action* aAction)
|
|||
MOZ_ASSERT(aTarget);
|
||||
MOZ_ASSERT(aAction);
|
||||
|
||||
MOZ_ASSERT(mState != STATE_CONTEXT_CANCELED);
|
||||
if (mState == STATE_CONTEXT_CANCELED) {
|
||||
return;
|
||||
} else if (mState == STATE_CONTEXT_INIT) {
|
||||
|
@ -766,11 +767,18 @@ Context::CancelAll()
|
|||
AllowToClose();
|
||||
}
|
||||
|
||||
bool
|
||||
Context::IsCanceled() const
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(Context);
|
||||
return mState == STATE_CONTEXT_CANCELED;
|
||||
}
|
||||
|
||||
void
|
||||
Context::Invalidate()
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(Context);
|
||||
mManager->Invalidate();
|
||||
mManager->NoteClosing();
|
||||
CancelAll();
|
||||
}
|
||||
|
||||
|
|
|
@ -126,6 +126,9 @@ public:
|
|||
// Only callable from the thread that created the Context.
|
||||
void CancelAll();
|
||||
|
||||
// True if CancelAll() has been called.
|
||||
bool IsCanceled() const;
|
||||
|
||||
// Like CancelAll(), but also marks the Manager as "invalid".
|
||||
void Invalidate();
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "nsIFile.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "DBSchema.h"
|
||||
#include "FileUtils.h"
|
||||
|
||||
|
@ -146,7 +147,7 @@ DBAction::OpenConnection(const QuotaInfo& aQuotaInfo, nsIFile* aDBDir,
|
|||
int32_t schemaVersion = 0;
|
||||
rv = conn->GetSchemaVersion(&schemaVersion);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
if (schemaVersion > 0 && schemaVersion < DBSchema::kMaxWipeSchemaVersion) {
|
||||
if (schemaVersion > 0 && schemaVersion < db::kMaxWipeSchemaVersion) {
|
||||
conn = nullptr;
|
||||
rv = WipeDatabase(dbFile, aDBDir);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
@ -154,7 +155,7 @@ DBAction::OpenConnection(const QuotaInfo& aQuotaInfo, nsIFile* aDBDir,
|
|||
rv = ss->OpenDatabaseWithFileURL(dbFileUrl, getter_AddRefs(conn));
|
||||
}
|
||||
|
||||
rv = DBSchema::InitializeConnection(conn);
|
||||
rv = db::InitializeConnection(conn);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
conn.forget(aConnOut);
|
||||
|
@ -169,7 +170,7 @@ DBAction::WipeDatabase(nsIFile* aDBFile, nsIFile* aDBDir)
|
|||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
// Delete the morgue as well.
|
||||
rv = FileUtils::BodyDeleteDir(aDBDir);
|
||||
rv = BodyDeleteDir(aDBDir);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
return rv;
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#define mozilla_dom_cache_DBAction_h
|
||||
|
||||
#include "mozilla/dom/cache/Action.h"
|
||||
#include "mozilla/dom/cache/CacheInitData.h"
|
||||
#include "nsRefPtr.h"
|
||||
#include "nsString.h"
|
||||
|
||||
|
|
|
@ -8,8 +8,10 @@
|
|||
|
||||
#include "ipc/IPCMessageUtils.h"
|
||||
#include "mozilla/dom/InternalHeaders.h"
|
||||
#include "mozilla/dom/cache/PCacheTypes.h"
|
||||
#include "mozilla/dom/cache/CacheTypes.h"
|
||||
#include "mozilla/dom/cache/SavedTypes.h"
|
||||
#include "mozilla/dom/cache/Types.h"
|
||||
#include "mozilla/dom/cache/TypeUtils.h"
|
||||
#include "mozIStorageConnection.h"
|
||||
#include "mozIStorageStatement.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
@ -19,16 +21,21 @@
|
|||
#include "mozilla/dom/HeadersBinding.h"
|
||||
#include "mozilla/dom/RequestBinding.h"
|
||||
#include "mozilla/dom/ResponseBinding.h"
|
||||
#include "Types.h"
|
||||
#include "nsIContentPolicy.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
namespace db {
|
||||
|
||||
const int32_t DBSchema::kMaxWipeSchemaVersion = 6;
|
||||
const int32_t DBSchema::kLatestSchemaVersion = 6;
|
||||
const int32_t DBSchema::kMaxEntriesPerStatement = 255;
|
||||
const int32_t kMaxWipeSchemaVersion = 6;
|
||||
|
||||
namespace {
|
||||
|
||||
const int32_t kLatestSchemaVersion = 6;
|
||||
const int32_t kMaxEntriesPerStatement = 255;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// If any of the static_asserts below fail, it means that you have changed
|
||||
// the corresponding WebIDL enum in a way that may be incompatible with the
|
||||
|
@ -140,11 +147,48 @@ static_assert(nsIContentPolicy::TYPE_INVALID == 0 &&
|
|||
nsIContentPolicy::TYPE_IMAGESET == 21,
|
||||
"nsContentPolicytType values are as expected");
|
||||
|
||||
using mozilla::void_t;
|
||||
namespace {
|
||||
|
||||
typedef int32_t EntryId;
|
||||
|
||||
static nsresult QueryAll(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
nsTArray<EntryId>& aEntryIdListOut);
|
||||
static nsresult QueryCache(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
const CacheRequest& aRequest,
|
||||
const CacheQueryParams& aParams,
|
||||
nsTArray<EntryId>& aEntryIdListOut,
|
||||
uint32_t aMaxResults = UINT32_MAX);
|
||||
static nsresult MatchByVaryHeader(mozIStorageConnection* aConn,
|
||||
const CacheRequest& aRequest,
|
||||
EntryId entryId, bool* aSuccessOut);
|
||||
static nsresult DeleteEntries(mozIStorageConnection* aConn,
|
||||
const nsTArray<EntryId>& aEntryIdList,
|
||||
nsTArray<nsID>& aDeletedBodyIdListOut,
|
||||
uint32_t aPos=0, int32_t aLen=-1);
|
||||
static nsresult InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
const CacheRequest& aRequest,
|
||||
const nsID* aRequestBodyId,
|
||||
const CacheResponse& aResponse,
|
||||
const nsID* aResponseBodyId);
|
||||
static nsresult ReadResponse(mozIStorageConnection* aConn, EntryId aEntryId,
|
||||
SavedResponse* aSavedResponseOut);
|
||||
static nsresult ReadRequest(mozIStorageConnection* aConn, EntryId aEntryId,
|
||||
SavedRequest* aSavedRequestOut);
|
||||
|
||||
static void AppendListParamsToQuery(nsACString& aQuery,
|
||||
const nsTArray<EntryId>& aEntryIdList,
|
||||
uint32_t aPos, int32_t aLen);
|
||||
static nsresult BindListParamsToQuery(mozIStorageStatement* aState,
|
||||
const nsTArray<EntryId>& aEntryIdList,
|
||||
uint32_t aPos, int32_t aLen);
|
||||
static nsresult BindId(mozIStorageStatement* aState, uint32_t aPos,
|
||||
const nsID* aId);
|
||||
static nsresult ExtractId(mozIStorageStatement* aState, uint32_t aPos,
|
||||
nsID* aIdOut);
|
||||
} // anonymous namespace
|
||||
|
||||
// static
|
||||
nsresult
|
||||
DBSchema::CreateSchema(mozIStorageConnection* aConn)
|
||||
CreateSchema(mozIStorageConnection* aConn)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aConn);
|
||||
|
@ -284,9 +328,8 @@ DBSchema::CreateSchema(mozIStorageConnection* aConn)
|
|||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
DBSchema::InitializeConnection(mozIStorageConnection* aConn)
|
||||
InitializeConnection(mozIStorageConnection* aConn)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aConn);
|
||||
|
@ -315,9 +358,8 @@ DBSchema::InitializeConnection(mozIStorageConnection* aConn)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
DBSchema::CreateCache(mozIStorageConnection* aConn, CacheId* aCacheIdOut)
|
||||
CreateCacheId(mozIStorageConnection* aConn, CacheId* aCacheIdOut)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aConn);
|
||||
|
@ -345,10 +387,9 @@ DBSchema::CreateCache(mozIStorageConnection* aConn, CacheId* aCacheIdOut)
|
|||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
DBSchema::DeleteCache(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
nsTArray<nsID>& aDeletedBodyIdListOut)
|
||||
DeleteCacheId(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
nsTArray<nsID>& aDeletedBodyIdListOut)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aConn);
|
||||
|
@ -379,10 +420,9 @@ DBSchema::DeleteCache(mozIStorageConnection* aConn, CacheId aCacheId,
|
|||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
DBSchema::IsCacheOrphaned(mozIStorageConnection* aConn,
|
||||
CacheId aCacheId, bool* aOrphanedOut)
|
||||
IsCacheOrphaned(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
bool* aOrphanedOut)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aConn);
|
||||
|
@ -414,13 +454,12 @@ DBSchema::IsCacheOrphaned(mozIStorageConnection* aConn,
|
|||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
DBSchema::CacheMatch(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
const PCacheRequest& aRequest,
|
||||
const PCacheQueryParams& aParams,
|
||||
bool* aFoundResponseOut,
|
||||
SavedResponse* aSavedResponseOut)
|
||||
CacheMatch(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
const CacheRequest& aRequest,
|
||||
const CacheQueryParams& aParams,
|
||||
bool* aFoundResponseOut,
|
||||
SavedResponse* aSavedResponseOut)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aConn);
|
||||
|
@ -446,19 +485,18 @@ DBSchema::CacheMatch(mozIStorageConnection* aConn, CacheId aCacheId,
|
|||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
DBSchema::CacheMatchAll(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
const PCacheRequestOrVoid& aRequestOrVoid,
|
||||
const PCacheQueryParams& aParams,
|
||||
nsTArray<SavedResponse>& aSavedResponsesOut)
|
||||
CacheMatchAll(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
const CacheRequestOrVoid& aRequestOrVoid,
|
||||
const CacheQueryParams& aParams,
|
||||
nsTArray<SavedResponse>& aSavedResponsesOut)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aConn);
|
||||
nsresult rv;
|
||||
|
||||
nsAutoTArray<EntryId, 256> matches;
|
||||
if (aRequestOrVoid.type() == PCacheRequestOrVoid::Tvoid_t) {
|
||||
if (aRequestOrVoid.type() == CacheRequestOrVoid::Tvoid_t) {
|
||||
rv = QueryAll(aConn, aCacheId, matches);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
} else {
|
||||
|
@ -478,19 +516,18 @@ DBSchema::CacheMatchAll(mozIStorageConnection* aConn, CacheId aCacheId,
|
|||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
DBSchema::CachePut(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
const PCacheRequest& aRequest,
|
||||
const nsID* aRequestBodyId,
|
||||
const PCacheResponse& aResponse,
|
||||
const nsID* aResponseBodyId,
|
||||
nsTArray<nsID>& aDeletedBodyIdListOut)
|
||||
CachePut(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
const CacheRequest& aRequest,
|
||||
const nsID* aRequestBodyId,
|
||||
const CacheResponse& aResponse,
|
||||
const nsID* aResponseBodyId,
|
||||
nsTArray<nsID>& aDeletedBodyIdListOut)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aConn);
|
||||
|
||||
PCacheQueryParams params(false, false, false, false,
|
||||
CacheQueryParams params(false, false, false, false,
|
||||
NS_LITERAL_STRING(""));
|
||||
nsAutoTArray<EntryId, 256> matches;
|
||||
nsresult rv = QueryCache(aConn, aCacheId, aRequest, params, matches);
|
||||
|
@ -506,12 +543,11 @@ DBSchema::CachePut(mozIStorageConnection* aConn, CacheId aCacheId,
|
|||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
DBSchema::CacheDelete(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
const PCacheRequest& aRequest,
|
||||
const PCacheQueryParams& aParams,
|
||||
nsTArray<nsID>& aDeletedBodyIdListOut, bool* aSuccessOut)
|
||||
CacheDelete(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
const CacheRequest& aRequest,
|
||||
const CacheQueryParams& aParams,
|
||||
nsTArray<nsID>& aDeletedBodyIdListOut, bool* aSuccessOut)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aConn);
|
||||
|
@ -535,19 +571,18 @@ DBSchema::CacheDelete(mozIStorageConnection* aConn, CacheId aCacheId,
|
|||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
DBSchema::CacheKeys(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
const PCacheRequestOrVoid& aRequestOrVoid,
|
||||
const PCacheQueryParams& aParams,
|
||||
nsTArray<SavedRequest>& aSavedRequestsOut)
|
||||
CacheKeys(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
const CacheRequestOrVoid& aRequestOrVoid,
|
||||
const CacheQueryParams& aParams,
|
||||
nsTArray<SavedRequest>& aSavedRequestsOut)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aConn);
|
||||
nsresult rv;
|
||||
|
||||
nsAutoTArray<EntryId, 256> matches;
|
||||
if (aRequestOrVoid.type() == PCacheRequestOrVoid::Tvoid_t) {
|
||||
if (aRequestOrVoid.type() == CacheRequestOrVoid::Tvoid_t) {
|
||||
rv = QueryAll(aConn, aCacheId, matches);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
} else {
|
||||
|
@ -567,14 +602,13 @@ DBSchema::CacheKeys(mozIStorageConnection* aConn, CacheId aCacheId,
|
|||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
DBSchema::StorageMatch(mozIStorageConnection* aConn,
|
||||
Namespace aNamespace,
|
||||
const PCacheRequest& aRequest,
|
||||
const PCacheQueryParams& aParams,
|
||||
bool* aFoundResponseOut,
|
||||
SavedResponse* aSavedResponseOut)
|
||||
StorageMatch(mozIStorageConnection* aConn,
|
||||
Namespace aNamespace,
|
||||
const CacheRequest& aRequest,
|
||||
const CacheQueryParams& aParams,
|
||||
bool* aFoundResponseOut,
|
||||
SavedResponse* aSavedResponseOut)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aConn);
|
||||
|
@ -639,11 +673,10 @@ DBSchema::StorageMatch(mozIStorageConnection* aConn,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
DBSchema::StorageGetCacheId(mozIStorageConnection* aConn, Namespace aNamespace,
|
||||
const nsAString& aKey, bool* aFoundCacheOut,
|
||||
CacheId* aCacheIdOut)
|
||||
StorageGetCacheId(mozIStorageConnection* aConn, Namespace aNamespace,
|
||||
const nsAString& aKey, bool* aFoundCacheOut,
|
||||
CacheId* aCacheIdOut)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aConn);
|
||||
|
@ -679,10 +712,9 @@ DBSchema::StorageGetCacheId(mozIStorageConnection* aConn, Namespace aNamespace,
|
|||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
DBSchema::StoragePutCache(mozIStorageConnection* aConn, Namespace aNamespace,
|
||||
const nsAString& aKey, CacheId aCacheId)
|
||||
StoragePutCache(mozIStorageConnection* aConn, Namespace aNamespace,
|
||||
const nsAString& aKey, CacheId aCacheId)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aConn);
|
||||
|
@ -708,10 +740,9 @@ DBSchema::StoragePutCache(mozIStorageConnection* aConn, Namespace aNamespace,
|
|||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
DBSchema::StorageForgetCache(mozIStorageConnection* aConn, Namespace aNamespace,
|
||||
const nsAString& aKey)
|
||||
StorageForgetCache(mozIStorageConnection* aConn, Namespace aNamespace,
|
||||
const nsAString& aKey)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aConn);
|
||||
|
@ -734,10 +765,9 @@ DBSchema::StorageForgetCache(mozIStorageConnection* aConn, Namespace aNamespace,
|
|||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
DBSchema::StorageGetKeys(mozIStorageConnection* aConn, Namespace aNamespace,
|
||||
nsTArray<nsString>& aKeysOut)
|
||||
StorageGetKeys(mozIStorageConnection* aConn, Namespace aNamespace,
|
||||
nsTArray<nsString>& aKeysOut)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aConn);
|
||||
|
@ -762,10 +792,11 @@ DBSchema::StorageGetKeys(mozIStorageConnection* aConn, Namespace aNamespace,
|
|||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
namespace {
|
||||
|
||||
nsresult
|
||||
DBSchema::QueryAll(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
nsTArray<EntryId>& aEntryIdListOut)
|
||||
QueryAll(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
nsTArray<EntryId>& aEntryIdListOut)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aConn);
|
||||
|
@ -790,13 +821,12 @@ DBSchema::QueryAll(mozIStorageConnection* aConn, CacheId aCacheId,
|
|||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
DBSchema::QueryCache(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
const PCacheRequest& aRequest,
|
||||
const PCacheQueryParams& aParams,
|
||||
nsTArray<EntryId>& aEntryIdListOut,
|
||||
uint32_t aMaxResults)
|
||||
QueryCache(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
const CacheRequest& aRequest,
|
||||
const CacheQueryParams& aParams,
|
||||
nsTArray<EntryId>& aEntryIdListOut,
|
||||
uint32_t aMaxResults)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aConn);
|
||||
|
@ -868,11 +898,10 @@ DBSchema::QueryCache(mozIStorageConnection* aConn, CacheId aCacheId,
|
|||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
DBSchema::MatchByVaryHeader(mozIStorageConnection* aConn,
|
||||
const PCacheRequest& aRequest,
|
||||
EntryId entryId, bool* aSuccessOut)
|
||||
MatchByVaryHeader(mozIStorageConnection* aConn,
|
||||
const CacheRequest& aRequest,
|
||||
EntryId entryId, bool* aSuccessOut)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aConn);
|
||||
|
@ -913,7 +942,8 @@ DBSchema::MatchByVaryHeader(mozIStorageConnection* aConn,
|
|||
rv = state->BindInt32Parameter(0, entryId);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
nsRefPtr<InternalHeaders> cachedHeaders = new InternalHeaders(HeadersGuardEnum::None);
|
||||
nsRefPtr<InternalHeaders> cachedHeaders =
|
||||
new InternalHeaders(HeadersGuardEnum::None);
|
||||
|
||||
while (NS_SUCCEEDED(state->ExecuteStep(&hasMoreData)) && hasMoreData) {
|
||||
nsAutoCString name;
|
||||
|
@ -930,7 +960,8 @@ DBSchema::MatchByVaryHeader(mozIStorageConnection* aConn,
|
|||
}
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
nsRefPtr<InternalHeaders> queryHeaders = new InternalHeaders(aRequest.headers());
|
||||
nsRefPtr<InternalHeaders> queryHeaders =
|
||||
TypeUtils::ToInternalHeaders(aRequest.headers());
|
||||
|
||||
// Assume the vary headers match until we find a conflict
|
||||
bool varyHeadersMatch = true;
|
||||
|
@ -979,12 +1010,11 @@ DBSchema::MatchByVaryHeader(mozIStorageConnection* aConn,
|
|||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
DBSchema::DeleteEntries(mozIStorageConnection* aConn,
|
||||
const nsTArray<EntryId>& aEntryIdList,
|
||||
nsTArray<nsID>& aDeletedBodyIdListOut,
|
||||
uint32_t aPos, int32_t aLen)
|
||||
DeleteEntries(mozIStorageConnection* aConn,
|
||||
const nsTArray<EntryId>& aEntryIdList,
|
||||
nsTArray<nsID>& aDeletedBodyIdListOut,
|
||||
uint32_t aPos, int32_t aLen)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aConn);
|
||||
|
@ -1068,13 +1098,12 @@ DBSchema::DeleteEntries(mozIStorageConnection* aConn,
|
|||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
DBSchema::InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
const PCacheRequest& aRequest,
|
||||
const nsID* aRequestBodyId,
|
||||
const PCacheResponse& aResponse,
|
||||
const nsID* aResponseBodyId)
|
||||
InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
const CacheRequest& aRequest,
|
||||
const nsID* aRequestBodyId,
|
||||
const CacheResponse& aResponse,
|
||||
const nsID* aResponseBodyId)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aConn);
|
||||
|
@ -1195,7 +1224,7 @@ DBSchema::InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId,
|
|||
), getter_AddRefs(state));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
const nsTArray<PHeadersEntry>& requestHeaders = aRequest.headers();
|
||||
const nsTArray<HeadersEntry>& requestHeaders = aRequest.headers();
|
||||
for (uint32_t i = 0; i < requestHeaders.Length(); ++i) {
|
||||
rv = state->BindUTF8StringParameter(0, requestHeaders[i].name());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
@ -1219,7 +1248,7 @@ DBSchema::InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId,
|
|||
), getter_AddRefs(state));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
const nsTArray<PHeadersEntry>& responseHeaders = aResponse.headers();
|
||||
const nsTArray<HeadersEntry>& responseHeaders = aResponse.headers();
|
||||
for (uint32_t i = 0; i < responseHeaders.Length(); ++i) {
|
||||
rv = state->BindUTF8StringParameter(0, responseHeaders[i].name());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
@ -1237,10 +1266,9 @@ DBSchema::InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId,
|
|||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
DBSchema::ReadResponse(mozIStorageConnection* aConn, EntryId aEntryId,
|
||||
SavedResponse* aSavedResponseOut)
|
||||
ReadResponse(mozIStorageConnection* aConn, EntryId aEntryId,
|
||||
SavedResponse* aSavedResponseOut)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aConn);
|
||||
|
@ -1320,7 +1348,7 @@ DBSchema::ReadResponse(mozIStorageConnection* aConn, EntryId aEntryId,
|
|||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
while (NS_SUCCEEDED(state->ExecuteStep(&hasMoreData)) && hasMoreData) {
|
||||
PHeadersEntry header;
|
||||
HeadersEntry header;
|
||||
|
||||
rv = state->GetUTF8String(0, header.name());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
@ -1334,10 +1362,9 @@ DBSchema::ReadResponse(mozIStorageConnection* aConn, EntryId aEntryId,
|
|||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
DBSchema::ReadRequest(mozIStorageConnection* aConn, EntryId aEntryId,
|
||||
SavedRequest* aSavedRequestOut)
|
||||
ReadRequest(mozIStorageConnection* aConn, EntryId aEntryId,
|
||||
SavedRequest* aSavedRequestOut)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aConn);
|
||||
|
@ -1439,7 +1466,7 @@ DBSchema::ReadRequest(mozIStorageConnection* aConn, EntryId aEntryId,
|
|||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
while (NS_SUCCEEDED(state->ExecuteStep(&hasMoreData)) && hasMoreData) {
|
||||
PHeadersEntry header;
|
||||
HeadersEntry header;
|
||||
|
||||
rv = state->GetUTF8String(0, header.name());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
@ -1453,11 +1480,10 @@ DBSchema::ReadRequest(mozIStorageConnection* aConn, EntryId aEntryId,
|
|||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
DBSchema::AppendListParamsToQuery(nsACString& aQuery,
|
||||
const nsTArray<EntryId>& aEntryIdList,
|
||||
uint32_t aPos, int32_t aLen)
|
||||
AppendListParamsToQuery(nsACString& aQuery,
|
||||
const nsTArray<EntryId>& aEntryIdList,
|
||||
uint32_t aPos, int32_t aLen)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT((aPos + aLen) <= aEntryIdList.Length());
|
||||
|
@ -1470,11 +1496,10 @@ DBSchema::AppendListParamsToQuery(nsACString& aQuery,
|
|||
}
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
DBSchema::BindListParamsToQuery(mozIStorageStatement* aState,
|
||||
const nsTArray<EntryId>& aEntryIdList,
|
||||
uint32_t aPos, int32_t aLen)
|
||||
BindListParamsToQuery(mozIStorageStatement* aState,
|
||||
const nsTArray<EntryId>& aEntryIdList,
|
||||
uint32_t aPos, int32_t aLen)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT((aPos + aLen) <= aEntryIdList.Length());
|
||||
|
@ -1485,9 +1510,8 @@ DBSchema::BindListParamsToQuery(mozIStorageStatement* aState,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
DBSchema::BindId(mozIStorageStatement* aState, uint32_t aPos, const nsID* aId)
|
||||
BindId(mozIStorageStatement* aState, uint32_t aPos, const nsID* aId)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aState);
|
||||
|
@ -1507,9 +1531,8 @@ DBSchema::BindId(mozIStorageStatement* aState, uint32_t aPos, const nsID* aId)
|
|||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
DBSchema::ExtractId(mozIStorageStatement* aState, uint32_t aPos, nsID* aIdOut)
|
||||
ExtractId(mozIStorageStatement* aState, uint32_t aPos, nsID* aIdOut)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(aState);
|
||||
|
@ -1525,6 +1548,9 @@ DBSchema::ExtractId(mozIStorageStatement* aState, uint32_t aPos, nsID* aIdOut)
|
|||
return rv;
|
||||
}
|
||||
|
||||
} // anonymouns namespace
|
||||
|
||||
} // namespace db
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -14,129 +14,100 @@
|
|||
#include "nsTArrayForwardDeclare.h"
|
||||
|
||||
class mozIStorageConnection;
|
||||
class mozIStorageStatement;
|
||||
struct nsID;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
class PCacheQueryParams;
|
||||
class PCacheRequest;
|
||||
class PCacheRequestOrVoid;
|
||||
class PCacheResponse;
|
||||
class CacheQueryParams;
|
||||
class CacheRequest;
|
||||
class CacheRequestOrVoid;
|
||||
class CacheResponse;
|
||||
struct SavedRequest;
|
||||
struct SavedResponse;
|
||||
|
||||
// TODO: remove static class and use functions in cache namespace (bug 1110485)
|
||||
class DBSchema final
|
||||
{
|
||||
public:
|
||||
static nsresult CreateSchema(mozIStorageConnection* aConn);
|
||||
static nsresult InitializeConnection(mozIStorageConnection* aConn);
|
||||
namespace db {
|
||||
|
||||
static nsresult CreateCache(mozIStorageConnection* aConn,
|
||||
CacheId* aCacheIdOut);
|
||||
// TODO: improve naming (confusing with CacheDelete) (bug 1110485)
|
||||
static nsresult DeleteCache(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
nsTArray<nsID>& aDeletedBodyIdListOut);
|
||||
nsresult
|
||||
CreateSchema(mozIStorageConnection* aConn);
|
||||
|
||||
// TODO: Consider removing unused IsCacheOrphaned after writing cleanup code. (bug 1110446)
|
||||
static nsresult IsCacheOrphaned(mozIStorageConnection* aConn,
|
||||
CacheId aCacheId, bool* aOrphanedOut);
|
||||
nsresult
|
||||
InitializeConnection(mozIStorageConnection* aConn);
|
||||
|
||||
static nsresult CacheMatch(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
const PCacheRequest& aRequest,
|
||||
const PCacheQueryParams& aParams,
|
||||
bool* aFoundResponseOut,
|
||||
SavedResponse* aSavedResponseOut);
|
||||
static nsresult CacheMatchAll(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
const PCacheRequestOrVoid& aRequestOrVoid,
|
||||
const PCacheQueryParams& aParams,
|
||||
nsTArray<SavedResponse>& aSavedResponsesOut);
|
||||
static nsresult CachePut(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
const PCacheRequest& aRequest,
|
||||
const nsID* aRequestBodyId,
|
||||
const PCacheResponse& aResponse,
|
||||
const nsID* aResponseBodyId,
|
||||
nsTArray<nsID>& aDeletedBodyIdListOut);
|
||||
static nsresult CacheDelete(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
const PCacheRequest& aRequest,
|
||||
const PCacheQueryParams& aParams,
|
||||
nsTArray<nsID>& aDeletedBodyIdListOut,
|
||||
bool* aSuccessOut);
|
||||
static nsresult CacheKeys(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
const PCacheRequestOrVoid& aRequestOrVoid,
|
||||
const PCacheQueryParams& aParams,
|
||||
nsTArray<SavedRequest>& aSavedRequestsOut);
|
||||
nsresult
|
||||
CreateCacheId(mozIStorageConnection* aConn, CacheId* aCacheIdOut);
|
||||
|
||||
static nsresult StorageMatch(mozIStorageConnection* aConn,
|
||||
Namespace aNamespace,
|
||||
const PCacheRequest& aRequest,
|
||||
const PCacheQueryParams& aParams,
|
||||
bool* aFoundResponseOut,
|
||||
SavedResponse* aSavedResponseOut);
|
||||
static nsresult StorageGetCacheId(mozIStorageConnection* aConn,
|
||||
Namespace aNamespace, const nsAString& aKey,
|
||||
bool* aFoundCacheOut, CacheId* aCacheIdOut);
|
||||
static nsresult StoragePutCache(mozIStorageConnection* aConn,
|
||||
Namespace aNamespace, const nsAString& aKey,
|
||||
CacheId aCacheId);
|
||||
static nsresult StorageForgetCache(mozIStorageConnection* aConn,
|
||||
Namespace aNamespace,
|
||||
const nsAString& aKey);
|
||||
static nsresult StorageGetKeys(mozIStorageConnection* aConn,
|
||||
Namespace aNamespace,
|
||||
nsTArray<nsString>& aKeysOut);
|
||||
nsresult
|
||||
DeleteCacheId(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
nsTArray<nsID>& aDeletedBodyIdListOut);
|
||||
|
||||
// We will wipe out databases with a schema versions less than this.
|
||||
static const int32_t kMaxWipeSchemaVersion;
|
||||
// TODO: Consider removing unused IsCacheOrphaned after writing cleanup code. (bug 1110446)
|
||||
nsresult
|
||||
IsCacheOrphaned(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
bool* aOrphanedOut);
|
||||
|
||||
private:
|
||||
typedef int32_t EntryId;
|
||||
nsresult
|
||||
CacheMatch(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
const CacheRequest& aRequest, const CacheQueryParams& aParams,
|
||||
bool* aFoundResponseOut, SavedResponse* aSavedResponseOut);
|
||||
|
||||
static nsresult QueryAll(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
nsTArray<EntryId>& aEntryIdListOut);
|
||||
static nsresult QueryCache(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
const PCacheRequest& aRequest,
|
||||
const PCacheQueryParams& aParams,
|
||||
nsTArray<EntryId>& aEntryIdListOut,
|
||||
uint32_t aMaxResults = UINT32_MAX);
|
||||
static nsresult MatchByVaryHeader(mozIStorageConnection* aConn,
|
||||
const PCacheRequest& aRequest,
|
||||
EntryId entryId, bool* aSuccessOut);
|
||||
static nsresult DeleteEntries(mozIStorageConnection* aConn,
|
||||
const nsTArray<EntryId>& aEntryIdList,
|
||||
nsTArray<nsID>& aDeletedBodyIdListOut,
|
||||
uint32_t aPos=0, int32_t aLen=-1);
|
||||
static nsresult InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
const PCacheRequest& aRequest,
|
||||
const nsID* aRequestBodyId,
|
||||
const PCacheResponse& aResponse,
|
||||
const nsID* aResponseBodyId);
|
||||
static nsresult ReadResponse(mozIStorageConnection* aConn, EntryId aEntryId,
|
||||
SavedResponse* aSavedResponseOut);
|
||||
static nsresult ReadRequest(mozIStorageConnection* aConn, EntryId aEntryId,
|
||||
SavedRequest* aSavedRequestOut);
|
||||
nsresult
|
||||
CacheMatchAll(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
const CacheRequestOrVoid& aRequestOrVoid,
|
||||
const CacheQueryParams& aParams,
|
||||
nsTArray<SavedResponse>& aSavedResponsesOut);
|
||||
|
||||
static void AppendListParamsToQuery(nsACString& aQuery,
|
||||
const nsTArray<EntryId>& aEntryIdList,
|
||||
uint32_t aPos, int32_t aLen);
|
||||
static nsresult BindListParamsToQuery(mozIStorageStatement* aState,
|
||||
const nsTArray<EntryId>& aEntryIdList,
|
||||
uint32_t aPos, int32_t aLen);
|
||||
static nsresult BindId(mozIStorageStatement* aState, uint32_t aPos,
|
||||
const nsID* aId);
|
||||
static nsresult ExtractId(mozIStorageStatement* aState, uint32_t aPos,
|
||||
nsID* aIdOut);
|
||||
nsresult
|
||||
CachePut(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
const CacheRequest& aRequest,
|
||||
const nsID* aRequestBodyId,
|
||||
const CacheResponse& aResponse,
|
||||
const nsID* aResponseBodyId,
|
||||
nsTArray<nsID>& aDeletedBodyIdListOut);
|
||||
|
||||
DBSchema() = delete;
|
||||
~DBSchema() = delete;
|
||||
nsresult
|
||||
CacheDelete(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
const CacheRequest& aRequest,
|
||||
const CacheQueryParams& aParams,
|
||||
nsTArray<nsID>& aDeletedBodyIdListOut,
|
||||
bool* aSuccessOut);
|
||||
|
||||
static const int32_t kLatestSchemaVersion;
|
||||
static const int32_t kMaxEntriesPerStatement;
|
||||
};
|
||||
nsresult
|
||||
CacheKeys(mozIStorageConnection* aConn, CacheId aCacheId,
|
||||
const CacheRequestOrVoid& aRequestOrVoid,
|
||||
const CacheQueryParams& aParams,
|
||||
nsTArray<SavedRequest>& aSavedRequestsOut);
|
||||
|
||||
nsresult
|
||||
StorageMatch(mozIStorageConnection* aConn,
|
||||
Namespace aNamespace,
|
||||
const CacheRequest& aRequest,
|
||||
const CacheQueryParams& aParams,
|
||||
bool* aFoundResponseOut,
|
||||
SavedResponse* aSavedResponseOut);
|
||||
|
||||
nsresult
|
||||
StorageGetCacheId(mozIStorageConnection* aConn, Namespace aNamespace,
|
||||
const nsAString& aKey, bool* aFoundCacheOut,
|
||||
CacheId* aCacheIdOut);
|
||||
|
||||
nsresult
|
||||
StoragePutCache(mozIStorageConnection* aConn, Namespace aNamespace,
|
||||
const nsAString& aKey, CacheId aCacheId);
|
||||
|
||||
nsresult
|
||||
StorageForgetCache(mozIStorageConnection* aConn, Namespace aNamespace,
|
||||
const nsAString& aKey);
|
||||
|
||||
nsresult
|
||||
StorageGetKeys(mozIStorageConnection* aConn, Namespace aNamespace,
|
||||
nsTArray<nsString>& aKeysOut);
|
||||
|
||||
// We will wipe out databases with a schema versions less than this.
|
||||
extern const int32_t kMaxWipeSchemaVersion;
|
||||
|
||||
} // namespace db
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include "mozilla/dom/ResponseBinding.h"
|
||||
#include "mozilla/dom/UnionTypes.h"
|
||||
#include "mozilla/dom/cache/ManagerId.h"
|
||||
#include "mozilla/dom/cache/PCacheTypes.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
@ -98,9 +97,8 @@ private:
|
|||
|
||||
// static
|
||||
nsresult
|
||||
FetchPut::Create(Listener* aListener, Manager* aManager,
|
||||
RequestId aRequestId, CacheId aCacheId,
|
||||
const nsTArray<PCacheRequest>& aRequests,
|
||||
FetchPut::Create(Listener* aListener, Manager* aManager, CacheId aCacheId,
|
||||
const nsTArray<CacheRequest>& aRequests,
|
||||
const nsTArray<nsCOMPtr<nsIInputStream>>& aRequestStreams,
|
||||
FetchPut** aFetchPutOut)
|
||||
{
|
||||
|
@ -115,7 +113,7 @@ FetchPut::Create(Listener* aListener, Manager* aManager,
|
|||
}
|
||||
#endif
|
||||
|
||||
nsRefPtr<FetchPut> ref = new FetchPut(aListener, aManager, aRequestId, aCacheId,
|
||||
nsRefPtr<FetchPut> ref = new FetchPut(aListener, aManager, aCacheId,
|
||||
aRequests, aRequestStreams);
|
||||
|
||||
nsresult rv = ref->DispatchToMainThread();
|
||||
|
@ -133,13 +131,11 @@ FetchPut::ClearListener()
|
|||
mListener = nullptr;
|
||||
}
|
||||
|
||||
FetchPut::FetchPut(Listener* aListener, Manager* aManager,
|
||||
RequestId aRequestId, CacheId aCacheId,
|
||||
const nsTArray<PCacheRequest>& aRequests,
|
||||
FetchPut::FetchPut(Listener* aListener, Manager* aManager, CacheId aCacheId,
|
||||
const nsTArray<CacheRequest>& aRequests,
|
||||
const nsTArray<nsCOMPtr<nsIInputStream>>& aRequestStreams)
|
||||
: mListener(aListener)
|
||||
, mManager(aManager)
|
||||
, mRequestId(aRequestId)
|
||||
, mCacheId(aCacheId)
|
||||
, mInitiatingThread(NS_GetCurrentThread())
|
||||
, mStateList(aRequests.Length())
|
||||
|
@ -151,7 +147,7 @@ FetchPut::FetchPut(Listener* aListener, Manager* aManager,
|
|||
|
||||
for (uint32_t i = 0; i < aRequests.Length(); ++i) {
|
||||
State* s = mStateList.AppendElement();
|
||||
s->mPCacheRequest = aRequests[i];
|
||||
s->mCacheRequest = aRequests[i];
|
||||
s->mRequestStream = aRequestStreams[i];
|
||||
}
|
||||
|
||||
|
@ -211,14 +207,14 @@ FetchPut::DoFetchOnMainThread()
|
|||
nsCOMPtr<nsILoadGroup> loadGroup;
|
||||
nsresult rv = NS_NewLoadGroup(getter_AddRefs(loadGroup), principal);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
MaybeSetError(rv);
|
||||
MaybeSetError(ErrorResult(rv));
|
||||
MaybeCompleteOnMainThread();
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < mStateList.Length(); ++i) {
|
||||
nsRefPtr<InternalRequest> internalRequest =
|
||||
ToInternalRequest(mStateList[i].mPCacheRequest);
|
||||
ToInternalRequest(mStateList[i].mCacheRequest);
|
||||
|
||||
// If there is a stream we must clone it so that its still available
|
||||
// to store in the cache later;
|
||||
|
@ -240,7 +236,7 @@ FetchPut::DoFetchOnMainThread()
|
|||
mStateList[i].mFetchObserver = new FetchObserver(this);
|
||||
rv = fetchDriver->Fetch(mStateList[i].mFetchObserver);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
MaybeSetError(rv);
|
||||
MaybeSetError(ErrorResult(rv));
|
||||
mStateList[i].mFetchObserver = nullptr;
|
||||
mPendingCount -= 1;
|
||||
continue;
|
||||
|
@ -258,16 +254,16 @@ FetchPut::FetchComplete(FetchObserver* aObserver,
|
|||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (aInternalResponse->IsError() && !mResult.Failed()) {
|
||||
MaybeSetError(NS_ERROR_FAILURE);
|
||||
MaybeSetError(ErrorResult(NS_ERROR_FAILURE));
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < mStateList.Length(); ++i) {
|
||||
if (mStateList[i].mFetchObserver == aObserver) {
|
||||
ErrorResult rv;
|
||||
ToPCacheResponseWithoutBody(mStateList[i].mPCacheResponse,
|
||||
ToCacheResponseWithoutBody(mStateList[i].mCacheResponse,
|
||||
*aInternalResponse, rv);
|
||||
if (rv.Failed()) {
|
||||
mResult = Move(rv);
|
||||
MaybeSetError(Move(rv));
|
||||
} else {
|
||||
aInternalResponse->GetBody(getter_AddRefs(mStateList[i].mResponseStream));
|
||||
}
|
||||
|
@ -316,27 +312,27 @@ FetchPut::DoPutOnWorkerThread()
|
|||
for (uint32_t i = 0; i < mStateList.Length(); ++i) {
|
||||
// The spec requires us to catch if content tries to insert a set of
|
||||
// requests that would overwrite each other.
|
||||
if (MatchInPutList(mStateList[i].mPCacheRequest, putList)) {
|
||||
MaybeSetError(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
if (MatchInPutList(mStateList[i].mCacheRequest, putList)) {
|
||||
MaybeSetError(ErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
|
||||
MaybeNotifyListener();
|
||||
return;
|
||||
}
|
||||
|
||||
CacheRequestResponse* entry = putList.AppendElement();
|
||||
entry->request() = mStateList[i].mPCacheRequest;
|
||||
entry->response() = mStateList[i].mPCacheResponse;
|
||||
entry->request() = mStateList[i].mCacheRequest;
|
||||
entry->response() = mStateList[i].mCacheResponse;
|
||||
requestStreamList.AppendElement(mStateList[i].mRequestStream.forget());
|
||||
responseStreamList.AppendElement(mStateList[i].mResponseStream.forget());
|
||||
}
|
||||
mStateList.Clear();
|
||||
|
||||
mManager->CachePutAll(this, mRequestId, mCacheId, putList, requestStreamList,
|
||||
responseStreamList);
|
||||
mManager->ExecutePutAll(this, mCacheId, putList, requestStreamList,
|
||||
responseStreamList);
|
||||
}
|
||||
|
||||
// static
|
||||
bool
|
||||
FetchPut::MatchInPutList(const PCacheRequest& aRequest,
|
||||
FetchPut::MatchInPutList(const CacheRequest& aRequest,
|
||||
const nsTArray<CacheRequestResponse>& aPutList)
|
||||
{
|
||||
// This method implements the SW spec QueryCache algorithm against an
|
||||
|
@ -351,11 +347,11 @@ FetchPut::MatchInPutList(const PCacheRequest& aRequest,
|
|||
}
|
||||
|
||||
nsRefPtr<InternalHeaders> requestHeaders =
|
||||
new InternalHeaders(aRequest.headers());
|
||||
ToInternalHeaders(aRequest.headers());
|
||||
|
||||
for (uint32_t i = 0; i < aPutList.Length(); ++i) {
|
||||
const PCacheRequest& cachedRequest = aPutList[i].request();
|
||||
const PCacheResponse& cachedResponse = aPutList[i].response();
|
||||
const CacheRequest& cachedRequest = aPutList[i].request();
|
||||
const CacheResponse& cachedResponse = aPutList[i].response();
|
||||
|
||||
// If the URLs don't match, then just skip to the next entry.
|
||||
if (aRequest.url() != cachedRequest.url()) {
|
||||
|
@ -363,10 +359,10 @@ FetchPut::MatchInPutList(const PCacheRequest& aRequest,
|
|||
}
|
||||
|
||||
nsRefPtr<InternalHeaders> cachedRequestHeaders =
|
||||
new InternalHeaders(cachedRequest.headers());
|
||||
ToInternalHeaders(cachedRequest.headers());
|
||||
|
||||
nsRefPtr<InternalHeaders> cachedResponseHeaders =
|
||||
new InternalHeaders(cachedResponse.headers());
|
||||
ToInternalHeaders(cachedResponse.headers());
|
||||
|
||||
nsAutoTArray<nsCString, 16> varyHeaders;
|
||||
ErrorResult rv;
|
||||
|
@ -426,20 +422,25 @@ FetchPut::MatchInPutList(const PCacheRequest& aRequest,
|
|||
}
|
||||
|
||||
void
|
||||
FetchPut::OnCachePutAll(RequestId aRequestId, nsresult aRv)
|
||||
FetchPut::OnOpComplete(ErrorResult&& aRv, const CacheOpResult& aResult,
|
||||
CacheId aOpenedCacheId,
|
||||
const nsTArray<SavedResponse>& aSavedResponseList,
|
||||
const nsTArray<SavedRequest>& aSavedRequestList,
|
||||
StreamList* aStreamList)
|
||||
{
|
||||
MOZ_ASSERT(mInitiatingThread == NS_GetCurrentThread());
|
||||
MaybeSetError(aRv);
|
||||
MOZ_ASSERT(aResult.type() == CacheOpResult::TCachePutAllResult);
|
||||
MaybeSetError(Move(aRv));
|
||||
MaybeNotifyListener();
|
||||
}
|
||||
|
||||
void
|
||||
FetchPut::MaybeSetError(nsresult aRv)
|
||||
FetchPut::MaybeSetError(ErrorResult&& aRv)
|
||||
{
|
||||
if (mResult.Failed() || NS_SUCCEEDED(aRv)) {
|
||||
if (mResult.Failed() || !aRv.Failed()) {
|
||||
return;
|
||||
}
|
||||
mResult.Throw(aRv);
|
||||
mResult = Move(aRv);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -453,8 +454,7 @@ FetchPut::MaybeNotifyListener()
|
|||
// object is removed from CacheParent::mFetchPutList, so make sure that
|
||||
// doesn't happen until this method returns.
|
||||
nsRefPtr<FetchPut> kungFuDeathGrip(this);
|
||||
mListener->OnFetchPut(this, mRequestId, mResult);
|
||||
mResult.ClearMessage(); // This may contain a TypeError.
|
||||
mListener->OnFetchPut(this, Move(mResult));
|
||||
}
|
||||
|
||||
nsIGlobalObject*
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/dom/cache/Manager.h"
|
||||
#include "mozilla/dom/cache/PCacheTypes.h"
|
||||
#include "mozilla/dom/cache/CacheTypes.h"
|
||||
#include "mozilla/dom/cache/Types.h"
|
||||
#include "mozilla/dom/cache/TypeUtils.h"
|
||||
#include "nsRefPtr.h"
|
||||
|
@ -40,13 +40,12 @@ public:
|
|||
{
|
||||
public:
|
||||
virtual void
|
||||
OnFetchPut(FetchPut* aFetchPut, RequestId aRequestId, const ErrorResult& aRv) = 0;
|
||||
OnFetchPut(FetchPut* aFetchPut, ErrorResult&& aRv) = 0;
|
||||
};
|
||||
|
||||
static nsresult
|
||||
Create(Listener* aListener, Manager* aManager,
|
||||
RequestId aRequestId, CacheId aCacheId,
|
||||
const nsTArray<PCacheRequest>& aRequests,
|
||||
Create(Listener* aListener, Manager* aManager, CacheId aCacheId,
|
||||
const nsTArray<CacheRequest>& aRequests,
|
||||
const nsTArray<nsCOMPtr<nsIInputStream>>& aRequestStreams,
|
||||
FetchPut** aFetchPutOut);
|
||||
|
||||
|
@ -58,19 +57,18 @@ private:
|
|||
friend class FetchObserver;
|
||||
struct State
|
||||
{
|
||||
PCacheRequest mPCacheRequest;
|
||||
CacheRequest mCacheRequest;
|
||||
nsCOMPtr<nsIInputStream> mRequestStream;
|
||||
nsRefPtr<FetchObserver> mFetchObserver;
|
||||
PCacheResponse mPCacheResponse;
|
||||
CacheResponse mCacheResponse;
|
||||
nsCOMPtr<nsIInputStream> mResponseStream;
|
||||
|
||||
nsRefPtr<Request> mRequest;
|
||||
nsRefPtr<Response> mResponse;
|
||||
};
|
||||
|
||||
FetchPut(Listener* aListener, Manager* aManager,
|
||||
RequestId aRequestId, CacheId aCacheId,
|
||||
const nsTArray<PCacheRequest>& aRequests,
|
||||
FetchPut(Listener* aListener, Manager* aManager, CacheId aCacheId,
|
||||
const nsTArray<CacheRequest>& aRequests,
|
||||
const nsTArray<nsCOMPtr<nsIInputStream>>& aRequestStreams);
|
||||
~FetchPut();
|
||||
|
||||
|
@ -83,11 +81,17 @@ private:
|
|||
void MaybeCompleteOnMainThread();
|
||||
|
||||
void DoPutOnWorkerThread();
|
||||
static bool MatchInPutList(const PCacheRequest& aRequest,
|
||||
static bool MatchInPutList(const CacheRequest& aRequest,
|
||||
const nsTArray<CacheRequestResponse>& aPutList);
|
||||
virtual void OnCachePutAll(RequestId aRequestId, nsresult aRv) override;
|
||||
|
||||
void MaybeSetError(nsresult aRv);
|
||||
virtual void
|
||||
OnOpComplete(ErrorResult&& aRv, const CacheOpResult& aResult,
|
||||
CacheId aOpenedCacheId,
|
||||
const nsTArray<SavedResponse>& aSavedResponseList,
|
||||
const nsTArray<SavedRequest>& aSavedRequestList,
|
||||
StreamList* aStreamList) override;
|
||||
|
||||
void MaybeSetError(ErrorResult&& aRv);
|
||||
void MaybeNotifyListener();
|
||||
|
||||
// TypeUtils methods
|
||||
|
@ -101,7 +105,6 @@ private:
|
|||
|
||||
Listener* mListener;
|
||||
nsRefPtr<Manager> mManager;
|
||||
const RequestId mRequestId;
|
||||
const CacheId mCacheId;
|
||||
nsCOMPtr<nsIThread> mInitiatingThread;
|
||||
nsTArray<State> mStateList;
|
||||
|
|
|
@ -23,11 +23,24 @@ namespace cache {
|
|||
using mozilla::dom::quota::FileInputStream;
|
||||
using mozilla::dom::quota::FileOutputStream;
|
||||
using mozilla::dom::quota::PERSISTENCE_TYPE_DEFAULT;
|
||||
using mozilla::unused;
|
||||
|
||||
namespace {
|
||||
|
||||
enum BodyFileType
|
||||
{
|
||||
BODY_FILE_FINAL,
|
||||
BODY_FILE_TMP
|
||||
};
|
||||
|
||||
nsresult
|
||||
BodyIdToFile(nsIFile* aBaseDir, const nsID& aId, BodyFileType aType,
|
||||
nsIFile** aBodyFileOut);
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// static
|
||||
nsresult
|
||||
FileUtils::BodyCreateDir(nsIFile* aBaseDir)
|
||||
BodyCreateDir(nsIFile* aBaseDir)
|
||||
{
|
||||
MOZ_ASSERT(aBaseDir);
|
||||
|
||||
|
@ -49,7 +62,7 @@ FileUtils::BodyCreateDir(nsIFile* aBaseDir)
|
|||
|
||||
// static
|
||||
nsresult
|
||||
FileUtils::BodyDeleteDir(nsIFile* aBaseDir)
|
||||
BodyDeleteDir(nsIFile* aBaseDir)
|
||||
{
|
||||
MOZ_ASSERT(aBaseDir);
|
||||
|
||||
|
@ -72,8 +85,7 @@ FileUtils::BodyDeleteDir(nsIFile* aBaseDir)
|
|||
|
||||
// static
|
||||
nsresult
|
||||
FileUtils::BodyGetCacheDir(nsIFile* aBaseDir, const nsID& aId,
|
||||
nsIFile** aCacheDirOut)
|
||||
BodyGetCacheDir(nsIFile* aBaseDir, const nsID& aId, nsIFile** aCacheDirOut)
|
||||
{
|
||||
MOZ_ASSERT(aBaseDir);
|
||||
MOZ_ASSERT(aCacheDirOut);
|
||||
|
@ -107,11 +119,11 @@ FileUtils::BodyGetCacheDir(nsIFile* aBaseDir, const nsID& aId,
|
|||
|
||||
// static
|
||||
nsresult
|
||||
FileUtils::BodyStartWriteStream(const QuotaInfo& aQuotaInfo,
|
||||
nsIFile* aBaseDir, nsIInputStream* aSource,
|
||||
void* aClosure,
|
||||
nsAsyncCopyCallbackFun aCallback, nsID* aIdOut,
|
||||
nsISupports** aCopyContextOut)
|
||||
BodyStartWriteStream(const QuotaInfo& aQuotaInfo,
|
||||
nsIFile* aBaseDir, nsIInputStream* aSource,
|
||||
void* aClosure,
|
||||
nsAsyncCopyCallbackFun aCallback, nsID* aIdOut,
|
||||
nsISupports** aCopyContextOut)
|
||||
{
|
||||
MOZ_ASSERT(aBaseDir);
|
||||
MOZ_ASSERT(aSource);
|
||||
|
@ -168,7 +180,7 @@ FileUtils::BodyStartWriteStream(const QuotaInfo& aQuotaInfo,
|
|||
|
||||
// static
|
||||
void
|
||||
FileUtils::BodyCancelWrite(nsIFile* aBaseDir, nsISupports* aCopyContext)
|
||||
BodyCancelWrite(nsIFile* aBaseDir, nsISupports* aCopyContext)
|
||||
{
|
||||
MOZ_ASSERT(aBaseDir);
|
||||
MOZ_ASSERT(aCopyContext);
|
||||
|
@ -182,7 +194,7 @@ FileUtils::BodyCancelWrite(nsIFile* aBaseDir, nsISupports* aCopyContext)
|
|||
|
||||
// static
|
||||
nsresult
|
||||
FileUtils::BodyFinalizeWrite(nsIFile* aBaseDir, const nsID& aId)
|
||||
BodyFinalizeWrite(nsIFile* aBaseDir, const nsID& aId)
|
||||
{
|
||||
MOZ_ASSERT(aBaseDir);
|
||||
|
||||
|
@ -206,8 +218,8 @@ FileUtils::BodyFinalizeWrite(nsIFile* aBaseDir, const nsID& aId)
|
|||
|
||||
// static
|
||||
nsresult
|
||||
FileUtils::BodyOpen(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir,
|
||||
const nsID& aId, nsIInputStream** aStreamOut)
|
||||
BodyOpen(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir, const nsID& aId,
|
||||
nsIInputStream** aStreamOut)
|
||||
{
|
||||
MOZ_ASSERT(aBaseDir);
|
||||
MOZ_ASSERT(aStreamOut);
|
||||
|
@ -234,7 +246,7 @@ FileUtils::BodyOpen(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir,
|
|||
|
||||
// static
|
||||
nsresult
|
||||
FileUtils::BodyDeleteFiles(nsIFile* aBaseDir, const nsTArray<nsID>& aIdList)
|
||||
BodyDeleteFiles(nsIFile* aBaseDir, const nsTArray<nsID>& aIdList)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
|
@ -273,10 +285,11 @@ FileUtils::BodyDeleteFiles(nsIFile* aBaseDir, const nsTArray<nsID>& aIdList)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// static
|
||||
namespace {
|
||||
|
||||
nsresult
|
||||
FileUtils::BodyIdToFile(nsIFile* aBaseDir, const nsID& aId,
|
||||
BodyFileType aType, nsIFile** aBodyFileOut)
|
||||
BodyIdToFile(nsIFile* aBaseDir, const nsID& aId, BodyFileType aType,
|
||||
nsIFile** aBodyFileOut)
|
||||
{
|
||||
MOZ_ASSERT(aBaseDir);
|
||||
MOZ_ASSERT(aBodyFileOut);
|
||||
|
@ -304,6 +317,8 @@ FileUtils::BodyIdToFile(nsIFile* aBaseDir, const nsID& aId,
|
|||
return rv;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -19,51 +19,36 @@ namespace mozilla {
|
|||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
// TODO: remove static class and use functions in cache namespace (bug 1110485)
|
||||
class FileUtils final
|
||||
{
|
||||
public:
|
||||
enum BodyFileType
|
||||
{
|
||||
BODY_FILE_FINAL,
|
||||
BODY_FILE_TMP
|
||||
};
|
||||
nsresult
|
||||
BodyCreateDir(nsIFile* aBaseDir);
|
||||
|
||||
static nsresult BodyCreateDir(nsIFile* aBaseDir);
|
||||
// Note that this function can only be used during the initialization of the
|
||||
// database. We're unlikely to be able to delete the DB successfully past
|
||||
// that point due to the file being in use.
|
||||
static nsresult BodyDeleteDir(nsIFile* aBaseDir);
|
||||
static nsresult BodyGetCacheDir(nsIFile* aBaseDir, const nsID& aId,
|
||||
nsIFile** aCacheDirOut);
|
||||
// Note that this function can only be used during the initialization of the
|
||||
// database. We're unlikely to be able to delete the DB successfully past
|
||||
// that point due to the file being in use.
|
||||
nsresult
|
||||
BodyDeleteDir(nsIFile* aBaseDir);
|
||||
|
||||
static nsresult
|
||||
BodyStartWriteStream(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir,
|
||||
nsIInputStream* aSource, void* aClosure,
|
||||
nsAsyncCopyCallbackFun aCallback, nsID* aIdOut,
|
||||
nsISupports** aCopyContextOut);
|
||||
nsresult
|
||||
BodyGetCacheDir(nsIFile* aBaseDir, const nsID& aId, nsIFile** aCacheDirOut);
|
||||
|
||||
static void
|
||||
BodyCancelWrite(nsIFile* aBaseDir, nsISupports* aCopyContext);
|
||||
nsresult
|
||||
BodyStartWriteStream(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir,
|
||||
nsIInputStream* aSource, void* aClosure,
|
||||
nsAsyncCopyCallbackFun aCallback, nsID* aIdOut,
|
||||
nsISupports** aCopyContextOut);
|
||||
|
||||
static nsresult
|
||||
BodyFinalizeWrite(nsIFile* aBaseDir, const nsID& aId);
|
||||
void
|
||||
BodyCancelWrite(nsIFile* aBaseDir, nsISupports* aCopyContext);
|
||||
|
||||
static nsresult
|
||||
BodyOpen(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir, const nsID& aId,
|
||||
nsIInputStream** aStreamOut);
|
||||
nsresult
|
||||
BodyFinalizeWrite(nsIFile* aBaseDir, const nsID& aId);
|
||||
|
||||
static nsresult
|
||||
BodyDeleteFiles(nsIFile* aBaseDir, const nsTArray<nsID>& aIdList);
|
||||
nsresult
|
||||
BodyOpen(const QuotaInfo& aQuotaInfo, nsIFile* aBaseDir, const nsID& aId,
|
||||
nsIInputStream** aStreamOut);
|
||||
|
||||
private:
|
||||
static nsresult
|
||||
BodyIdToFile(nsIFile* aBaseDir, const nsID& aId, BodyFileType aType,
|
||||
nsIFile** aBodyFileOut);
|
||||
|
||||
FileUtils() = delete;
|
||||
~FileUtils() = delete;
|
||||
};
|
||||
nsresult
|
||||
BodyDeleteFiles(nsIFile* aBaseDir, const nsTArray<nsID>& aIdList);
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
|
|
|
@ -8,10 +8,47 @@
|
|||
#define mozilla_dom_cache_IPCUtils_h
|
||||
|
||||
#include "ipc/IPCMessageUtils.h"
|
||||
|
||||
// Fix X11 header brain damage that conflicts with HeadersGuardEnum::None
|
||||
#undef None
|
||||
|
||||
#include "mozilla/dom/HeadersBinding.h"
|
||||
#include "mozilla/dom/RequestBinding.h"
|
||||
#include "mozilla/dom/ResponseBinding.h"
|
||||
#include "mozilla/dom/cache/Types.h"
|
||||
|
||||
namespace IPC {
|
||||
template<>
|
||||
struct ParamTraits<mozilla::dom::HeadersGuardEnum> :
|
||||
public ContiguousEnumSerializer<mozilla::dom::HeadersGuardEnum,
|
||||
mozilla::dom::HeadersGuardEnum::None,
|
||||
mozilla::dom::HeadersGuardEnum::EndGuard_> {};
|
||||
template<>
|
||||
struct ParamTraits<mozilla::dom::RequestMode> :
|
||||
public ContiguousEnumSerializer<mozilla::dom::RequestMode,
|
||||
mozilla::dom::RequestMode::Same_origin,
|
||||
mozilla::dom::RequestMode::EndGuard_> {};
|
||||
template<>
|
||||
struct ParamTraits<mozilla::dom::RequestCredentials> :
|
||||
public ContiguousEnumSerializer<mozilla::dom::RequestCredentials,
|
||||
mozilla::dom::RequestCredentials::Omit,
|
||||
mozilla::dom::RequestCredentials::EndGuard_> {};
|
||||
template<>
|
||||
struct ParamTraits<mozilla::dom::RequestCache> :
|
||||
public ContiguousEnumSerializer<mozilla::dom::RequestCache,
|
||||
mozilla::dom::RequestCache::Default,
|
||||
mozilla::dom::RequestCache::EndGuard_> {};
|
||||
template<>
|
||||
struct ParamTraits<mozilla::dom::RequestContext> :
|
||||
public ContiguousEnumSerializer<mozilla::dom::RequestContext,
|
||||
mozilla::dom::RequestContext::Audio,
|
||||
mozilla::dom::RequestContext::EndGuard_> {};
|
||||
template<>
|
||||
struct ParamTraits<mozilla::dom::ResponseType> :
|
||||
public ContiguousEnumSerializer<mozilla::dom::ResponseType,
|
||||
mozilla::dom::ResponseType::Basic,
|
||||
mozilla::dom::ResponseType::EndGuard_> {};
|
||||
template<>
|
||||
struct ParamTraits<mozilla::dom::cache::Namespace> :
|
||||
public ContiguousEnumSerializer<mozilla::dom::cache::Namespace,
|
||||
mozilla::dom::cache::DEFAULT_NAMESPACE,
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -7,11 +7,10 @@
|
|||
#ifndef mozilla_dom_cache_Manager_h
|
||||
#define mozilla_dom_cache_Manager_h
|
||||
|
||||
#include "mozilla/dom/cache/CacheInitData.h"
|
||||
#include "mozilla/dom/cache/PCacheStreamControlParent.h"
|
||||
#include "mozilla/dom/cache/Types.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsRefPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
|
@ -22,12 +21,11 @@ namespace mozilla {
|
|||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
class CacheOpArgs;
|
||||
class CacheOpResult;
|
||||
class CacheRequestResponse;
|
||||
class Context;
|
||||
class ManagerId;
|
||||
class PCacheQueryParams;
|
||||
class PCacheRequest;
|
||||
class PCacheRequestOrVoid;
|
||||
struct SavedRequest;
|
||||
struct SavedResponse;
|
||||
class StreamList;
|
||||
|
@ -86,30 +84,36 @@ public:
|
|||
class Listener
|
||||
{
|
||||
public:
|
||||
virtual void OnCacheMatch(RequestId aRequestId, nsresult aRv,
|
||||
const SavedResponse* aResponse,
|
||||
StreamList* aStreamList) { }
|
||||
virtual void OnCacheMatchAll(RequestId aRequestId, nsresult aRv,
|
||||
const nsTArray<SavedResponse>& aSavedResponses,
|
||||
StreamList* aStreamList) { }
|
||||
virtual void OnCachePutAll(RequestId aRequestId, nsresult aRv) { }
|
||||
virtual void OnCacheDelete(RequestId aRequestId, nsresult aRv,
|
||||
bool aSuccess) { }
|
||||
virtual void OnCacheKeys(RequestId aRequestId, nsresult aRv,
|
||||
const nsTArray<SavedRequest>& aSavedRequests,
|
||||
StreamList* aStreamList) { }
|
||||
// convenience routines
|
||||
void
|
||||
OnOpComplete(ErrorResult&& aRv, const CacheOpResult& aResult);
|
||||
|
||||
virtual void OnStorageMatch(RequestId aRequestId, nsresult aRv,
|
||||
const SavedResponse* aResponse,
|
||||
StreamList* aStreamList) { }
|
||||
virtual void OnStorageHas(RequestId aRequestId, nsresult aRv,
|
||||
bool aCacheFound) { }
|
||||
virtual void OnStorageOpen(RequestId aRequestId, nsresult aRv,
|
||||
CacheId aCacheId) { }
|
||||
virtual void OnStorageDelete(RequestId aRequestId, nsresult aRv,
|
||||
bool aCacheDeleted) { }
|
||||
virtual void OnStorageKeys(RequestId aRequestId, nsresult aRv,
|
||||
const nsTArray<nsString>& aKeys) { }
|
||||
void
|
||||
OnOpComplete(ErrorResult&& aRv, const CacheOpResult& aResult,
|
||||
CacheId aOpenedCacheId);
|
||||
|
||||
void
|
||||
OnOpComplete(ErrorResult&& aRv, const CacheOpResult& aResult,
|
||||
const SavedResponse& aSavedResponse,
|
||||
StreamList* aStreamList);
|
||||
|
||||
void
|
||||
OnOpComplete(ErrorResult&& aRv, const CacheOpResult& aResult,
|
||||
const nsTArray<SavedResponse>& aSavedResponseList,
|
||||
StreamList* aStreamList);
|
||||
|
||||
void
|
||||
OnOpComplete(ErrorResult&& aRv, const CacheOpResult& aResult,
|
||||
const nsTArray<SavedRequest>& aSavedRequestList,
|
||||
StreamList* aStreamList);
|
||||
|
||||
// interface to be implemented
|
||||
virtual void
|
||||
OnOpComplete(ErrorResult&& aRv, const CacheOpResult& aResult,
|
||||
CacheId aOpenedCacheId,
|
||||
const nsTArray<SavedResponse>& aSavedResponseList,
|
||||
const nsTArray<SavedRequest>& aSavedRequestList,
|
||||
StreamList* aStreamList) { }
|
||||
|
||||
protected:
|
||||
~Listener() { }
|
||||
|
@ -129,8 +133,8 @@ public:
|
|||
|
||||
// Marks the Manager "invalid". Once the Context completes no new operations
|
||||
// will be permitted with this Manager. New actors will get a new Manager.
|
||||
void Invalidate();
|
||||
bool IsValid() const;
|
||||
void NoteClosing();
|
||||
bool IsClosing() const;
|
||||
|
||||
// If an actor represents a long term reference to a cache or body stream,
|
||||
// then they must call AddRefCacheId() or AddRefBodyId(). This will
|
||||
|
@ -150,35 +154,15 @@ public:
|
|||
void AddStreamList(StreamList* aStreamList);
|
||||
void RemoveStreamList(StreamList* aStreamList);
|
||||
|
||||
// TODO: consider moving CacheId up in the argument lists below (bug 1110485)
|
||||
void CacheMatch(Listener* aListener, RequestId aRequestId, CacheId aCacheId,
|
||||
const PCacheRequest& aRequest,
|
||||
const PCacheQueryParams& aParams);
|
||||
void CacheMatchAll(Listener* aListener, RequestId aRequestId,
|
||||
CacheId aCacheId, const PCacheRequestOrVoid& aRequestOrVoid,
|
||||
const PCacheQueryParams& aParams);
|
||||
void CachePutAll(Listener* aListener, RequestId aRequestId, CacheId aCacheId,
|
||||
const nsTArray<CacheRequestResponse>& aPutList,
|
||||
const nsTArray<nsCOMPtr<nsIInputStream>>& aRequestStreamList,
|
||||
const nsTArray<nsCOMPtr<nsIInputStream>>& aResponseStreamList);
|
||||
void CacheDelete(Listener* aListener, RequestId aRequestId,
|
||||
CacheId aCacheId, const PCacheRequest& aRequest,
|
||||
const PCacheQueryParams& aParams);
|
||||
void CacheKeys(Listener* aListener, RequestId aRequestId,
|
||||
CacheId aCacheId, const PCacheRequestOrVoid& aRequestOrVoid,
|
||||
const PCacheQueryParams& aParams);
|
||||
void ExecuteCacheOp(Listener* aListener, CacheId aCacheId,
|
||||
const CacheOpArgs& aOpArgs);
|
||||
void ExecutePutAll(Listener* aListener, CacheId aCacheId,
|
||||
const nsTArray<CacheRequestResponse>& aPutList,
|
||||
const nsTArray<nsCOMPtr<nsIInputStream>>& aRequestStreamList,
|
||||
const nsTArray<nsCOMPtr<nsIInputStream>>& aResponseStreamList);
|
||||
|
||||
void StorageMatch(Listener* aListener, RequestId aRequestId,
|
||||
Namespace aNamespace, const PCacheRequest& aRequest,
|
||||
const PCacheQueryParams& aParams);
|
||||
void StorageHas(Listener* aListener, RequestId aRequestId,
|
||||
Namespace aNamespace, const nsAString& aKey);
|
||||
void StorageOpen(Listener* aListener, RequestId aRequestId,
|
||||
Namespace aNamespace, const nsAString& aKey);
|
||||
void StorageDelete(Listener* aListener, RequestId aRequestId,
|
||||
Namespace aNamespace, const nsAString& aKey);
|
||||
void StorageKeys(Listener* aListener, RequestId aRequestId,
|
||||
Namespace aNamespace);
|
||||
void ExecuteStorageOp(Listener* aListener, Namespace aNamespace,
|
||||
const CacheOpArgs& aOpArgs);
|
||||
|
||||
private:
|
||||
class Factory;
|
||||
|
@ -201,6 +185,7 @@ private:
|
|||
|
||||
Manager(ManagerId* aManagerId, nsIThread* aIOThread);
|
||||
~Manager();
|
||||
void Init();
|
||||
void Shutdown();
|
||||
already_AddRefed<Context> CurrentContext();
|
||||
|
||||
|
@ -264,7 +249,7 @@ private:
|
|||
nsTArray<StreamList*> mStreamLists;
|
||||
|
||||
bool mShuttingDown;
|
||||
bool mValid;
|
||||
bool mClosing;
|
||||
|
||||
struct CacheIdRefCounter
|
||||
{
|
||||
|
|
|
@ -3,16 +3,13 @@
|
|||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PBackground;
|
||||
include protocol PBlob; // FIXME: bug 792908
|
||||
include protocol PCacheOp;
|
||||
include protocol PCachePushStream;
|
||||
include PCacheTypes;
|
||||
include protocol PCacheStreamControl;
|
||||
include protocol PFileDescriptorSet;
|
||||
|
||||
include protocol PBlob; // FIXME: bug 792908
|
||||
include protocol PCacheStreamControl;
|
||||
|
||||
using mozilla::dom::cache::RequestId from "mozilla/dom/cache/Types.h";
|
||||
using mozilla::ErrorResult from "ipc/ErrorIPCUtils.h";
|
||||
include "mozilla/dom/cache/IPCUtils.h";
|
||||
include CacheTypes;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -21,27 +18,15 @@ namespace cache {
|
|||
protocol PCache
|
||||
{
|
||||
manager PBackground;
|
||||
manages PCacheOp;
|
||||
manages PCachePushStream;
|
||||
|
||||
parent:
|
||||
PCacheOp(CacheOpArgs aOpArgs);
|
||||
PCachePushStream();
|
||||
Teardown();
|
||||
Match(RequestId requestId, PCacheRequest request, PCacheQueryParams params);
|
||||
MatchAll(RequestId requestId, PCacheRequestOrVoid request, PCacheQueryParams params);
|
||||
AddAll(RequestId requestId, PCacheRequest[] requests);
|
||||
Put(RequestId requestId, CacheRequestResponse aPut);
|
||||
Delete(RequestId requestId, PCacheRequest request, PCacheQueryParams params);
|
||||
Keys(RequestId requestId, PCacheRequestOrVoid request, PCacheQueryParams params);
|
||||
|
||||
child:
|
||||
MatchResponse(RequestId requestId, nsresult aRv, PCacheResponseOrVoid aResponse);
|
||||
MatchAllResponse(RequestId requestId, nsresult aRv, PCacheResponse[] responses);
|
||||
AddAllResponse(RequestId requestId, ErrorResult aRv);
|
||||
PutResponse(RequestId requestId, nsresult aRv);
|
||||
DeleteResponse(RequestId requestId, nsresult aRv, bool success);
|
||||
KeysResponse(RequestId requestId, nsresult aRv, PCacheRequest[] requests);
|
||||
|
||||
both:
|
||||
__delete__();
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PCache;
|
||||
include protocol PCachePushStream;
|
||||
include protocol PCacheStorage;
|
||||
include protocol PCacheStreamControl;
|
||||
include protocol PFileDescriptorSet;
|
||||
|
||||
include CacheTypes;
|
||||
|
||||
using mozilla::ErrorResult from "ipc/ErrorIPCUtils.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
protocol PCacheOp
|
||||
{
|
||||
manager PCache or PCacheStorage;
|
||||
|
||||
child:
|
||||
__delete__(ErrorResult aRv, CacheOpResult aResult);
|
||||
};
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
|
@ -3,14 +3,13 @@
|
|||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PBackground;
|
||||
include protocol PBlob; // FIXME: bug 792908
|
||||
include protocol PCache;
|
||||
include PCacheTypes;
|
||||
include protocol PCacheOp;
|
||||
include protocol PCacheStreamControl;
|
||||
include protocol PFileDescriptorSet;
|
||||
|
||||
include protocol PBlob; // FIXME: bug 792908
|
||||
include protocol PCacheStreamControl;
|
||||
|
||||
using mozilla::dom::cache::RequestId from "mozilla/dom/cache/IPCUtils.h";
|
||||
include CacheTypes;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -19,23 +18,13 @@ namespace cache {
|
|||
protocol PCacheStorage
|
||||
{
|
||||
manager PBackground;
|
||||
manages PCacheOp;
|
||||
|
||||
parent:
|
||||
PCacheOp(CacheOpArgs aOpArgs);
|
||||
Teardown();
|
||||
Match(RequestId aRequestId, PCacheRequest aRequest,
|
||||
PCacheQueryParams aParams);
|
||||
Has(RequestId aRequestId, nsString aKey);
|
||||
Open(RequestId aRequestId, nsString aKey);
|
||||
Delete(RequestId aRequestId, nsString aKey);
|
||||
Keys(RequestId aRequestId);
|
||||
|
||||
child:
|
||||
MatchResponse(RequestId aRequestId, nsresult aRv,
|
||||
PCacheResponseOrVoid aResponseOrVoid);
|
||||
HasResponse(RequestId aRequestId, nsresult aRv, bool aSuccess);
|
||||
OpenResponse(RequestId aRequestId, nsresult aRv, nullable PCache aActor);
|
||||
DeleteResponse(RequestId aRequestId, nsresult aRv, bool aSuccess);
|
||||
KeysResponse(RequestId aRequestId, nsresult aRv, nsString[] aKeys);
|
||||
__delete__();
|
||||
};
|
||||
|
||||
|
|
|
@ -1,95 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PCachePushStream;
|
||||
include protocol PCacheStreamControl;
|
||||
include PHeaders;
|
||||
include InputStreamParams;
|
||||
|
||||
using HeadersGuardEnum from "mozilla/dom/FetchIPCUtils.h";
|
||||
using RequestCredentials from "mozilla/dom/FetchIPCUtils.h";
|
||||
using RequestMode from "mozilla/dom/FetchIPCUtils.h";
|
||||
using RequestCache from "mozilla/dom/FetchIPCUtils.h";
|
||||
using RequestContext from "mozilla/dom/FetchIPCUtils.h";
|
||||
using mozilla::dom::ResponseType from "mozilla/dom/FetchIPCUtils.h";
|
||||
using mozilla::void_t from "ipc/IPCMessageUtils.h";
|
||||
using struct nsID from "nsID.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
struct PCacheQueryParams
|
||||
{
|
||||
bool ignoreSearch;
|
||||
bool ignoreMethod;
|
||||
bool ignoreVary;
|
||||
bool cacheNameSet;
|
||||
nsString cacheName;
|
||||
};
|
||||
|
||||
struct PCacheReadStream
|
||||
{
|
||||
nsID id;
|
||||
OptionalInputStreamParams params;
|
||||
OptionalFileDescriptorSet fds;
|
||||
nullable PCacheStreamControl control;
|
||||
nullable PCachePushStream pushStream;
|
||||
};
|
||||
|
||||
union PCacheReadStreamOrVoid
|
||||
{
|
||||
void_t;
|
||||
PCacheReadStream;
|
||||
};
|
||||
|
||||
struct PCacheRequest
|
||||
{
|
||||
nsCString method;
|
||||
nsString url;
|
||||
nsString urlWithoutQuery;
|
||||
PHeadersEntry[] headers;
|
||||
HeadersGuardEnum headersGuard;
|
||||
nsString referrer;
|
||||
RequestMode mode;
|
||||
RequestCredentials credentials;
|
||||
PCacheReadStreamOrVoid body;
|
||||
uint32_t contentPolicyType;
|
||||
RequestContext context;
|
||||
RequestCache requestCache;
|
||||
};
|
||||
|
||||
union PCacheRequestOrVoid
|
||||
{
|
||||
void_t;
|
||||
PCacheRequest;
|
||||
};
|
||||
|
||||
struct PCacheResponse
|
||||
{
|
||||
ResponseType type;
|
||||
nsString url;
|
||||
uint32_t status;
|
||||
nsCString statusText;
|
||||
PHeadersEntry[] headers;
|
||||
HeadersGuardEnum headersGuard;
|
||||
PCacheReadStreamOrVoid body;
|
||||
nsCString securityInfo;
|
||||
};
|
||||
|
||||
union PCacheResponseOrVoid
|
||||
{
|
||||
void_t;
|
||||
PCacheResponse;
|
||||
};
|
||||
|
||||
struct CacheRequestResponse
|
||||
{
|
||||
PCacheRequest request;
|
||||
PCacheResponse response;
|
||||
};
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
|
@ -46,25 +46,35 @@ PrincipalVerifier::CreateAndDispatch(Listener* aListener,
|
|||
}
|
||||
|
||||
void
|
||||
PrincipalVerifier::ClearListener()
|
||||
PrincipalVerifier::AddListener(Listener* aListener)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(mListener);
|
||||
mListener = nullptr;
|
||||
MOZ_ASSERT(aListener);
|
||||
MOZ_ASSERT(!mListenerList.Contains(aListener));
|
||||
mListenerList.AppendElement(aListener);
|
||||
}
|
||||
|
||||
void
|
||||
PrincipalVerifier::RemoveListener(Listener* aListener)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(aListener);
|
||||
MOZ_ALWAYS_TRUE(mListenerList.RemoveElement(aListener));
|
||||
}
|
||||
|
||||
PrincipalVerifier::PrincipalVerifier(Listener* aListener,
|
||||
PBackgroundParent* aActor,
|
||||
const PrincipalInfo& aPrincipalInfo)
|
||||
: mListener(aListener)
|
||||
, mActor(BackgroundParent::GetContentParent(aActor))
|
||||
: mActor(BackgroundParent::GetContentParent(aActor))
|
||||
, mPrincipalInfo(aPrincipalInfo)
|
||||
, mInitiatingThread(NS_GetCurrentThread())
|
||||
, mResult(NS_OK)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(mListener);
|
||||
MOZ_ASSERT(mInitiatingThread);
|
||||
MOZ_ASSERT(aListener);
|
||||
|
||||
mListenerList.AppendElement(aListener);
|
||||
}
|
||||
|
||||
PrincipalVerifier::~PrincipalVerifier()
|
||||
|
@ -73,7 +83,7 @@ PrincipalVerifier::~PrincipalVerifier()
|
|||
// threads, its a race to see which thread de-refs us last. Therefore
|
||||
// we cannot guarantee which thread we destruct on.
|
||||
|
||||
MOZ_ASSERT(!mListener);
|
||||
MOZ_ASSERT(mListenerList.IsEmpty());
|
||||
|
||||
// We should always be able to explicitly release the actor on the main
|
||||
// thread.
|
||||
|
@ -172,17 +182,13 @@ void
|
|||
PrincipalVerifier::CompleteOnInitiatingThread()
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
// This can happen if the listener is destroyed before we finish. For
|
||||
// example, if the child process OOMs and the actor is destroyed.
|
||||
if (!mListener) {
|
||||
return;
|
||||
ListenerList::ForwardIterator iter(mListenerList);
|
||||
while (iter.HasMore()) {
|
||||
iter.GetNext()->OnPrincipalVerified(mResult, mManagerId);
|
||||
}
|
||||
|
||||
mListener->OnPrincipalVerified(mResult, mManagerId);
|
||||
|
||||
// The listener must clear their reference in OnPrincipalVerified()
|
||||
MOZ_ASSERT(!mListener);
|
||||
// The listener must clear its reference in OnPrincipalVerified()
|
||||
MOZ_ASSERT(mListenerList.IsEmpty());
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "mozilla/ipc/PBackgroundSharedTypes.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsTObserverArray.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -26,7 +27,7 @@ class PrincipalVerifier final : public nsRunnable
|
|||
public:
|
||||
// An interface to be implemented by code wishing to use the
|
||||
// PrincipalVerifier. Note, the Listener implementation is responsible
|
||||
// for calling ClearListener() on the PrincipalVerifier to clear the
|
||||
// for calling RemoveListener() on the PrincipalVerifier to clear the
|
||||
// weak reference.
|
||||
class Listener
|
||||
{
|
||||
|
@ -38,9 +39,11 @@ public:
|
|||
CreateAndDispatch(Listener* aListener, mozilla::ipc::PBackgroundParent* aActor,
|
||||
const mozilla::ipc::PrincipalInfo& aPrincipalInfo);
|
||||
|
||||
// The Listener must call ClearListener() when OnPrincipalVerified() is
|
||||
void AddListener(Listener* aListener);
|
||||
|
||||
// The Listener must call RemoveListener() when OnPrincipalVerified() is
|
||||
// called or when the Listener is destroyed.
|
||||
void ClearListener();
|
||||
void RemoveListener(Listener* aListener);
|
||||
|
||||
private:
|
||||
PrincipalVerifier(Listener* aListener, mozilla::ipc::PBackgroundParent* aActor,
|
||||
|
@ -52,8 +55,9 @@ private:
|
|||
|
||||
void DispatchToInitiatingThread(nsresult aRv);
|
||||
|
||||
// Weak reference cleared by ClearListener()
|
||||
Listener* mListener;
|
||||
// Weak reference cleared by RemoveListener()
|
||||
typedef nsTObserverArray<Listener*> ListenerList;
|
||||
ListenerList mListenerList;
|
||||
|
||||
// set in originating thread at construction, but must be accessed and
|
||||
// released on main thread
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include "mozilla/unused.h"
|
||||
#include "mozilla/dom/cache/CacheStreamControlChild.h"
|
||||
#include "mozilla/dom/cache/CacheStreamControlParent.h"
|
||||
#include "mozilla/dom/cache/PCacheTypes.h"
|
||||
#include "mozilla/dom/cache/CacheTypes.h"
|
||||
#include "mozilla/ipc/FileDescriptor.h"
|
||||
#include "mozilla/ipc/InputStreamUtils.h"
|
||||
#include "mozilla/SnappyUncompressInputStream.h"
|
||||
|
@ -35,10 +35,10 @@ public:
|
|||
nsIInputStream* aStream);
|
||||
|
||||
void
|
||||
Serialize(PCacheReadStreamOrVoid* aReadStreamOut);
|
||||
Serialize(CacheReadStreamOrVoid* aReadStreamOut);
|
||||
|
||||
void
|
||||
Serialize(PCacheReadStream* aReadStreamOut);
|
||||
Serialize(CacheReadStream* aReadStreamOut);
|
||||
|
||||
// ReadStream::Controllable methods
|
||||
virtual void
|
||||
|
@ -50,6 +50,9 @@ public:
|
|||
virtual bool
|
||||
MatchId(const nsID& aId) const override;
|
||||
|
||||
virtual bool
|
||||
HasEverBeenRead() const override;
|
||||
|
||||
// Simulate nsIInputStream methods, but we don't actually inherit from it
|
||||
NS_METHOD
|
||||
Close();
|
||||
|
@ -103,6 +106,7 @@ private:
|
|||
NumStates
|
||||
};
|
||||
Atomic<State> mState;
|
||||
Atomic<bool> mHasEverBeenRead;
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(cache::ReadStream::Inner, override)
|
||||
};
|
||||
|
@ -193,17 +197,17 @@ ReadStream::Inner::Inner(StreamControl* aControl, const nsID& aId,
|
|||
}
|
||||
|
||||
void
|
||||
ReadStream::Inner::Serialize(PCacheReadStreamOrVoid* aReadStreamOut)
|
||||
ReadStream::Inner::Serialize(CacheReadStreamOrVoid* aReadStreamOut)
|
||||
{
|
||||
MOZ_ASSERT(NS_GetCurrentThread() == mOwningThread);
|
||||
MOZ_ASSERT(aReadStreamOut);
|
||||
PCacheReadStream stream;
|
||||
CacheReadStream stream;
|
||||
Serialize(&stream);
|
||||
*aReadStreamOut = stream;
|
||||
}
|
||||
|
||||
void
|
||||
ReadStream::Inner::Serialize(PCacheReadStream* aReadStreamOut)
|
||||
ReadStream::Inner::Serialize(CacheReadStream* aReadStreamOut)
|
||||
{
|
||||
MOZ_ASSERT(NS_GetCurrentThread() == mOwningThread);
|
||||
MOZ_ASSERT(aReadStreamOut);
|
||||
|
@ -249,6 +253,13 @@ ReadStream::Inner::MatchId(const nsID& aId) const
|
|||
return mId.Equals(aId);
|
||||
}
|
||||
|
||||
bool
|
||||
ReadStream::Inner::HasEverBeenRead() const
|
||||
{
|
||||
MOZ_ASSERT(NS_GetCurrentThread() == mOwningThread);
|
||||
return mHasEverBeenRead;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ReadStream::Inner::Close()
|
||||
{
|
||||
|
@ -284,6 +295,8 @@ ReadStream::Inner::Read(char* aBuf, uint32_t aCount, uint32_t* aNumReadOut)
|
|||
Close();
|
||||
}
|
||||
|
||||
mHasEverBeenRead = true;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -294,6 +307,10 @@ ReadStream::Inner::ReadSegments(nsWriteSegmentFun aWriter, void* aClosure,
|
|||
// stream ops can happen on any thread
|
||||
MOZ_ASSERT(aNumReadOut);
|
||||
|
||||
if (aCount) {
|
||||
mHasEverBeenRead = true;
|
||||
}
|
||||
|
||||
nsresult rv = mSnappyStream->ReadSegments(aWriter, aClosure, aCount,
|
||||
aNumReadOut);
|
||||
|
||||
|
@ -302,6 +319,14 @@ ReadStream::Inner::ReadSegments(nsWriteSegmentFun aWriter, void* aClosure,
|
|||
Close();
|
||||
}
|
||||
|
||||
// Verify bytes were actually read before marking as being ever read. For
|
||||
// example, code can test if the stream supports ReadSegments() by calling
|
||||
// this method with a dummy callback which doesn't read anything. We don't
|
||||
// want to trigger on that.
|
||||
if (*aNumReadOut) {
|
||||
mHasEverBeenRead = true;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -391,18 +416,18 @@ NS_IMPL_ISUPPORTS(cache::ReadStream, nsIInputStream, ReadStream);
|
|||
|
||||
// static
|
||||
already_AddRefed<ReadStream>
|
||||
ReadStream::Create(const PCacheReadStreamOrVoid& aReadStreamOrVoid)
|
||||
ReadStream::Create(const CacheReadStreamOrVoid& aReadStreamOrVoid)
|
||||
{
|
||||
if (aReadStreamOrVoid.type() == PCacheReadStreamOrVoid::Tvoid_t) {
|
||||
if (aReadStreamOrVoid.type() == CacheReadStreamOrVoid::Tvoid_t) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return Create(aReadStreamOrVoid.get_PCacheReadStream());
|
||||
return Create(aReadStreamOrVoid.get_CacheReadStream());
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<ReadStream>
|
||||
ReadStream::Create(const PCacheReadStream& aReadStream)
|
||||
ReadStream::Create(const CacheReadStream& aReadStream)
|
||||
{
|
||||
// The parameter may or may not be for a Cache created stream. The way we
|
||||
// tell is by looking at the stream control actor. If the actor exists,
|
||||
|
@ -457,13 +482,13 @@ ReadStream::Create(PCacheStreamControlParent* aControl, const nsID& aId,
|
|||
}
|
||||
|
||||
void
|
||||
ReadStream::Serialize(PCacheReadStreamOrVoid* aReadStreamOut)
|
||||
ReadStream::Serialize(CacheReadStreamOrVoid* aReadStreamOut)
|
||||
{
|
||||
mInner->Serialize(aReadStreamOut);
|
||||
}
|
||||
|
||||
void
|
||||
ReadStream::Serialize(PCacheReadStream* aReadStreamOut)
|
||||
ReadStream::Serialize(CacheReadStream* aReadStreamOut)
|
||||
{
|
||||
mInner->Serialize(aReadStreamOut);
|
||||
}
|
||||
|
|
|
@ -21,8 +21,8 @@ namespace mozilla {
|
|||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
class PCacheReadStream;
|
||||
class PCacheReadStreamOrVoid;
|
||||
class CacheReadStream;
|
||||
class CacheReadStreamOrVoid;
|
||||
class PCacheStreamControlParent;
|
||||
|
||||
// IID for the dom::cache::ReadStream interface
|
||||
|
@ -63,6 +63,9 @@ public:
|
|||
virtual bool
|
||||
MatchId(const nsID& aId) const = 0;
|
||||
|
||||
virtual bool
|
||||
HasEverBeenRead() const = 0;
|
||||
|
||||
NS_IMETHOD_(MozExternalRefCountType)
|
||||
AddRef(void) = 0;
|
||||
|
||||
|
@ -71,17 +74,17 @@ public:
|
|||
};
|
||||
|
||||
static already_AddRefed<ReadStream>
|
||||
Create(const PCacheReadStreamOrVoid& aReadStreamOrVoid);
|
||||
Create(const CacheReadStreamOrVoid& aReadStreamOrVoid);
|
||||
|
||||
static already_AddRefed<ReadStream>
|
||||
Create(const PCacheReadStream& aReadStream);
|
||||
Create(const CacheReadStream& aReadStream);
|
||||
|
||||
static already_AddRefed<ReadStream>
|
||||
Create(PCacheStreamControlParent* aControl, const nsID& aId,
|
||||
nsIInputStream* aStream);
|
||||
|
||||
void Serialize(PCacheReadStreamOrVoid* aReadStreamOut);
|
||||
void Serialize(PCacheReadStream* aReadStreamOut);
|
||||
void Serialize(CacheReadStreamOrVoid* aReadStreamOut);
|
||||
void Serialize(CacheReadStream* aReadStreamOut);
|
||||
|
||||
private:
|
||||
class Inner;
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
// NOTE: This cannot be rolled into Types.h because the IPC dependency.
|
||||
// breaks webidl unified builds.
|
||||
|
||||
#include "mozilla/dom/cache/PCacheTypes.h"
|
||||
#include "mozilla/dom/cache/CacheTypes.h"
|
||||
#include "mozilla/dom/cache/Types.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsID.h"
|
||||
|
@ -23,7 +23,7 @@ namespace cache {
|
|||
struct SavedRequest
|
||||
{
|
||||
SavedRequest() : mHasBodyId(false) { mValue.body() = void_t(); }
|
||||
PCacheRequest mValue;
|
||||
CacheRequest mValue;
|
||||
bool mHasBodyId;
|
||||
nsID mBodyId;
|
||||
CacheId mCacheId;
|
||||
|
@ -32,7 +32,7 @@ struct SavedRequest
|
|||
struct SavedResponse
|
||||
{
|
||||
SavedResponse() : mHasBodyId(false) { mValue.body() = void_t(); }
|
||||
PCacheResponse mValue;
|
||||
CacheResponse mValue;
|
||||
bool mHasBodyId;
|
||||
nsID mBodyId;
|
||||
CacheId mCacheId;
|
||||
|
|
|
@ -84,6 +84,18 @@ StreamControl::CloseAllReadStreamsWithoutReporting()
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
StreamControl::HasEverBeenRead() const
|
||||
{
|
||||
ReadStreamList::ForwardIterator iter(mReadStreamList);
|
||||
while (iter.HasMore()) {
|
||||
if (iter.GetNext()->HasEverBeenRead()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace ipc {
|
|||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
class PCacheReadStream;
|
||||
class CacheReadStream;
|
||||
|
||||
// Abstract class to help implement the stream control Child and Parent actors.
|
||||
// This provides an interface to partly help with serialization of IPC types,
|
||||
|
@ -30,14 +30,14 @@ class StreamControl
|
|||
public:
|
||||
// abstract interface that must be implemented by child class
|
||||
virtual void
|
||||
SerializeControl(PCacheReadStream* aReadStreamOut) = 0;
|
||||
SerializeControl(CacheReadStream* aReadStreamOut) = 0;
|
||||
|
||||
virtual void
|
||||
SerializeFds(PCacheReadStream* aReadStreamOut,
|
||||
SerializeFds(CacheReadStream* aReadStreamOut,
|
||||
const nsTArray<mozilla::ipc::FileDescriptor>& aFds) = 0;
|
||||
|
||||
virtual void
|
||||
DeserializeFds(const PCacheReadStream& aReadStream,
|
||||
DeserializeFds(const CacheReadStream& aReadStream,
|
||||
nsTArray<mozilla::ipc::FileDescriptor>& aFdsOut) = 0;
|
||||
|
||||
// inherited implementation of the ReadStream::Controllable list
|
||||
|
@ -68,6 +68,9 @@ protected:
|
|||
void
|
||||
CloseAllReadStreamsWithoutReporting();
|
||||
|
||||
bool
|
||||
HasEverBeenRead() const;
|
||||
|
||||
// protected parts of the abstract interface
|
||||
virtual void
|
||||
NoteClosedAfterForget(const nsID& aId) = 0;
|
||||
|
|
|
@ -1,151 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/cache/StreamUtils.h"
|
||||
|
||||
#include "mozilla/unused.h"
|
||||
#include "mozilla/dom/cache/CacheStreamControlChild.h"
|
||||
#include "mozilla/dom/cache/PCacheTypes.h"
|
||||
#include "mozilla/ipc/FileDescriptor.h"
|
||||
#include "mozilla/ipc/FileDescriptorSetChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
namespace {
|
||||
|
||||
using mozilla::unused;
|
||||
using mozilla::void_t;
|
||||
using mozilla::dom::cache::CacheStreamControlChild;
|
||||
using mozilla::dom::cache::Feature;
|
||||
using mozilla::dom::cache::PCacheReadStream;
|
||||
using mozilla::ipc::FileDescriptor;
|
||||
using mozilla::ipc::FileDescriptorSetChild;
|
||||
using mozilla::ipc::OptionalFileDescriptorSet;
|
||||
|
||||
void
|
||||
StartDestroyStreamChild(const PCacheReadStream& aReadStream)
|
||||
{
|
||||
CacheStreamControlChild* cacheControl =
|
||||
static_cast<CacheStreamControlChild*>(aReadStream.controlChild());
|
||||
if (cacheControl) {
|
||||
cacheControl->StartDestroy();
|
||||
}
|
||||
|
||||
if (aReadStream.fds().type() ==
|
||||
OptionalFileDescriptorSet::TPFileDescriptorSetChild) {
|
||||
nsAutoTArray<FileDescriptor, 4> fds;
|
||||
|
||||
FileDescriptorSetChild* fdSetActor =
|
||||
static_cast<FileDescriptorSetChild*>(aReadStream.fds().get_PFileDescriptorSetChild());
|
||||
MOZ_ASSERT(fdSetActor);
|
||||
|
||||
fdSetActor->ForgetFileDescriptors(fds);
|
||||
MOZ_ASSERT(!fds.IsEmpty());
|
||||
|
||||
unused << fdSetActor->Send__delete__(fdSetActor);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AddFeatureToStreamChild(const PCacheReadStream& aReadStream, Feature* aFeature)
|
||||
{
|
||||
CacheStreamControlChild* cacheControl =
|
||||
static_cast<CacheStreamControlChild*>(aReadStream.controlChild());
|
||||
if (cacheControl) {
|
||||
cacheControl->SetFeature(aFeature);
|
||||
}
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
void
|
||||
StartDestroyStreamChild(const PCacheResponseOrVoid& aResponseOrVoid)
|
||||
{
|
||||
if (aResponseOrVoid.type() == PCacheResponseOrVoid::Tvoid_t) {
|
||||
return;
|
||||
}
|
||||
|
||||
StartDestroyStreamChild(aResponseOrVoid.get_PCacheResponse());
|
||||
}
|
||||
|
||||
void
|
||||
StartDestroyStreamChild(const PCacheResponse& aResponse)
|
||||
{
|
||||
if (aResponse.body().type() == PCacheReadStreamOrVoid::Tvoid_t) {
|
||||
return;
|
||||
}
|
||||
|
||||
StartDestroyStreamChild(aResponse.body().get_PCacheReadStream());
|
||||
}
|
||||
|
||||
void
|
||||
StartDestroyStreamChild(const nsTArray<PCacheResponse>& aResponses)
|
||||
{
|
||||
for (uint32_t i = 0; i < aResponses.Length(); ++i) {
|
||||
StartDestroyStreamChild(aResponses[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StartDestroyStreamChild(const nsTArray<PCacheRequest>& aRequests)
|
||||
{
|
||||
for (uint32_t i = 0; i < aRequests.Length(); ++i) {
|
||||
if (aRequests[i].body().type() == PCacheReadStreamOrVoid::Tvoid_t) {
|
||||
continue;
|
||||
}
|
||||
StartDestroyStreamChild(aRequests[i].body().get_PCacheReadStream());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AddFeatureToStreamChild(const PCacheResponseOrVoid& aResponseOrVoid,
|
||||
Feature* aFeature)
|
||||
{
|
||||
if (aResponseOrVoid.type() == PCacheResponseOrVoid::Tvoid_t) {
|
||||
return;
|
||||
}
|
||||
|
||||
AddFeatureToStreamChild(aResponseOrVoid.get_PCacheResponse(), aFeature);
|
||||
}
|
||||
|
||||
void
|
||||
AddFeatureToStreamChild(const PCacheResponse& aResponse,
|
||||
Feature* aFeature)
|
||||
{
|
||||
if (aResponse.body().type() == PCacheReadStreamOrVoid::Tvoid_t) {
|
||||
return;
|
||||
}
|
||||
|
||||
AddFeatureToStreamChild(aResponse.body().get_PCacheReadStream(), aFeature);
|
||||
}
|
||||
|
||||
void
|
||||
AddFeatureToStreamChild(const nsTArray<PCacheResponse>& aResponses,
|
||||
Feature* aFeature)
|
||||
{
|
||||
for (uint32_t i = 0; i < aResponses.Length(); ++i) {
|
||||
AddFeatureToStreamChild(aResponses[i], aFeature);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AddFeatureToStreamChild(const nsTArray<PCacheRequest>& aRequests,
|
||||
Feature* aFeature)
|
||||
{
|
||||
for (uint32_t i = 0; i < aRequests.Length(); ++i) {
|
||||
if (aRequests[i].body().type() == PCacheReadStreamOrVoid::Tvoid_t) {
|
||||
continue;
|
||||
}
|
||||
AddFeatureToStreamChild(aRequests[i].body().get_PCacheReadStream(),
|
||||
aFeature);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
|
@ -1,39 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_cache_StreamUtils_h
|
||||
#define mozilla_dom_cache_StreamUtils_h
|
||||
|
||||
#include "nsTArrayForwardDeclare.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
class Feature;
|
||||
class PCacheRequest;
|
||||
class PCacheResponse;
|
||||
class PCacheResponseOrVoid;
|
||||
|
||||
void StartDestroyStreamChild(const PCacheResponseOrVoid& aResponseOrVoid);
|
||||
void StartDestroyStreamChild(const PCacheResponse& aResponse);
|
||||
void StartDestroyStreamChild(const nsTArray<PCacheResponse>& aResponses);
|
||||
void StartDestroyStreamChild(const nsTArray<PCacheRequest>& aRequests);
|
||||
|
||||
void AddFeatureToStreamChild(const PCacheResponseOrVoid& aResponseOrVoid,
|
||||
Feature* aFeature);
|
||||
void AddFeatureToStreamChild(const PCacheResponse& aResponse,
|
||||
Feature* aFeature);
|
||||
void AddFeatureToStreamChild(const nsTArray<PCacheResponse>& aResponses,
|
||||
Feature* aFeature);
|
||||
void AddFeatureToStreamChild(const nsTArray<PCacheRequest>& aRequests,
|
||||
Feature* aFeature);
|
||||
|
||||
} // namespace cache
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_cache_StreamUtils_h
|
|
@ -12,7 +12,7 @@
|
|||
#include "mozilla/dom/Request.h"
|
||||
#include "mozilla/dom/Response.h"
|
||||
#include "mozilla/dom/cache/CachePushStreamChild.h"
|
||||
#include "mozilla/dom/cache/PCacheTypes.h"
|
||||
#include "mozilla/dom/cache/CacheTypes.h"
|
||||
#include "mozilla/dom/cache/ReadStream.h"
|
||||
#include "mozilla/ipc/BackgroundChild.h"
|
||||
#include "mozilla/ipc/FileDescriptorSetChild.h"
|
||||
|
@ -34,7 +34,9 @@ namespace {
|
|||
using mozilla::ErrorResult;
|
||||
using mozilla::unused;
|
||||
using mozilla::void_t;
|
||||
using mozilla::dom::cache::PCacheReadStream;
|
||||
using mozilla::dom::InternalHeaders;
|
||||
using mozilla::dom::cache::CacheReadStream;
|
||||
using mozilla::dom::cache::HeadersEntry;
|
||||
using mozilla::ipc::BackgroundChild;
|
||||
using mozilla::ipc::FileDescriptor;
|
||||
using mozilla::ipc::PBackgroundChild;
|
||||
|
@ -130,7 +132,7 @@ HasVaryStar(mozilla::dom::InternalHeaders* aHeaders)
|
|||
}
|
||||
|
||||
void
|
||||
SerializeNormalStream(nsIInputStream* aStream, PCacheReadStream& aReadStreamOut)
|
||||
SerializeNormalStream(nsIInputStream* aStream, CacheReadStream& aReadStreamOut)
|
||||
{
|
||||
nsAutoTArray<FileDescriptor, 4> fds;
|
||||
SerializeInputStream(aStream, aReadStreamOut.params(), fds);
|
||||
|
@ -154,6 +156,20 @@ SerializeNormalStream(nsIInputStream* aStream, PCacheReadStream& aReadStreamOut)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
ToHeadersEntryList(nsTArray<HeadersEntry>& aOut, InternalHeaders* aHeaders)
|
||||
{
|
||||
MOZ_ASSERT(aHeaders);
|
||||
|
||||
nsAutoTArray<InternalHeaders::Entry, 16> entryList;
|
||||
aHeaders->GetEntries(entryList);
|
||||
|
||||
for (uint32_t i = 0; i < entryList.Length(); ++i) {
|
||||
InternalHeaders::Entry& entry = entryList[i];
|
||||
aOut.AppendElement(HeadersEntry(entry.mName, entry.mValue));
|
||||
}
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -206,10 +222,10 @@ TypeUtils::ToInternalRequest(const OwningRequestOrUSVString& aIn,
|
|||
}
|
||||
|
||||
void
|
||||
TypeUtils::ToPCacheRequest(PCacheRequest& aOut, InternalRequest* aIn,
|
||||
BodyAction aBodyAction,
|
||||
ReferrerAction aReferrerAction,
|
||||
SchemeAction aSchemeAction, ErrorResult& aRv)
|
||||
TypeUtils::ToCacheRequest(CacheRequest& aOut, InternalRequest* aIn,
|
||||
BodyAction aBodyAction,
|
||||
ReferrerAction aReferrerAction,
|
||||
SchemeAction aSchemeAction, ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aIn);
|
||||
|
||||
|
@ -245,7 +261,7 @@ TypeUtils::ToPCacheRequest(PCacheRequest& aOut, InternalRequest* aIn,
|
|||
|
||||
nsRefPtr<InternalHeaders> headers = aIn->Headers();
|
||||
MOZ_ASSERT(headers);
|
||||
headers->GetPHeaders(aOut.headers());
|
||||
ToHeadersEntryList(aOut.headers(), headers);
|
||||
aOut.headersGuard() = headers->Guard();
|
||||
aOut.mode() = aIn->Mode();
|
||||
aOut.credentials() = aIn->GetCredentialsMode();
|
||||
|
@ -269,8 +285,8 @@ TypeUtils::ToPCacheRequest(PCacheRequest& aOut, InternalRequest* aIn,
|
|||
}
|
||||
|
||||
void
|
||||
TypeUtils::ToPCacheResponseWithoutBody(PCacheResponse& aOut,
|
||||
InternalResponse& aIn, ErrorResult& aRv)
|
||||
TypeUtils::ToCacheResponseWithoutBody(CacheResponse& aOut,
|
||||
InternalResponse& aIn, ErrorResult& aRv)
|
||||
{
|
||||
aOut.type() = aIn.Type();
|
||||
|
||||
|
@ -295,13 +311,13 @@ TypeUtils::ToPCacheResponseWithoutBody(PCacheResponse& aOut,
|
|||
aRv.ThrowTypeError(MSG_RESPONSE_HAS_VARY_STAR);
|
||||
return;
|
||||
}
|
||||
headers->GetPHeaders(aOut.headers());
|
||||
ToHeadersEntryList(aOut.headers(), headers);
|
||||
aOut.headersGuard() = headers->Guard();
|
||||
aOut.securityInfo() = aIn.GetSecurityInfo();
|
||||
}
|
||||
|
||||
void
|
||||
TypeUtils::ToPCacheResponse(PCacheResponse& aOut, Response& aIn, ErrorResult& aRv)
|
||||
TypeUtils::ToCacheResponse(CacheResponse& aOut, Response& aIn, ErrorResult& aRv)
|
||||
{
|
||||
if (aIn.BodyUsed()) {
|
||||
aRv.ThrowTypeError(MSG_FETCH_BODY_CONSUMED_ERROR);
|
||||
|
@ -309,7 +325,7 @@ TypeUtils::ToPCacheResponse(PCacheResponse& aOut, Response& aIn, ErrorResult& aR
|
|||
}
|
||||
|
||||
nsRefPtr<InternalResponse> ir = aIn.GetInternalResponse();
|
||||
ToPCacheResponseWithoutBody(aOut, *ir, aRv);
|
||||
ToCacheResponseWithoutBody(aOut, *ir, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
@ -328,8 +344,8 @@ TypeUtils::ToPCacheResponse(PCacheResponse& aOut, Response& aIn, ErrorResult& aR
|
|||
|
||||
// static
|
||||
void
|
||||
TypeUtils::ToPCacheQueryParams(PCacheQueryParams& aOut,
|
||||
const CacheQueryOptions& aIn)
|
||||
TypeUtils::ToCacheQueryParams(CacheQueryParams& aOut,
|
||||
const CacheQueryOptions& aIn)
|
||||
{
|
||||
aOut.ignoreSearch() = aIn.mIgnoreSearch;
|
||||
aOut.ignoreMethod() = aIn.mIgnoreMethod;
|
||||
|
@ -343,7 +359,7 @@ TypeUtils::ToPCacheQueryParams(PCacheQueryParams& aOut,
|
|||
}
|
||||
|
||||
already_AddRefed<Response>
|
||||
TypeUtils::ToResponse(const PCacheResponse& aIn)
|
||||
TypeUtils::ToResponse(const CacheResponse& aIn)
|
||||
{
|
||||
if (aIn.type() == ResponseType::Error) {
|
||||
nsRefPtr<InternalResponse> error = InternalResponse::NetworkError();
|
||||
|
@ -356,7 +372,7 @@ TypeUtils::ToResponse(const PCacheResponse& aIn)
|
|||
ir->SetUrl(NS_ConvertUTF16toUTF8(aIn.url()));
|
||||
|
||||
nsRefPtr<InternalHeaders> internalHeaders =
|
||||
new InternalHeaders(aIn.headers(), aIn.headersGuard());
|
||||
ToInternalHeaders(aIn.headers(), aIn.headersGuard());
|
||||
ErrorResult result;
|
||||
ir->Headers()->SetGuard(aIn.headersGuard(), result);
|
||||
MOZ_ASSERT(!result.Failed());
|
||||
|
@ -391,7 +407,7 @@ TypeUtils::ToResponse(const PCacheResponse& aIn)
|
|||
}
|
||||
|
||||
already_AddRefed<InternalRequest>
|
||||
TypeUtils::ToInternalRequest(const PCacheRequest& aIn)
|
||||
TypeUtils::ToInternalRequest(const CacheRequest& aIn)
|
||||
{
|
||||
nsRefPtr<InternalRequest> internalRequest = new InternalRequest();
|
||||
|
||||
|
@ -408,7 +424,7 @@ TypeUtils::ToInternalRequest(const PCacheRequest& aIn)
|
|||
internalRequest->SetCacheMode(aIn.requestCache());
|
||||
|
||||
nsRefPtr<InternalHeaders> internalHeaders =
|
||||
new InternalHeaders(aIn.headers(), aIn.headersGuard());
|
||||
ToInternalHeaders(aIn.headers(), aIn.headersGuard());
|
||||
ErrorResult result;
|
||||
internalRequest->Headers()->SetGuard(aIn.headersGuard(), result);
|
||||
MOZ_ASSERT(!result.Failed());
|
||||
|
@ -423,13 +439,30 @@ TypeUtils::ToInternalRequest(const PCacheRequest& aIn)
|
|||
}
|
||||
|
||||
already_AddRefed<Request>
|
||||
TypeUtils::ToRequest(const PCacheRequest& aIn)
|
||||
TypeUtils::ToRequest(const CacheRequest& aIn)
|
||||
{
|
||||
nsRefPtr<InternalRequest> internalRequest = ToInternalRequest(aIn);
|
||||
nsRefPtr<Request> request = new Request(GetGlobalObject(), internalRequest);
|
||||
return request.forget();
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<InternalHeaders>
|
||||
TypeUtils::ToInternalHeaders(const nsTArray<HeadersEntry>& aHeadersEntryList,
|
||||
HeadersGuardEnum aGuard)
|
||||
{
|
||||
nsTArray<InternalHeaders::Entry> entryList(aHeadersEntryList.Length());
|
||||
|
||||
for (uint32_t i = 0; i < aHeadersEntryList.Length(); ++i) {
|
||||
const HeadersEntry& headersEntry = aHeadersEntryList[i];
|
||||
entryList.AppendElement(InternalHeaders::Entry(headersEntry.name(),
|
||||
headersEntry.value()));
|
||||
}
|
||||
|
||||
nsRefPtr<InternalHeaders> ref = new InternalHeaders(Move(entryList), aGuard);
|
||||
return ref.forget();
|
||||
}
|
||||
|
||||
void
|
||||
TypeUtils::CheckAndSetBodyUsed(Request* aRequest, BodyAction aBodyAction,
|
||||
ErrorResult& aRv)
|
||||
|
@ -477,7 +510,7 @@ TypeUtils::ToInternalRequest(const nsAString& aIn, ErrorResult& aRv)
|
|||
|
||||
void
|
||||
TypeUtils::SerializeCacheStream(nsIInputStream* aStream,
|
||||
PCacheReadStreamOrVoid* aStreamOut,
|
||||
CacheReadStreamOrVoid* aStreamOut,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
*aStreamOut = void_t();
|
||||
|
@ -492,7 +525,7 @@ TypeUtils::SerializeCacheStream(nsIInputStream* aStream,
|
|||
return;
|
||||
}
|
||||
|
||||
PCacheReadStream readStream;
|
||||
CacheReadStream readStream;
|
||||
readStream.controlChild() = nullptr;
|
||||
readStream.controlParent() = nullptr;
|
||||
readStream.pushStreamChild() = nullptr;
|
||||
|
@ -516,7 +549,7 @@ TypeUtils::SerializeCacheStream(nsIInputStream* aStream,
|
|||
|
||||
void
|
||||
TypeUtils::SerializePushStream(nsIInputStream* aStream,
|
||||
PCacheReadStream& aReadStreamOut,
|
||||
CacheReadStream& aReadStreamOut,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsIAsyncInputStream> asyncStream = do_QueryInterface(aStream);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/InternalHeaders.h"
|
||||
#include "nsError.h"
|
||||
|
||||
class nsIGlobalObject;
|
||||
|
@ -29,11 +30,12 @@ class Response;
|
|||
namespace cache {
|
||||
|
||||
class CachePushStreamChild;
|
||||
class PCacheQueryParams;
|
||||
class PCacheReadStream;
|
||||
class PCacheReadStreamOrVoid;
|
||||
class PCacheRequest;
|
||||
class PCacheResponse;
|
||||
class CacheQueryParams;
|
||||
class CacheReadStream;
|
||||
class CacheReadStreamOrVoid;
|
||||
class CacheRequest;
|
||||
class CacheResponse;
|
||||
class HeadersEntry;
|
||||
|
||||
class TypeUtils
|
||||
{
|
||||
|
@ -77,28 +79,33 @@ public:
|
|||
ErrorResult& aRv);
|
||||
|
||||
void
|
||||
ToPCacheRequest(PCacheRequest& aOut, InternalRequest* aIn,
|
||||
BodyAction aBodyAction, ReferrerAction aReferrerAction,
|
||||
SchemeAction aSchemeAction, ErrorResult& aRv);
|
||||
ToCacheRequest(CacheRequest& aOut, InternalRequest* aIn,
|
||||
BodyAction aBodyAction, ReferrerAction aReferrerAction,
|
||||
SchemeAction aSchemeAction, ErrorResult& aRv);
|
||||
|
||||
void
|
||||
ToPCacheResponseWithoutBody(PCacheResponse& aOut, InternalResponse& aIn,
|
||||
ErrorResult& aRv);
|
||||
ToCacheResponseWithoutBody(CacheResponse& aOut, InternalResponse& aIn,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void
|
||||
ToPCacheResponse(PCacheResponse& aOut, Response& aIn, ErrorResult& aRv);
|
||||
ToCacheResponse(CacheResponse& aOut, Response& aIn, ErrorResult& aRv);
|
||||
|
||||
void
|
||||
ToPCacheQueryParams(PCacheQueryParams& aOut, const CacheQueryOptions& aIn);
|
||||
ToCacheQueryParams(CacheQueryParams& aOut, const CacheQueryOptions& aIn);
|
||||
|
||||
already_AddRefed<Response>
|
||||
ToResponse(const PCacheResponse& aIn);
|
||||
ToResponse(const CacheResponse& aIn);
|
||||
|
||||
already_AddRefed<InternalRequest>
|
||||
ToInternalRequest(const PCacheRequest& aIn);
|
||||
ToInternalRequest(const CacheRequest& aIn);
|
||||
|
||||
already_AddRefed<Request>
|
||||
ToRequest(const PCacheRequest& aIn);
|
||||
ToRequest(const CacheRequest& aIn);
|
||||
|
||||
// static methods
|
||||
static already_AddRefed<InternalHeaders>
|
||||
ToInternalHeaders(const nsTArray<HeadersEntry>& aHeadersEntryList,
|
||||
HeadersGuardEnum aGuard = HeadersGuardEnum::None);
|
||||
|
||||
private:
|
||||
void
|
||||
|
@ -109,11 +116,11 @@ private:
|
|||
ToInternalRequest(const nsAString& aIn, ErrorResult& aRv);
|
||||
|
||||
void
|
||||
SerializeCacheStream(nsIInputStream* aStream, PCacheReadStreamOrVoid* aStreamOut,
|
||||
SerializeCacheStream(nsIInputStream* aStream, CacheReadStreamOrVoid* aStreamOut,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void
|
||||
SerializePushStream(nsIInputStream* aStream, PCacheReadStream& aReadStreamOut,
|
||||
SerializePushStream(nsIInputStream* aStream, CacheReadStream& aReadStreamOut,
|
||||
ErrorResult& aRv);
|
||||
};
|
||||
|
||||
|
|
|
@ -22,9 +22,7 @@ enum Namespace
|
|||
CHROME_ONLY_NAMESPACE,
|
||||
NUMBER_OF_NAMESPACES
|
||||
};
|
||||
|
||||
typedef uintptr_t RequestId;
|
||||
static const RequestId INVALID_REQUEST_ID = 0;
|
||||
static const Namespace INVALID_NAMESPACE = NUMBER_OF_NAMESPACES;
|
||||
|
||||
typedef int64_t CacheId;
|
||||
static const CacheId INVALID_CACHE_ID = -1;
|
||||
|
|
|
@ -11,6 +11,8 @@ EXPORTS.mozilla.dom.cache += [
|
|||
'AutoUtils.h',
|
||||
'Cache.h',
|
||||
'CacheChild.h',
|
||||
'CacheOpChild.h',
|
||||
'CacheOpParent.h',
|
||||
'CacheParent.h',
|
||||
'CachePushStreamChild.h',
|
||||
'CachePushStreamParent.h',
|
||||
|
@ -35,7 +37,6 @@ EXPORTS.mozilla.dom.cache += [
|
|||
'SavedTypes.h',
|
||||
'StreamControl.h',
|
||||
'StreamList.h',
|
||||
'StreamUtils.h',
|
||||
'Types.h',
|
||||
'TypeUtils.h',
|
||||
]
|
||||
|
@ -46,6 +47,8 @@ UNIFIED_SOURCES += [
|
|||
'AutoUtils.cpp',
|
||||
'Cache.cpp',
|
||||
'CacheChild.cpp',
|
||||
'CacheOpChild.cpp',
|
||||
'CacheOpParent.cpp',
|
||||
'CacheParent.cpp',
|
||||
'CachePushStreamChild.cpp',
|
||||
'CachePushStreamParent.cpp',
|
||||
|
@ -68,17 +71,16 @@ UNIFIED_SOURCES += [
|
|||
'ReadStream.cpp',
|
||||
'StreamControl.cpp',
|
||||
'StreamList.cpp',
|
||||
'StreamUtils.cpp',
|
||||
'TypeUtils.cpp',
|
||||
]
|
||||
|
||||
IPDL_SOURCES += [
|
||||
'CacheInitData.ipdlh',
|
||||
'CacheTypes.ipdlh',
|
||||
'PCache.ipdl',
|
||||
'PCacheOp.ipdl',
|
||||
'PCachePushStream.ipdl',
|
||||
'PCacheStorage.ipdl',
|
||||
'PCacheStreamControl.ipdl',
|
||||
'PCacheTypes.ipdlh',
|
||||
]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
|
|
@ -558,7 +558,7 @@ public:
|
|||
}
|
||||
|
||||
void
|
||||
Run(DataStoreDB* aDb, RunStatus aStatus)
|
||||
Run(DataStoreDB* aDb, RunStatus aStatus) override
|
||||
{
|
||||
AssertIsInMainProcess();
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
@ -640,7 +640,7 @@ public:
|
|||
|
||||
// nsIDOMEventListener
|
||||
NS_IMETHOD
|
||||
HandleEvent(nsIDOMEvent* aEvent)
|
||||
HandleEvent(nsIDOMEvent* aEvent) override
|
||||
{
|
||||
AssertIsInMainProcess();
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
[DEFAULT]
|
||||
skip-if = e10s
|
||||
support-files =
|
||||
file_utf16_be_bom.css
|
||||
file_utf16_be_bom.js
|
||||
|
|
|
@ -1180,7 +1180,9 @@ CrossProcessSafeEvent(const WidgetEvent& aEvent)
|
|||
case NS_MOUSE_BUTTON_UP:
|
||||
case NS_MOUSE_MOVE:
|
||||
case NS_CONTEXTMENU:
|
||||
case NS_MOUSE_ENTER:
|
||||
case NS_MOUSE_EXIT:
|
||||
case NS_MOUSE_ENTER_SYNTH:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
@ -3787,20 +3789,27 @@ EventStateManager::DispatchMouseOrPointerEvent(WidgetMouseEvent* aMouseEvent,
|
|||
// the same object after event dispatch and handling, so refetch it.
|
||||
targetFrame = mPresContext->GetPrimaryFrameFor(aTargetContent);
|
||||
|
||||
// If we are leaving remote content, dispatch a mouse exit event to the
|
||||
// remote frame.
|
||||
if (aMessage == NS_MOUSE_EXIT_SYNTH && IsRemoteTarget(aTargetContent)) {
|
||||
// For remote content, send a normal widget mouse exit event.
|
||||
nsAutoPtr<WidgetMouseEvent> remoteEvent;
|
||||
CreateMouseOrPointerWidgetEvent(aMouseEvent, NS_MOUSE_EXIT,
|
||||
aRelatedContent, remoteEvent);
|
||||
// If we are entering/leaving remote content, dispatch a mouse enter/exit
|
||||
// event to the remote frame.
|
||||
if (IsRemoteTarget(aTargetContent)) {
|
||||
if (aMessage == NS_MOUSE_EXIT_SYNTH) {
|
||||
// For remote content, send a normal widget mouse exit event.
|
||||
nsAutoPtr<WidgetMouseEvent> remoteEvent;
|
||||
CreateMouseOrPointerWidgetEvent(aMouseEvent, NS_MOUSE_EXIT,
|
||||
aRelatedContent, remoteEvent);
|
||||
|
||||
// mCurrentTarget is set to the new target, so we must reset it to the
|
||||
// old target and then dispatch a cross-process event. (mCurrentTarget
|
||||
// will be set back below.) HandleCrossProcessEvent will query for the
|
||||
// proper target via GetEventTarget which will return mCurrentTarget.
|
||||
mCurrentTarget = targetFrame;
|
||||
HandleCrossProcessEvent(remoteEvent, &status);
|
||||
// mCurrentTarget is set to the new target, so we must reset it to the
|
||||
// old target and then dispatch a cross-process event. (mCurrentTarget
|
||||
// will be set back below.) HandleCrossProcessEvent will query for the
|
||||
// proper target via GetEventTarget which will return mCurrentTarget.
|
||||
mCurrentTarget = targetFrame;
|
||||
HandleCrossProcessEvent(remoteEvent, &status);
|
||||
} else if (aMessage == NS_MOUSE_ENTER_SYNTH) {
|
||||
nsAutoPtr<WidgetMouseEvent> remoteEvent;
|
||||
CreateMouseOrPointerWidgetEvent(aMouseEvent, NS_MOUSE_ENTER,
|
||||
aRelatedContent, remoteEvent);
|
||||
HandleCrossProcessEvent(remoteEvent, &status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче