mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
84d1744c1c
Moves most of the cookie implementation to a new file, testing/marionette/cookies.js. The new Cookies class encapsulates all APIs for manipulating and querying cookies from content space. It communicates with chrome space, where the cookie manager lives, through a new SyncContentSender provided by testing/marionette/proxy.js. This new interface provides synchronous and transparent communication from content to chrome, not dissimilar from how the original listener proxy works. r=dburns
132 lines
3.6 KiB
JavaScript
132 lines
3.6 KiB
JavaScript
/* 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/. */
|
|
|
|
"use strict";
|
|
|
|
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
|
|
|
Cu.import("resource://gre/modules/Log.jsm");
|
|
Cu.import("chrome://marionette/content/error.js");
|
|
|
|
const logger = Log.repository.getLogger("Marionette");
|
|
|
|
this.EXPORTED_SYMBOLS = ["Cookies"];
|
|
|
|
const IPV4_PORT_EXPR = /:\d+$/;
|
|
|
|
/**
|
|
* Interface for manipulating cookies from content space.
|
|
*/
|
|
this.Cookies = class {
|
|
|
|
/**
|
|
* @param {function(): Document} documentFn
|
|
* Closure that returns the current content document.
|
|
* @param {Proxy(SyncChromeSender)} chromeProxy
|
|
* A synchronous proxy interface to chrome space.
|
|
*/
|
|
constructor(documentFn, chromeProxy) {
|
|
this.documentFn_ = documentFn;
|
|
this.chrome = chromeProxy;
|
|
}
|
|
|
|
get document() {
|
|
return this.documentFn_();
|
|
}
|
|
|
|
[Symbol.iterator]() {
|
|
let path = this.document.location.pathname || "/";
|
|
let cs = this.chrome.getVisibleCookies(path, this.document.location.hostname)[0];
|
|
return cs[Symbol.iterator]();
|
|
}
|
|
|
|
/**
|
|
* Add a new cookie to a content document.
|
|
*
|
|
* @param {string} name
|
|
* Cookie key.
|
|
* @param {string} value
|
|
* Cookie value.
|
|
* @param {Object.<string, ?>} opts
|
|
* An object with the optional fields {@code domain}, {@code path},
|
|
* {@code secure}, {@code httpOnly}, and {@code expiry}.
|
|
*
|
|
* @return {Object.<string, ?>}
|
|
* A serialisation of the cookie that was added.
|
|
*
|
|
* @throws UnableToSetCookieError
|
|
* If the document's content type isn't HTML, the current document's
|
|
* domain is a mismatch to the cookie's provided domain, or there
|
|
* otherwise was issues with the input data.
|
|
*/
|
|
add(name, value, opts={}) {
|
|
if (typeof this.document == "undefined" || !this.document.contentType.match(/html/i)) {
|
|
throw new UnableToSetCookieError(
|
|
"You may only set cookies on HTML documents: " + this.document.contentType);
|
|
}
|
|
|
|
if (!opts.expiry) {
|
|
// date twenty years into future, in seconds
|
|
let date = new Date();
|
|
let now = new Date(Date.now());
|
|
date.setYear(now.getFullYear() + 20);
|
|
opts.expiry = date.getTime() / 1000;
|
|
}
|
|
|
|
if (!opts.domain) {
|
|
opts.domain = this.document.location.host;
|
|
} else if (this.document.location.host.indexOf(opts.domain) < 0) {
|
|
throw new InvalidCookieDomainError(
|
|
"You may only set cookies for the current domain");
|
|
}
|
|
|
|
// remove port from domain, if present.
|
|
// unfortunately this catches IPv6 addresses by mistake
|
|
// TODO: Bug 814416
|
|
opts.domain = opts.domain.replace(IPV4_PORT_EXPR, "");
|
|
|
|
let cookie = {
|
|
domain: opts.domain,
|
|
path: opts.path,
|
|
name: name,
|
|
value: value,
|
|
secure: opts.secure,
|
|
httpOnly: opts.httpOnly,
|
|
session: false,
|
|
expiry: opts.expiry,
|
|
};
|
|
if (!this.chrome.addCookie(cookie)) {
|
|
throw new UnableToSetCookieError();
|
|
}
|
|
|
|
return cookie;
|
|
}
|
|
|
|
/**
|
|
* Delete cookie by reference or by name.
|
|
*
|
|
* @param {(string|Object.<string, ?>)} cookie
|
|
* Name of cookie or cookie object.
|
|
*
|
|
* @throws {UnknownError}
|
|
* If unable to delete the cookie.
|
|
*/
|
|
delete(cookie) {
|
|
let name;
|
|
if (cookie.hasOwnProperty("name")) {
|
|
name = cookie.name;
|
|
} else {
|
|
name = cookie;
|
|
}
|
|
|
|
for (let candidate of this) {
|
|
if (candidate.name == name) {
|
|
if (!this.chrome.deleteCookie(candidate)) {
|
|
throw new UnknownError("Unable to delete cookie by name: " + name);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|