// Copyright 2017 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. module network.mojom; import "mojo/public/mojom/base/time.mojom"; import "url/mojom/url.mojom"; enum CookiePriority { LOW, MEDIUM, HIGH }; // See https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00 // and https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis for // information about same site cookie restrictions. enum CookieSameSite { NO_RESTRICTION, LAX_MODE, STRICT_MODE }; enum CookieSameSiteFilter { INCLUDE_STRICT_AND_LAX, INCLUDE_LAX, DO_NOT_INCLUDE }; // Keep defaults here in sync with net/cookies/cookie_options.cc. struct CookieOptions { bool exclude_httponly = true; CookieSameSiteFilter cookie_same_site_filter = DO_NOT_INCLUDE; bool update_access_time = true; // TODO(rdsmith): Remove this element from the mojo structure? It's only // used in the underlying net:: structure in CanonicalCookie::Create(). mojo_base.mojom.Time? server_time; }; // See net/cookies/canonical_cookie.{h,cc} for documentation. // Keep defaults here in sync with those files. struct CanonicalCookie { string name; string value; string domain; string path; mojo_base.mojom.Time? creation; mojo_base.mojom.Time? expiry; mojo_base.mojom.Time? last_access; bool secure = false; bool httponly = false; CookieSameSite site_restrictions = NO_RESTRICTION; CookiePriority priority = MEDIUM; }; // Keep values here in sync with net::CookieStore::ChangeCause. // (Not typemapped to avoid forcing clients to know about net::CookieStore.) enum CookieChangeCause { // The cookie was inserted. INSERTED, // The cookie was changed directly by a consumer's action. EXPLICIT, // The cookie was deleted, but no more details are known. UNKNOWN_DELETION, // The cookie was automatically removed due to an insert operation that // overwrote it. OVERWRITE, // The cookie was automatically removed as it expired. EXPIRED, // The cookie was automatically evicted during garbage collection. EVICTED, // The cookie was overwritten with an already-expired expiration date. EXPIRED_OVERWRITE }; // Session cookies are cookies that expire at the end of the browser session. // That is represented in canonical cookies by a null expiry time. enum CookieDeletionSessionControl { IGNORE_CONTROL, SESSION_COOKIES, PERSISTENT_COOKIES, }; // All existing filters are ANDed together. I.e. if there is a value for // created_after_time and there's a value for including_domains, only cookies // in including_domains that have been created after the specified date would be // deleted. A value for session_control of IGNORE_CONTROL is treated the same // as optional values not being present for the other filters. // If no filters are specified then all cookies will be deleted; this can be // thought of as there being a default "match everything" filter which is // ANDed in with all other filters. // // Note that whether a domain matches a cookie or not is somewhat nuanced. For // the purposes of this filter: // * The host/domain cookie distinction is ignored // * A cookies effective domain is considered to be the top level registry // (including private registries) for the domain stored in the cookie // + the next entry down. So the effective domain for x.y.google.com // would be google.com, and the effective domain for x.google.co.uk would // be google.co.uk. See the function // net::registry_controlled_domains::GetDomainAndRegistry for more // details. // * If a cookie does not have such a top level domain (e.g. IP address // or private hostname), the domain specified in the cookie (the IP // address or private hostname) is used. struct CookieDeletionFilter { // Delete cookies created after a date. mojo_base.mojom.Time? created_after_time; // Delete cookies created before a date. mojo_base.mojom.Time? created_before_time; // Delete cookies whose domains are not listed. array? excluding_domains; // Deletes cookies whose domains are listed. array? including_domains; // Delete cookies with a particular name. string? cookie_name; // Delete cookies from a particular host. string? host_name; // Delete cookies which match the given URL. // See https://tools.ietf.org/html/rfc6265, sections 5.1.{3,4} & 5.2.{5,6} // for matching rules. In general terms, secure cookies only match // https URLs, the domain must match (the cookie domain must be a suffix // of the URL domain), and the path must match (the cookie path must // be a prefix of the URL path). So // a cookie with {domain: ".sub.example.com", path: "/path", secure} // would be deleted if the URL passed was // "https://www.sub.example.com/path/path2" but not if it was // "http://www.example.com/x"--in fact, that cookie wouldn't be deleted // if any of the secure/domain/path attributes in the URL were changed. url.mojom.Url? url; // Delete session/persistent cookies. CookieDeletionSessionControl session_control = IGNORE_CONTROL; }; interface CookieChangeListener { // TODO(rdsmith): Should this be made a batch interface? OnCookieChange(CanonicalCookie cookie, CookieChangeCause cause); }; interface CookieManager { // TODO(rdsmith): Worthwhile specifying a sort order for the getters? // Get all the cookies known to the service. // Returned cookie list is sorted first by path length (longest first) // and second by creation time. // TODO(rdsmith): There are consumers that rely on this behavior, but // for this function it doesn't make a lot of sense not to also sort // on origin. Should the returned cookies also be sorted by origin? GetAllCookies() => (array cookies); // Get all cookies for the specified URL and cookie options. // Returned cookie list is sorted first by path length (longest first) // and second by creation time. GetCookieList(url.mojom.Url url, CookieOptions cookie_options) => (array cookies); // Set a cookie. |secure_source| indicates whether existing secure // cookies can be overwritten (secure cookies may be created from a // non-secure source). |modify_http_only| indicates whether http_only // cookies may be overwritten. SetCanonicalCookie( CanonicalCookie cookie, bool secure_source, bool modify_http_only) => (bool success); // Delete a set of cookies matching the passed filter. // To delete a single cookie, use SetCanonicalCookie with an expiry // time in the past. // Returns the number of cookies deleted. DeleteCookies(CookieDeletionFilter filter) => (uint32 num_deleted); // Subscribes the given listener to changes to a cookie. // // The subscription is canceled by closing the CookieChangeListener's pipe. // // Note that if the caller may be racing with other uses of the cookie store, // it should follow the subscription request with a probe of the relevant // information about the tracked cookie, to make sure that a change to the // cookie did not happen right before the listener was registered. // // TODO(rdsmith): Should this have a filter to register for a lot of // notifications at once? Maybe combine with the deletion filter? // TODO(rdsmith): Describe the performance implications of using this meethod. // The comments in CookieMonster::AddCallbackForCookie look pretty scary. AddCookieChangeListener( url.mojom.Url url, string name, CookieChangeListener listener); // Subscribes the given listener to changes to this CookieManager's cookies. // // The subscription is canceled by closing the CookieChangeListener's pipe. // // TODO(rdsmith): Should this have a filter to register for a lot of // notifications at once? Maybe combine with the deletion filter? AddGlobalChangeListener(CookieChangeListener notification_pointer); // Clone the interface for use somewhere else. After this call, // requests to the same implementation may be posted to the other side // of the pipe new_interface was configured on. CloneInterface(CookieManager& new_interface); // Flush the backing store (if any) to disk. FlushCookieStore() => (); };