Index: chrome/common/extensions/docs/server2/templates/private/webRequest_intro.html |
diff --git a/chrome/common/extensions/docs/server2/templates/private/webRequest_intro.html b/chrome/common/extensions/docs/server2/templates/private/webRequest_intro.html |
new file mode 100644 |
index 0000000000000000000000000000000000000000..477c6fb9a7b8cc9f21f7112197e0a86c78edf721 |
--- /dev/null |
+++ b/chrome/common/extensions/docs/server2/templates/private/webRequest_intro.html |
@@ -0,0 +1,276 @@ |
+<!-- BEGIN AUTHORED CONTENT --> |
+<p id="classSummary"> |
+Use the <code>chrome.webRequest</code> module to intercept, block, |
+or modify requests in-flight and to observe and analyze traffic. |
+</p> |
+<h2 id="manifest">Manifest</h2> |
+<p>You must declare the "webRequest" permission in the <a |
+ href="manifest.html">extension manifest</a> to use the web request |
+API, along with <a href="manifest.html#permissions">host permissions</a> |
+for any hosts whose network requests you want to access. If you want to |
+use the web request API in a blocking fashion, you need to request |
+the "webRequestBlocking" permission in addition. |
+For example:</p> |
+<pre>{ |
+ "name": "My extension", |
+ ... |
+ <b>"permissions": [ |
+ "webRequest", |
+ "*://*.google.com" |
+ ]</b>, |
+ ... |
+}</pre> |
+<p class="note"> |
+<b>Node:</b> If you request the "webRequestBlocking" permission, web requests |
+are delayed until the background page of your extension has been loaded. This |
+allows you to register event listeners before any web requests are processed. |
+In order to avoid deadlocks, you must not start synchronous XmlHttpRequests or |
+include scripts from the internet via <code><script src="..."></code> tags |
+in your background page. |
+</p> |
+<h2 id="life_cycle">Life cycle of requests</h2> |
+<p> |
+The web request API defines a set of events that follow the life cycle of a web |
+request. You can use these events to observe and analyze traffic. Certain |
+synchronous events will allow you to intercept, block, or modify a request. |
+</p> |
+<p> |
+The event life cycle for successful requests is illustrated here, followed by |
+event definitions:<br/> |
+<img src="/static/images/webrequestapi.png" |
+ width="385" height="503" |
+ alt="Life cycle of a web request from the perspective of the webrequest API" |
+ style="margin-left: auto; margin-right: auto; display: block"/> |
+</p> |
+<p> |
+<dl> |
+ <dt><code>onBeforeRequest</code> (optionally synchronous)</dt> |
+ <dd>Fires when a request is about to occur. This event is sent before any TCP |
+ connection is made and can be used to cancel or redirect requests.</dd> |
+ <dt><code>onBeforeSendHeaders</code> (optionally synchronous)</dt> |
+ <dd>Fires when a request is about to occur and the initial headers have been |
+ prepared. The event is intended to allow extensions to add, modify, and delete |
+ request headers <a href="#life_cycle_footnote">(*)</a>. The |
+ <code>onBeforeSendHeaders</code> event is passed to all subscribers, so |
+ different subscribers may attempt to modify the request; see the <a |
+ href="#implementation">Implementation details</a> section for how this is |
+ handled. This event can be used to cancel the request.</dd> |
+ <dt><code>onSendHeaders</code></dt> |
+ <dd>Fires after all extensions have had a chance to modify the request |
+ headers, and presents the final <a href="#life_cycle_footnote">(*)</a> |
+ version. The event is triggered before the headers are sent to the network. |
+ This event is informational and handled asynchronously. It does not allow |
+ modifying or cancelling the request.</dd> |
+ <dt><code>onHeadersReceived</code> (optionally synchronous)</dt> |
+ <dd>Fires each time that an HTTP(S) response header is received. Due |
+ to redirects and authentication requests this can happen multiple times per |
+ request. This event is intended to allow extensions to add, modify, and delete |
+ response headers, such as incoming Set-Cookie headers.</dd> |
+ <dt><code>onAuthRequired</code> (optionally synchronous)</dt> |
+ <dd>Fires when a request requires authentication of the user. This event can |
+ be handled synchronously to provide authentication credentials. Note that |
+ extensions may provide invalid credentials. Take care not to enter an infinite |
+ loop by repeatedly providing invalid credentials.</dd> |
+ <dt><code>onBeforeRedirect</code></dt> |
+ <dd>Fires when a redirect is about to be executed. A redirection can be |
+ triggered by an HTTP response code or by an extension. This event is |
+ informational and handled asynchronously. It does not allow you to modify or |
+ cancel the request. </dd> |
+ <dt><code>onResponseStarted</code></dt> |
+ <dd>Fires when the first byte of the response body is received. For HTTP |
+ requests, this means that the status line and response headers are |
+ available. This event is informational and handled asynchronously. It does not |
+ allow modifying or cancelling the request.</dd> |
+ <dt><code>onCompleted</code></dt> |
+ <dd>Fires when a request has been processed successfully.</dd> |
+ <dt><code>onErrorOccurred</code></dt> |
+ <dd>Fires when a request could not be processed successfully.</dd> |
+</dl> |
+The web request API guarantees that for each request either |
+<code>onCompleted</code> or <code>onErrorOccurred</code> is fired as the final |
+event with one exception: If a request is redirected to a <code>data://</code> |
+URL, <code>onBeforeRedirect</code> is the last reported event. |
+</p> |
+<p id="life_cycle_footnote">(*) Note that the web request API presents an |
+abstraction of the network stack to the extension. Internally, one URL request |
+can be split into several HTTP requests (for example to fetch individual byte |
+ranges from a large file) or can be handled by the network stack without |
+communicating with the network. For this reason, the API does not provide the |
+final HTTP headers that are sent to the network. For example, all headers that |
+are related to caching are invisible to the extension.</p> |
+<p>The following headers are currently <b>not provided</b> to the |
+<code>onBeforeSendHeaders</code> event. This list is not guaranteed to be |
+complete nor stable. |
+<ul> |
+ <li>Authorization</li> |
+ <li>Cache-Control</li> |
+ <li>Connection</li> |
+ <li>Content-Length</li> |
+ <li>Host</li> |
+ <li>If-Modified-Since</li> |
+ <li>If-None-Match</li> |
+ <li>If-Range</li> |
+ <li>Partial-Data</li> |
+ <li>Pragma</li> |
+ <li>Proxy-Authorization</li> |
+ <li>Proxy-Connection</li> |
+ <li>Transfer-Encoding</li> |
+</ul> |
+</p> |
+<p> |
+The webRequest API only exposes requests that the extension has |
+permission to see, given its |
+<a href="manifest.html#permissions">host permissions</a>. |
+Moreover, only the following schemes are accessible: |
+<code>http://</code>, |
+<code>https://</code>, |
+<code>ftp://</code>, |
+<code>file://</code>, or |
+<code>chrome-extension://</code>. |
+In addition, even certain requests with URLs using one of the above schemes |
+are hidden, e.g., |
+<code>chrome-extension://other_extension_id</code> where |
+<code>other_extension_id</code> is not the ID of the extension to handle |
+the request, |
+<code>https://www.google.com/chrome</code>, |
+and others (this list is not complete). |
+</p> |
+<h2 id="concepts">Concepts</h2> |
+<p>As the following sections explain, events in the web request API use request |
+IDs, and you can optionally specify filters and extra information when you |
+register event listeners.</p> |
+<h3 id="Request IDs">Request IDs</h3> |
+<p>Each request is identified by a request ID. This ID is unique within a |
+browser session and the context of an extension. It remains constant during the |
+the life cycle of a request and can be used to match events for the same |
+request. Note that several HTTP requests are mapped to one web request in case |
+of HTTP redirection or HTTP authentication.</p> |
+<h3 id="subscription">Registering event listeners</h3> |
+<p>To register an event listener for a web request, you use a variation on the |
+<a href="events.html">usual <code>addListener()</code> function</a>. |
+In addition to specifying a callback function, |
+you have to specify a filter argument and you may specify an optional extra info |
+argument.</p> |
+<p>The three arguments to the web request API's <code>addListener()</code> have |
+the following definitions:</p> |
+<pre> |
+var callback = function(details) {...}; |
+var filter = {...}; |
+var opt_extraInfoSpec = [...]; |
+</pre> |
+<p>Here's an example of listening for the <code>onBeforeRequest</code> |
+event:</p> |
+<pre> |
+chrome.webRequest.onBeforeRequest.addListener( |
+ callback, filter, opt_extraInfoSpec); |
+</pre> |
+<p>Each <code>addListener()</code> call takes a mandatory callback function as |
+the first parameter. This callback function is passed a dictionary containing |
+information about the current URL request. The information in this dictionary |
+depends on the specific event type as well as the content of |
+<code>opt_extraInfoSpec</code>.</p> |
+<p>If the optional <code>opt_extraInfoSpec</code> array contains the string |
+<code>'blocking'</code> (only allowed for specific events), the callback |
+function is handled synchronously. That means that the request is blocked until |
+the callback function returns. In this case, the callback can return a <a |
+ href="#type-webRequest.BlockingResponse">BlockingResponse</a> that determines the further |
+life cycle of the request. Depending on the context, this response allows |
+cancelling or redirecting a request (<code>onBeforeRequest</code>), cancelling a |
+request or modifying headers (<code>onBeforeSendHeaders</code>, |
+<code>onHeadersReceived</code>), or providing authentication credentials |
+(<code>onAuthRequired</code>).</p> |
+<p>The <a href="#type-webRequest.RequestFilter">RequestFilter</a> |
+<code>filter</code> allows limiting the requests for which events are |
+triggered in various dimensions: |
+<dl> |
+ <dt>URLs</dt> |
+ <dd><a href="match_patterns.html">URL patterns</a> such as |
+ <code>*://www.google.com/foo*bar</code>.</dd> |
+ <dt>Types</dt> |
+ <dd>Request types such as <code>main_frame</code> (a document that is loaded |
+ for a top-level frame), <code>sub_frame</code> (a document that is loaded for |
+ an embedded frame), and <code>image</code> (an image on a web site). |
+ See <a href="#type-webRequest.RequestFilter">RequestFilter</a>.</dd> |
+ <dt>Tab ID</dt> |
+ <dd>The identifier for one tab.</dd> |
+ <dt>Window ID</dt> |
+ <dd>The identifier for a window.</dd> |
+</p> |
+<p>Depending on the event type, you can specify strings in |
+<code>opt_extraInfoSpec</code> to ask for additional information about the |
+request. This is used to provide detailed information on request's data only |
+if explicitly requested.</p> |
+<h2 id="implementation">Implementation details</h2> |
+<p>Several implementation details can be important to understand when developing |
+an extension that uses the web request API:</p> |
+<h3>Conflict resolution</h3> |
+<p>In the current implementation of the web request API, a request is considered |
+as cancelled if at least one extension instructs to cancel the request. If |
+an extension cancels a request, all extensions are notified by an |
+<code>onErrorOccurred</code> event. Only one extension is allowed to redirect a |
+request or modify a header at a time. If more than one extension attempts to |
+modify the request, the most recently installed extension wins and all others |
+are ignored. An extension is not notified if its instruction to modify or |
+redirect has been ignored.</p> |
+<h3>Caching</h3> |
+<p> |
+Chrome employs two caches — an on-disk cache and a very fast in-memory |
+cache. The lifetime of an in-memory cache is attached to the lifetime of a |
+render process, which roughly corresponds to a tab. Requests that are answered |
+from the in-memory cache are invisible to the web request API. If a request |
+handler changes its behavior (for example, the behavior according to which |
+requests are blocked), a simple page refresh might not respect this changed |
+behavior. To make sure the behavior change goes through, call |
+<code>handlerBehaviorChanged()</code> to flush the in-memory cache. But don't do |
+it often; flushing the cache is a very expensive operation. You don't need to |
+call <code>handlerBehaviorChanged()</code> after registering or unregistering an |
+event listener.</p> |
+<h3>Timestamps</h3> |
+<p> |
+The <code>timestamp</code> property of web request events is only guaranteed to |
+be <i>internally</i> consistent. Comparing one event to another event will give |
+you the correct offset between them, but comparing them to the current time |
+inside the extension (via <code>(new Date()).getTime()</code>, for instance) |
+might give unexpected results. |
+</p> |
+<h2 id="examples">Examples</h2> |
+<p>The following example illustrates how to block all requests to |
+<code>www.evil.com</code>:</p> |
+<pre> |
+chrome.webRequest.onBeforeRequest.addListener( |
+ function(details) { |
+ return {cancel: details.url.indexOf("://www.evil.com/") != -1}; |
+ }, |
+ {urls: ["<all_urls>"]}, |
+ ["blocking"]); |
+</pre> |
+<p>As this function uses a blocking event handler, it requires the "webRequest" |
+as well as the "webRequestBlocking" permission in the manifest file.</p> |
+<p>The following example achieves the same goal in a more efficient way because |
+requests that are not targeted to <code>www.evil.com</code> do not need to be |
+passed to the extension:</p> |
+<pre> |
+chrome.webRequest.onBeforeRequest.addListener( |
+ function(details) { return {cancel: true}; }, |
+ {urls: ["*://www.evil.com/*"]}, |
+ ["blocking"]); |
+</pre> |
+<p>The following example illustrates how to delete the User-Agent header from |
+all requests:</p> |
+<pre> |
+chrome.webRequest.onBeforeSendHeaders.addListener( |
+ function(details) { |
+ for (var i = 0; i < details.requestHeaders.length; ++i) { |
+ if (details.requestHeaders[i].name === 'User-Agent') { |
+ details.requestHeaders.splice(i, 1); |
+ break; |
+ } |
+ } |
+ return {requestHeaders: details.requestHeaders}; |
+ }, |
+ {urls: ["<all_urls>"]}, |
+ ["blocking", "requestHeaders"]); |
+</pre> |
+<p> For more example code, see the <a href="samples.html#webrequest">web request |
+samples</a>.</p> |
+<!-- END AUTHORED CONTENT --> |