# Network interception

> Register URL-based request callbacks, inspect parsed bodies, cancel requests, and handle Service Worker restarts and timeouts.

Source: https://console.getchrovia.com/en/docs/sdk-network-intercept

**Entitlement:** `networkIntercept`. **API:** `chrovia.network`. Use a Provision Service Worker; no EP section is needed for basic interception.

## Register a handler

Put registration at the top level of `background.js`, so it runs on every worker start:

```js
const network = globalThis.chrovia?.network;
if (network) {
  network.intercept({ urls: ['https://example.com/api/*'], timeout: 30 }, request => {
    return request.method === 'POST' ? { cancel: true } : {};
  });
}
```

Replace the URL with a test endpoint you control. Register before opening the page, or reload an already-open page before testing. An existing tab may not be covered until it is reloaded. This is not a guarantee to intercept all browser-internal or extension traffic.

## Options and return contract

| Item | Meaning |
| --- | --- |
| `urls` | String array of wildcard patterns matched against the full URL, including query string |
| `timeout` | Seconds; default 30 for missing/invalid/non-positive values; positive values clamped to 0.1–600 |
| Callback returns `{}` | Forward the original request unchanged |
| Callback returns `{cancel: true}` | Cancel the request |
| `stopIntercepting()` | Clear the interception session and release pending requests |

Patterns match the complete URL and are case-sensitive. `*` matches zero or more characters; `?` matches zero or one character. A backslash escapes the next character. This is not regex or Chrome extension match-pattern syntax.

To match a literal query separator, use `https://example.com/api\?mode=*` as the pattern value, written as `'https://example.com/api\\?mode=*'` in JavaScript or `"https://example.com/api\\?mode=*"` in JSON. The doubled backslash in source produces one backslash in the pattern. Use specific host/path patterns rather than `*` unless you intentionally need broad matching.

`intercept()` and `stopIntercepting()` return `undefined`. There is no registration readiness Promise: `await intercept(...)` cannot guarantee browser-side readiness. The callback itself may return a Promise. Thrown errors, rejected Promises and timeout continue the original request, so interception is not a fail-closed security barrier.

The callback can only allow or cancel the original request. Returned replacement headers, URLs, bodies, or synthetic responses are ignored. Use [DNR](https://console.getchrovia.com/en/docs/sdk-declarative-net-request) for supported static request rules, or [navigation redirect](https://console.getchrovia.com/en/docs/sdk-navigation-redirect) for main-frame routing.

## Request data

| Field | Type/meaning |
| --- | --- |
| `url`, `method`, `referrer` | Strings describing the request |
| `type` | Request destination, such as `document`, `iframe`, `image`, `script`, `style`, or `empty` for fetch/XHR; not DNR's `main_frame` / `sub_frame` names |
| `timestamp` | Unix milliseconds |
| `requestHeaders` | Array of `{name, value}` entries |
| `requestBody` | Optional parsed JSON value or form dictionary |
| `currentUsername` | Optional username captured from the frame's password-manager flow |

For `application/json`, the body is the parsed JSON value, not a raw string. For `application/x-www-form-urlencoded`, each field maps to an array of strings, preserving repeated fields. Only in-memory byte bodies up to 1 MiB are parsed. Empty, unsupported, file/stream, oversized, or invalid JSON bodies can omit `requestBody`. It is not a general upload capture API. Do not log credential bodies.

## Cancellation display

By default cancellation uses `ERR_ABORTED`, generally leaving navigation silently stopped. To request Chromium's blocked-by-client error behavior, configure:

```json
{
  "internal": {
    "network_intercept": {
      "cancel_as": "blocked_by_client"
    }
  }
}
```

Other values use the default. Merge and sign the [EP](https://console.getchrovia.com/en/docs/sdk-extended-preferences) as required, then restart. This affects the error code, not the callback's decision or timeout policy.

## Service Worker usage

Use one plugin for interception. A later `intercept()` call replaces the previous handler and rules for the browser instance.

Register at the script's top level, not only in `onInstalled`, and do not rely on global variables surviving worker restarts. Matching requests can wake the worker; the configured timeout still applies. Requests whose callback is interrupted by worker shutdown continue unchanged. Call `stopIntercepting()` to stop interception.

Verify GET versus POST behavior, worker sleep/wake, errors, and timeout on a disposable endpoint. A page opened before registration may need reloading even if the API object exists.
