/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* 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 "nsISupports.idl" #include "nsIContentPolicy.idl" interface nsICacheInfoChannel; interface nsIChannel; interface nsIConsoleReportCollector; interface nsIInputStream; interface nsIOutputStream; interface nsIURI; %{C++ #include "nsContentUtils.h" #include "nsIChannel.h" #include "nsIConsoleReportCollector.h" #include "nsILoadInfo.h" namespace mozilla { class TimeStamp; namespace dom { class ChannelInfo; } } %} native TimeStamp(mozilla::TimeStamp); [ptr] native ChannelInfo(mozilla::dom::ChannelInfo); /** * Interface allowing the nsIInterceptedChannel to callback when it is * done reading from the body stream. */ [scriptable, uuid(51039eb6-bea0-40c7-b523-ccab56cc4fde)] interface nsIInterceptedBodyCallback : nsISupports { void bodyComplete(in nsresult aRv); }; /** * Interface to allow implementors of nsINetworkInterceptController to control the behaviour * of intercepted channels without tying implementation details of the interception to * the actual channel. nsIInterceptedChannel is expected to be implemented by objects * which do not implement nsIChannel. */ [scriptable, uuid(f4b82975-6a86-4cc4-87fe-9a1fd430c86d)] interface nsIInterceptedChannel : nsISupports { /** * Instruct a channel that has been intercepted to continue with the original * network request. */ void resetInterception(); /** * Set the status and reason for the forthcoming synthesized response. * Multiple calls overwrite existing values. */ void synthesizeStatus(in uint16_t status, in ACString reason); /** * Attach a header name/value pair to the forthcoming synthesized response. * Overwrites any existing header value. */ void synthesizeHeader(in ACString name, in ACString value); /** * Instruct a channel that has been intercepted that a response is * starting to be synthesized. No further header modification is allowed * after this point. There are a few parameters: * - A body stream may be optionally passed. If nullptr, then an * empty body is assumed. * - A callback may be optionally passed. It will be invoked * when the body is complete. For a nullptr body this may be * synchronously on the current thread. Otherwise it will be invoked * asynchronously on the current thread. * - A cacheInfoChannel may be optionally passed. If the body stream is * from alternative data cache, this cacheInfoChannel provides needed * cache information. * - The caller may optionally pass a spec for a URL that this response * originates from; an empty string will cause the original * intercepted request's URL to be used instead. * - The responseRedirected flag is false will cause the channel do an * internal redirect when the original intercepted reauest's URL is * different from the response's URL. The flag is true will cause the * chaanel do a non-internal redirect when the URLs are different. */ void startSynthesizedResponse(in nsIInputStream body, in nsIInterceptedBodyCallback callback, in nsICacheInfoChannel channel, in ACString finalURLSpec, in bool responseRedirected); /** * Instruct a channel that has been intercepted that response synthesis * has completed and all outstanding resources can be closed. */ void finishSynthesizedResponse(); /** * Cancel the pending intercepted request. * @return NS_ERROR_FAILURE if the response has already been synthesized or * the original request has been instructed to continue. */ void cancelInterception(in nsresult status); /** * The underlying channel object that was intercepted. */ readonly attribute nsIChannel channel; /** * The URL of the underlying channel object, corrected for a potential * secure upgrade. */ readonly attribute nsIURI secureUpgradedChannelURI; /** * This method allows to override the channel info for the channel. */ [noscript] void setChannelInfo(in ChannelInfo channelInfo); /** * Get the internal load type from the underlying channel. */ [noscript] readonly attribute nsContentPolicyType internalContentPolicyType; [noscript] readonly attribute nsIConsoleReportCollector consoleReportCollector; /** * Save the timestamps of various service worker interception phases. */ [noscript] void SetLaunchServiceWorkerStart(in TimeStamp aTimeStamp); // A hack to get sw launch start time for telemetry. [noscript] void GetLaunchServiceWorkerStart(out TimeStamp aTimeStamp); [noscript] void SetLaunchServiceWorkerEnd(in TimeStamp aTimeStamp); // A hack to get sw launch end time for telemetry. [noscript] void GetLaunchServiceWorkerEnd(out TimeStamp aTimeStamp); [noscript] void SetDispatchFetchEventStart(in TimeStamp aTimeStamp); [noscript] void SetDispatchFetchEventEnd(in TimeStamp aTimeStamp); [noscript] void SetHandleFetchEventStart(in TimeStamp aTimeStamp); [noscript] void SetHandleFetchEventEnd(in TimeStamp aTimeStamp); // Depending on the outcome we measure the time difference between // |FinishResponseStart| and either |FinishSynthesizedResponseEnd| or // |ChannelResetEnd|. [noscript] void SetFinishResponseStart(in TimeStamp aTimeStamp); [noscript] void SetFinishSynthesizedResponseEnd(in TimeStamp aTimeStamp); [noscript] void SetChannelResetEnd(in TimeStamp aTimeStamp); [noscript] void SaveTimeStamps(); %{C++ already_AddRefed<nsIConsoleReportCollector> GetConsoleReportCollector() { nsCOMPtr<nsIConsoleReportCollector> reporter; GetConsoleReportCollector(getter_AddRefs(reporter)); return reporter.forget(); } void GetSubresourceTimeStampKey(nsIChannel* aChannel, nsACString& aKey) { if (!nsContentUtils::IsNonSubresourceRequest(aChannel)) { nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo(); switch(loadInfo->InternalContentPolicyType()) { case nsIContentPolicy::TYPE_SCRIPT: case nsIContentPolicy::TYPE_INTERNAL_SCRIPT: case nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD: case nsIContentPolicy::TYPE_INTERNAL_MODULE: case nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD: case nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS: { aKey = "subresource-script"_ns; break; } case nsIContentPolicy::TYPE_IMAGE: case nsIContentPolicy::TYPE_INTERNAL_IMAGE: case nsIContentPolicy::TYPE_INTERNAL_IMAGE_PRELOAD: case nsIContentPolicy::TYPE_INTERNAL_IMAGE_FAVICON: { aKey = "subresource-image"_ns; break; } case nsIContentPolicy::TYPE_STYLESHEET: case nsIContentPolicy::TYPE_INTERNAL_STYLESHEET: case nsIContentPolicy::TYPE_INTERNAL_STYLESHEET_PRELOAD: { aKey = "subresource-stylesheet"_ns; break; } default: { aKey = "subresource-other"_ns; break; } } } } %} /** * Allow the ServiceWorkerManager to set an RAII-style object on the * intercepted channel that should be released once the channel is * torn down. */ [noscript] void setReleaseHandle(in nsISupports aHandle); }; /** * Interface to allow consumers to attach themselves to a channel's * notification callbacks/loadgroup and determine if a given channel * request should be intercepted before any network request is initiated. */ [scriptable, uuid(70d2b4fe-a552-48cd-8d93-1d8437a56b53)] interface nsINetworkInterceptController : nsISupports { /** * Returns true if a channel should avoid initiating any network * requests until specifically instructed to do so. * * @param aURI The URI to be loaded. Note, this may differ from * the channel's current URL in some cases. * @param aChannel The channel that may be intercepted. It will * be in the state prior to calling OnStartRequest(). */ bool shouldPrepareForIntercept(in nsIURI aURI, in nsIChannel aChannel); /** * Notification when a given intercepted channel is prepared to accept a synthesized * response via the provided stream. * * @param aChannel the controlling interface for a channel that has been intercepted */ void channelIntercepted(in nsIInterceptedChannel aChannel); };