docs: move protocol-ns to protocol.md (#23911)
* docs: move protocol-ns to protocol.md * chore: fix up tests and implement missing pieces required for tests Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com>
This commit is contained in:
Родитель
87cd20b9e9
Коммит
9ea42da40e
|
@ -1,309 +0,0 @@
|
|||
# protocol (NetworkService) (Draft)
|
||||
|
||||
This document describes the new protocol APIs based on the [NetworkService](https://www.chromium.org/servicification).
|
||||
|
||||
We don't currently have an estimate of when we will enable the `NetworkService` by
|
||||
default in Electron, but as Chromium is already removing non-`NetworkService`
|
||||
code, we will probably switch before Electron 10.
|
||||
|
||||
The content of this document should be moved to `protocol.md` after we have
|
||||
enabled the `NetworkService` by default in Electron.
|
||||
|
||||
> Register a custom protocol and intercept existing protocol requests.
|
||||
|
||||
Process: [Main](../glossary.md#main-process)
|
||||
|
||||
An example of implementing a protocol that has the same effect as the
|
||||
`file://` protocol:
|
||||
|
||||
```javascript
|
||||
const { app, protocol } = require('electron')
|
||||
const path = require('path')
|
||||
|
||||
app.whenReady().then(() => {
|
||||
protocol.registerFileProtocol('atom', (request, callback) => {
|
||||
const url = request.url.substr(7)
|
||||
callback({ path: path.normalize(`${__dirname}/${url}`) })
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
**Note:** All methods unless specified can only be used after the `ready` event
|
||||
of the `app` module gets emitted.
|
||||
|
||||
## Using `protocol` with a custom `partition` or `session`
|
||||
|
||||
A protocol is registered to a specific Electron [`session`](./session.md)
|
||||
object. If you don't specify a session, then your `protocol` will be applied to
|
||||
the default session that Electron uses. However, if you define a `partition` or
|
||||
`session` on your `browserWindow`'s `webPreferences`, then that window will use
|
||||
a different session and your custom protocol will not work if you just use
|
||||
`electron.protocol.XXX`.
|
||||
|
||||
To have your custom protocol work in combination with a custom session, you need
|
||||
to register it to that session explicitly.
|
||||
|
||||
```javascript
|
||||
const { session, app, protocol } = require('electron')
|
||||
const path = require('path')
|
||||
|
||||
app.whenReady().then(() => {
|
||||
const partition = 'persist:example'
|
||||
const ses = session.fromPartition(partition)
|
||||
|
||||
ses.protocol.registerFileProtocol('atom', (request, callback) => {
|
||||
const url = request.url.substr(7)
|
||||
callback({ path: path.normalize(`${__dirname}/${url}`) })
|
||||
})
|
||||
|
||||
mainWindow = new BrowserWindow({ webPreferences: { partition } })
|
||||
})
|
||||
```
|
||||
|
||||
## Methods
|
||||
|
||||
The `protocol` module has the following methods:
|
||||
|
||||
### `protocol.registerSchemesAsPrivileged(customSchemes)`
|
||||
|
||||
* `customSchemes` [CustomScheme[]](structures/custom-scheme.md)
|
||||
|
||||
**Note:** This method can only be used before the `ready` event of the `app`
|
||||
module gets emitted and can be called only once.
|
||||
|
||||
Registers the `scheme` as standard, secure, bypasses content security policy for
|
||||
resources, allows registering ServiceWorker and supports fetch API. Specify a
|
||||
privilege with the value of `true` to enable the capability.
|
||||
|
||||
An example of registering a privileged scheme, that bypasses Content Security
|
||||
Policy:
|
||||
|
||||
```javascript
|
||||
const { protocol } = require('electron')
|
||||
protocol.registerSchemesAsPrivileged([
|
||||
{ scheme: 'foo', privileges: { bypassCSP: true } }
|
||||
])
|
||||
```
|
||||
|
||||
A standard scheme adheres to what RFC 3986 calls [generic URI
|
||||
syntax](https://tools.ietf.org/html/rfc3986#section-3). For example `http` and
|
||||
`https` are standard schemes, while `file` is not.
|
||||
|
||||
Registering a scheme as standard allows relative and absolute resources to
|
||||
be resolved correctly when served. Otherwise the scheme will behave like the
|
||||
`file` protocol, but without the ability to resolve relative URLs.
|
||||
|
||||
For example when you load following page with custom protocol without
|
||||
registering it as standard scheme, the image will not be loaded because
|
||||
non-standard schemes can not recognize relative URLs:
|
||||
|
||||
```html
|
||||
<body>
|
||||
<img src='test.png'>
|
||||
</body>
|
||||
```
|
||||
|
||||
Registering a scheme as standard will allow access to files through the
|
||||
[FileSystem API][file-system-api]. Otherwise the renderer will throw a security
|
||||
error for the scheme.
|
||||
|
||||
By default web storage apis (localStorage, sessionStorage, webSQL, indexedDB,
|
||||
cookies) are disabled for non standard schemes. So in general if you want to
|
||||
register a custom protocol to replace the `http` protocol, you have to register
|
||||
it as a standard scheme.
|
||||
|
||||
### `protocol.registerFileProtocol(scheme, handler)`
|
||||
|
||||
* `scheme` String
|
||||
* `handler` Function
|
||||
* `request` ProtocolRequest
|
||||
* `callback` Function
|
||||
* `response` (String | [ProtocolResponse](structures/protocol-response.md))
|
||||
|
||||
Registers a protocol of `scheme` that will send a file as the response. The
|
||||
`handler` will be called with `request` and `callback` where `request` is
|
||||
an incoming request for the `scheme`.
|
||||
|
||||
To handle the `request`, the `callback` should be called with either the file's
|
||||
path or an object that has a `path` property, e.g. `callback(filePath)` or
|
||||
`callback({ path: filePath })`. The `filePath` must be an absolute path.
|
||||
|
||||
By default the `scheme` is treated like `http:`, which is parsed differently
|
||||
from protocols that follow the "generic URI syntax" like `file:`.
|
||||
|
||||
### `protocol.registerBufferProtocol(scheme, handler)`
|
||||
|
||||
* `scheme` String
|
||||
* `handler` Function
|
||||
* `request` ProtocolRequest
|
||||
* `callback` Function
|
||||
* `response` (Buffer | [ProtocolResponse](structures/protocol-response.md))
|
||||
|
||||
Registers a protocol of `scheme` that will send a `Buffer` as a response.
|
||||
|
||||
The usage is the same with `registerFileProtocol`, except that the `callback`
|
||||
should be called with either a `Buffer` object or an object that has the `data`
|
||||
property.
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
protocol.registerBufferProtocol('atom', (request, callback) => {
|
||||
callback({ mimeType: 'text/html', data: Buffer.from('<h5>Response</h5>') })
|
||||
})
|
||||
```
|
||||
|
||||
### `protocol.registerStringProtocol(scheme, handler)`
|
||||
|
||||
* `scheme` String
|
||||
* `handler` Function
|
||||
* `request` ProtocolRequest
|
||||
* `callback` Function
|
||||
* `response` (String | [ProtocolResponse](structures/protocol-response.md))
|
||||
|
||||
Registers a protocol of `scheme` that will send a `String` as a response.
|
||||
|
||||
The usage is the same with `registerFileProtocol`, except that the `callback`
|
||||
should be called with either a `String` or an object that has the `data`
|
||||
property.
|
||||
|
||||
### `protocol.registerHttpProtocol(scheme, handler)`
|
||||
|
||||
* `scheme` String
|
||||
* `handler` Function
|
||||
* `request` ProtocolRequest
|
||||
* `callback` Function
|
||||
* `response` ProtocolResponse
|
||||
|
||||
Registers a protocol of `scheme` that will send an HTTP request as a response.
|
||||
|
||||
The usage is the same with `registerFileProtocol`, except that the `callback`
|
||||
should be called with an object that has the `url` property.
|
||||
|
||||
### `protocol.registerStreamProtocol(scheme, handler)`
|
||||
|
||||
* `scheme` String
|
||||
* `handler` Function
|
||||
* `request` ProtocolRequest
|
||||
* `callback` Function
|
||||
* `response` (ReadableStream | [ProtocolResponse](structures/protocol-response.md))
|
||||
|
||||
Registers a protocol of `scheme` that will send a stream as a response.
|
||||
|
||||
The usage is the same with `registerFileProtocol`, except that the
|
||||
`callback` should be called with either a [`ReadableStream`](https://nodejs.org/api/stream.html#stream_class_stream_readable) object or an object that
|
||||
has the `data` property.
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
const { protocol } = require('electron')
|
||||
const { PassThrough } = require('stream')
|
||||
|
||||
function createStream (text) {
|
||||
const rv = new PassThrough() // PassThrough is also a Readable stream
|
||||
rv.push(text)
|
||||
rv.push(null)
|
||||
return rv
|
||||
}
|
||||
|
||||
protocol.registerStreamProtocol('atom', (request, callback) => {
|
||||
callback({
|
||||
statusCode: 200,
|
||||
headers: {
|
||||
'content-type': 'text/html'
|
||||
},
|
||||
data: createStream('<h5>Response</h5>')
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
It is possible to pass any object that implements the readable stream API (emits
|
||||
`data`/`end`/`error` events). For example, here's how a file could be returned:
|
||||
|
||||
```javascript
|
||||
protocol.registerStreamProtocol('atom', (request, callback) => {
|
||||
callback(fs.createReadStream('index.html'))
|
||||
})
|
||||
```
|
||||
|
||||
### `protocol.unregisterProtocol(scheme)`
|
||||
|
||||
* `scheme` String
|
||||
|
||||
Unregisters the custom protocol of `scheme`.
|
||||
|
||||
### `protocol.isProtocolRegistered(scheme)`
|
||||
|
||||
* `scheme` String
|
||||
|
||||
Returns `Boolean` - Whether `scheme` is already registered.
|
||||
|
||||
### `protocol.interceptFileProtocol(scheme, handler)`
|
||||
|
||||
* `scheme` String
|
||||
* `handler` Function
|
||||
* `request` ProtocolRequest
|
||||
* `callback` Function
|
||||
* `response` (String | [ProtocolResponse](structures/protocol-response.md))
|
||||
|
||||
Intercepts `scheme` protocol and uses `handler` as the protocol's new handler
|
||||
which sends a file as a response.
|
||||
|
||||
### `protocol.interceptStringProtocol(scheme, handler)`
|
||||
|
||||
* `scheme` String
|
||||
* `handler` Function
|
||||
* `request` ProtocolRequest
|
||||
* `callback` Function
|
||||
* `response` (String | [ProtocolResponse](structures/protocol-response.md))
|
||||
|
||||
Intercepts `scheme` protocol and uses `handler` as the protocol's new handler
|
||||
which sends a `String` as a response.
|
||||
|
||||
### `protocol.interceptBufferProtocol(scheme, handler)`
|
||||
|
||||
* `scheme` String
|
||||
* `handler` Function
|
||||
* `request` ProtocolRequest
|
||||
* `callback` Function
|
||||
* `response` (Buffer | [ProtocolResponse](structures/protocol-response.md))
|
||||
|
||||
Intercepts `scheme` protocol and uses `handler` as the protocol's new handler
|
||||
which sends a `Buffer` as a response.
|
||||
|
||||
### `protocol.interceptHttpProtocol(scheme, handler)`
|
||||
|
||||
* `scheme` String
|
||||
* `handler` Function
|
||||
* `request` ProtocolRequest
|
||||
* `callback` Function
|
||||
* `response` ProtocolResponse
|
||||
|
||||
Intercepts `scheme` protocol and uses `handler` as the protocol's new handler
|
||||
which sends a new HTTP request as a response.
|
||||
|
||||
### `protocol.interceptStreamProtocol(scheme, handler)`
|
||||
|
||||
* `scheme` String
|
||||
* `handler` Function
|
||||
* `request` ProtocolRequest
|
||||
* `callback` Function
|
||||
* `response` (ReadableStream | [ProtocolResponse](structures/protocol-response.md))
|
||||
|
||||
Same as `protocol.registerStreamProtocol`, except that it replaces an existing
|
||||
protocol handler.
|
||||
|
||||
### `protocol.uninterceptProtocol(scheme)`
|
||||
|
||||
* `scheme` String
|
||||
|
||||
Remove the interceptor installed for `scheme` and restore its original handler.
|
||||
|
||||
### `protocol.isProtocolIntercepted(scheme)`
|
||||
|
||||
* `scheme` String
|
||||
|
||||
Returns `Boolean` - Whether `scheme` is already intercepted.
|
||||
|
||||
[file-system-api]: https://developer.mozilla.org/en-US/docs/Web/API/LocalFileSystem
|
|
@ -15,8 +15,6 @@ app.whenReady().then(() => {
|
|||
protocol.registerFileProtocol('atom', (request, callback) => {
|
||||
const url = request.url.substr(7)
|
||||
callback({ path: path.normalize(`${__dirname}/${url}`) })
|
||||
}, (error) => {
|
||||
if (error) console.error('Failed to register protocol')
|
||||
})
|
||||
})
|
||||
```
|
||||
|
@ -26,9 +24,15 @@ of the `app` module gets emitted.
|
|||
|
||||
## Using `protocol` with a custom `partition` or `session`
|
||||
|
||||
A protocol is registered to a specific Electron [`session`](./session.md) object. If you don't specify a session, then your `protocol` will be applied to the default session that Electron uses. However, if you define a `partition` or `session` on your `browserWindow`'s `webPreferences`, then that window will use a different session and your custom protocol will not work if you just use `electron.protocol.XXX`.
|
||||
A protocol is registered to a specific Electron [`session`](./session.md)
|
||||
object. If you don't specify a session, then your `protocol` will be applied to
|
||||
the default session that Electron uses. However, if you define a `partition` or
|
||||
`session` on your `browserWindow`'s `webPreferences`, then that window will use
|
||||
a different session and your custom protocol will not work if you just use
|
||||
`electron.protocol.XXX`.
|
||||
|
||||
To have your custom protocol work in combination with a custom session, you need to register it to that session explicitly.
|
||||
To have your custom protocol work in combination with a custom session, you need
|
||||
to register it to that session explicitly.
|
||||
|
||||
```javascript
|
||||
const { session, app, protocol } = require('electron')
|
||||
|
@ -41,17 +45,9 @@ app.whenReady().then(() => {
|
|||
ses.protocol.registerFileProtocol('atom', (request, callback) => {
|
||||
const url = request.url.substr(7)
|
||||
callback({ path: path.normalize(`${__dirname}/${url}`) })
|
||||
}, (error) => {
|
||||
if (error) console.error('Failed to register protocol')
|
||||
})
|
||||
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
partition: partition
|
||||
}
|
||||
})
|
||||
mainWindow = new BrowserWindow({ webPreferences: { partition } })
|
||||
})
|
||||
```
|
||||
|
||||
|
@ -63,15 +59,15 @@ The `protocol` module has the following methods:
|
|||
|
||||
* `customSchemes` [CustomScheme[]](structures/custom-scheme.md)
|
||||
|
||||
|
||||
**Note:** This method can only be used before the `ready` event of the `app`
|
||||
module gets emitted and can be called only once.
|
||||
|
||||
Registers the `scheme` as standard, secure, bypasses content security policy for resources,
|
||||
allows registering ServiceWorker and supports fetch API.
|
||||
Registers the `scheme` as standard, secure, bypasses content security policy for
|
||||
resources, allows registering ServiceWorker and supports fetch API. Specify a
|
||||
privilege with the value of `true` to enable the capability.
|
||||
|
||||
Specify a privilege with the value of `true` to enable the capability.
|
||||
An example of registering a privileged scheme, with bypassing Content Security Policy:
|
||||
An example of registering a privileged scheme, that bypasses Content Security
|
||||
Policy:
|
||||
|
||||
```javascript
|
||||
const { protocol } = require('electron')
|
||||
|
@ -84,7 +80,7 @@ A standard scheme adheres to what RFC 3986 calls [generic URI
|
|||
syntax](https://tools.ietf.org/html/rfc3986#section-3). For example `http` and
|
||||
`https` are standard schemes, while `file` is not.
|
||||
|
||||
Registering a scheme as standard, will allow relative and absolute resources to
|
||||
Registering a scheme as standard allows relative and absolute resources to
|
||||
be resolved correctly when served. Otherwise the scheme will behave like the
|
||||
`file` protocol, but without the ability to resolve relative URLs.
|
||||
|
||||
|
@ -102,168 +98,102 @@ Registering a scheme as standard will allow access to files through the
|
|||
[FileSystem API][file-system-api]. Otherwise the renderer will throw a security
|
||||
error for the scheme.
|
||||
|
||||
By default web storage apis (localStorage, sessionStorage, webSQL, indexedDB, cookies)
|
||||
are disabled for non standard schemes. So in general if you want to register a
|
||||
custom protocol to replace the `http` protocol, you have to register it as a standard scheme.
|
||||
By default web storage apis (localStorage, sessionStorage, webSQL, indexedDB,
|
||||
cookies) are disabled for non standard schemes. So in general if you want to
|
||||
register a custom protocol to replace the `http` protocol, you have to register
|
||||
it as a standard scheme.
|
||||
|
||||
`protocol.registerSchemesAsPrivileged` can be used to replicate the functionality of the previous `protocol.registerStandardSchemes`, `webFrame.registerURLSchemeAs*` and `protocol.registerServiceWorkerSchemes` functions that existed prior to Electron 5.0.0, for example:
|
||||
|
||||
**before (<= v4.x)**
|
||||
```javascript
|
||||
// Main
|
||||
protocol.registerStandardSchemes(['scheme1', 'scheme2'], { secure: true })
|
||||
// Renderer
|
||||
webFrame.registerURLSchemeAsPrivileged('scheme1', { secure: true })
|
||||
webFrame.registerURLSchemeAsPrivileged('scheme2', { secure: true })
|
||||
```
|
||||
|
||||
**after (>= v5.x)**
|
||||
```javascript
|
||||
protocol.registerSchemesAsPrivileged([
|
||||
{ scheme: 'scheme1', privileges: { standard: true, secure: true } },
|
||||
{ scheme: 'scheme2', privileges: { standard: true, secure: true } }
|
||||
])
|
||||
```
|
||||
|
||||
### `protocol.registerFileProtocol(scheme, handler[, completion])`
|
||||
### `protocol.registerFileProtocol(scheme, handler)`
|
||||
|
||||
* `scheme` String
|
||||
* `handler` Function
|
||||
* `request` Object
|
||||
* `url` String
|
||||
* `headers` Record<String, String>
|
||||
* `referrer` String
|
||||
* `method` String
|
||||
* `uploadData` [UploadData[]](structures/upload-data.md)
|
||||
* `request` ProtocolRequest
|
||||
* `callback` Function
|
||||
* `filePath` String | [FilePathWithHeaders](structures/file-path-with-headers.md) (optional)
|
||||
* `completion` Function (optional)
|
||||
* `error` Error
|
||||
* `response` (String | [ProtocolResponse](structures/protocol-response.md))
|
||||
|
||||
Registers a protocol of `scheme` that will send the file as a response. The
|
||||
`handler` will be called with `handler(request, callback)` when a `request` is
|
||||
going to be created with `scheme`. `completion` will be called with
|
||||
`completion(null)` when `scheme` is successfully registered or
|
||||
`completion(error)` when failed.
|
||||
Returns `Boolean` - Whether the protocol was successfully registered
|
||||
|
||||
Registers a protocol of `scheme` that will send a file as the response. The
|
||||
`handler` will be called with `request` and `callback` where `request` is
|
||||
an incoming request for the `scheme`.
|
||||
|
||||
To handle the `request`, the `callback` should be called with either the file's
|
||||
path or an object that has a `path` property, e.g. `callback(filePath)` or
|
||||
`callback({ path: filePath })`. The object may also have a `headers` property
|
||||
which gives a map of headers to values for the response headers, e.g.
|
||||
`callback({ path: filePath, headers: {"Content-Security-Policy": "default-src 'none'"]})`.
|
||||
|
||||
When `callback` is called with nothing, a number, or an object that has an
|
||||
`error` property, the `request` will fail with the `error` number you
|
||||
specified. For the available error numbers you can use, please see the
|
||||
[net error list][net-error].
|
||||
`callback({ path: filePath })`. The `filePath` must be an absolute path.
|
||||
|
||||
By default the `scheme` is treated like `http:`, which is parsed differently
|
||||
than protocols that follow the "generic URI syntax" like `file:`.
|
||||
from protocols that follow the "generic URI syntax" like `file:`.
|
||||
|
||||
### `protocol.registerBufferProtocol(scheme, handler[, completion])`
|
||||
### `protocol.registerBufferProtocol(scheme, handler)`
|
||||
|
||||
* `scheme` String
|
||||
* `handler` Function
|
||||
* `request` Object
|
||||
* `url` String
|
||||
* `headers` Record<String, String>
|
||||
* `referrer` String
|
||||
* `method` String
|
||||
* `uploadData` [UploadData[]](structures/upload-data.md)
|
||||
* `request` ProtocolRequest
|
||||
* `callback` Function
|
||||
* `buffer` (Buffer | [MimeTypedBuffer](structures/mime-typed-buffer.md)) (optional)
|
||||
* `completion` Function (optional)
|
||||
* `error` Error
|
||||
* `response` (Buffer | [ProtocolResponse](structures/protocol-response.md))
|
||||
|
||||
Returns `Boolean` - Whether the protocol was successfully registered
|
||||
|
||||
Registers a protocol of `scheme` that will send a `Buffer` as a response.
|
||||
|
||||
The usage is the same with `registerFileProtocol`, except that the `callback`
|
||||
should be called with either a `Buffer` object or an object that has the `data`,
|
||||
`mimeType`, and `charset` properties.
|
||||
should be called with either a `Buffer` object or an object that has the `data`
|
||||
property.
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
const { protocol } = require('electron')
|
||||
|
||||
protocol.registerBufferProtocol('atom', (request, callback) => {
|
||||
callback({ mimeType: 'text/html', data: Buffer.from('<h5>Response</h5>') })
|
||||
}, (error) => {
|
||||
if (error) console.error('Failed to register protocol')
|
||||
})
|
||||
```
|
||||
|
||||
### `protocol.registerStringProtocol(scheme, handler[, completion])`
|
||||
### `protocol.registerStringProtocol(scheme, handler)`
|
||||
|
||||
* `scheme` String
|
||||
* `handler` Function
|
||||
* `request` Object
|
||||
* `url` String
|
||||
* `headers` Record<String, String>
|
||||
* `referrer` String
|
||||
* `method` String
|
||||
* `uploadData` [UploadData[]](structures/upload-data.md)
|
||||
* `request` ProtocolRequest
|
||||
* `callback` Function
|
||||
* `data` (String | [StringProtocolResponse](structures/string-protocol-response.md)) (optional)
|
||||
* `completion` Function (optional)
|
||||
* `error` Error
|
||||
* `response` (String | [ProtocolResponse](structures/protocol-response.md))
|
||||
|
||||
Returns `Boolean` - Whether the protocol was successfully registered
|
||||
|
||||
Registers a protocol of `scheme` that will send a `String` as a response.
|
||||
|
||||
The usage is the same with `registerFileProtocol`, except that the `callback`
|
||||
should be called with either a `String` or an object that has the `data`,
|
||||
`mimeType`, and `charset` properties.
|
||||
should be called with either a `String` or an object that has the `data`
|
||||
property.
|
||||
|
||||
### `protocol.registerHttpProtocol(scheme, handler[, completion])`
|
||||
### `protocol.registerHttpProtocol(scheme, handler)`
|
||||
|
||||
* `scheme` String
|
||||
* `handler` Function
|
||||
* `request` Object
|
||||
* `url` String
|
||||
* `headers` Record<String, String>
|
||||
* `referrer` String
|
||||
* `method` String
|
||||
* `uploadData` [UploadData[]](structures/upload-data.md)
|
||||
* `request` ProtocolRequest
|
||||
* `callback` Function
|
||||
* `redirectRequest` Object
|
||||
* `url` String
|
||||
* `method` String (optional)
|
||||
* `session` Session | null (optional)
|
||||
* `uploadData` [ProtocolResponseUploadData](structures/protocol-response-upload-data.md) (optional)
|
||||
* `completion` Function (optional)
|
||||
* `error` Error
|
||||
* `response` ProtocolResponse
|
||||
|
||||
Returns `Boolean` - Whether the protocol was successfully registered
|
||||
|
||||
Registers a protocol of `scheme` that will send an HTTP request as a response.
|
||||
|
||||
The usage is the same with `registerFileProtocol`, except that the `callback`
|
||||
should be called with a `redirectRequest` object that has the `url`, `method`,
|
||||
`referrer`, `uploadData` and `session` properties.
|
||||
should be called with an object that has the `url` property.
|
||||
|
||||
By default the HTTP request will reuse the current session. If you want the
|
||||
request to have a different session you should set `session` to `null`.
|
||||
|
||||
For POST requests the `uploadData` object must be provided.
|
||||
|
||||
### `protocol.registerStreamProtocol(scheme, handler[, completion])`
|
||||
### `protocol.registerStreamProtocol(scheme, handler)`
|
||||
|
||||
* `scheme` String
|
||||
* `handler` Function
|
||||
* `request` Object
|
||||
* `url` String
|
||||
* `headers` Record<String, String>
|
||||
* `referrer` String
|
||||
* `method` String
|
||||
* `uploadData` [UploadData[]](structures/upload-data.md)
|
||||
* `request` ProtocolRequest
|
||||
* `callback` Function
|
||||
* `stream` (ReadableStream | [StreamProtocolResponse](structures/stream-protocol-response.md)) (optional)
|
||||
* `completion` Function (optional)
|
||||
* `error` Error
|
||||
* `response` (ReadableStream | [ProtocolResponse](structures/protocol-response.md))
|
||||
|
||||
Registers a protocol of `scheme` that will send a `Readable` as a response.
|
||||
Returns `Boolean` - Whether the protocol was successfully registered
|
||||
|
||||
The usage is similar to the other `register{Any}Protocol`, except that the
|
||||
`callback` should be called with either a `Readable` object or an object that
|
||||
has the `data`, `statusCode`, and `headers` properties.
|
||||
Registers a protocol of `scheme` that will send a stream as a response.
|
||||
|
||||
The usage is the same with `registerFileProtocol`, except that the
|
||||
`callback` should be called with either a [`ReadableStream`](https://nodejs.org/api/stream.html#stream_class_stream_readable) object or an object that
|
||||
has the `data` property.
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -286,8 +216,6 @@ protocol.registerStreamProtocol('atom', (request, callback) => {
|
|||
},
|
||||
data: createStream('<h5>Response</h5>')
|
||||
})
|
||||
}, (error) => {
|
||||
if (error) console.error('Failed to register protocol')
|
||||
})
|
||||
```
|
||||
|
||||
|
@ -295,132 +223,102 @@ It is possible to pass any object that implements the readable stream API (emits
|
|||
`data`/`end`/`error` events). For example, here's how a file could be returned:
|
||||
|
||||
```javascript
|
||||
const { protocol } = require('electron')
|
||||
const fs = require('fs')
|
||||
|
||||
protocol.registerStreamProtocol('atom', (request, callback) => {
|
||||
callback(fs.createReadStream('index.html'))
|
||||
}, (error) => {
|
||||
if (error) console.error('Failed to register protocol')
|
||||
})
|
||||
```
|
||||
|
||||
### `protocol.unregisterProtocol(scheme[, completion])`
|
||||
### `protocol.unregisterProtocol(scheme)`
|
||||
|
||||
* `scheme` String
|
||||
* `completion` Function (optional)
|
||||
* `error` Error
|
||||
|
||||
Returns `Boolean` - Whether the protocol was successfully unregistered
|
||||
|
||||
Unregisters the custom protocol of `scheme`.
|
||||
|
||||
### `protocol.isProtocolHandled(scheme)`
|
||||
### `protocol.isProtocolRegistered(scheme)`
|
||||
|
||||
* `scheme` String
|
||||
|
||||
Returns `Promise<Boolean>` - fulfilled with a boolean that indicates whether there is
|
||||
already a handler for `scheme`.
|
||||
Returns `Boolean` - Whether `scheme` is already registered.
|
||||
|
||||
### `protocol.interceptFileProtocol(scheme, handler[, completion])`
|
||||
### `protocol.interceptFileProtocol(scheme, handler)`
|
||||
|
||||
* `scheme` String
|
||||
* `handler` Function
|
||||
* `request` Object
|
||||
* `url` String
|
||||
* `headers` Record<String, String>
|
||||
* `referrer` String
|
||||
* `method` String
|
||||
* `uploadData` [UploadData[]](structures/upload-data.md)
|
||||
* `request` ProtocolRequest
|
||||
* `callback` Function
|
||||
* `filePath` String
|
||||
* `completion` Function (optional)
|
||||
* `error` Error
|
||||
* `response` (String | [ProtocolResponse](structures/protocol-response.md))
|
||||
|
||||
Returns `Boolean` - Whether the protocol was successfully intercepted
|
||||
|
||||
Intercepts `scheme` protocol and uses `handler` as the protocol's new handler
|
||||
which sends a file as a response.
|
||||
|
||||
### `protocol.interceptStringProtocol(scheme, handler[, completion])`
|
||||
### `protocol.interceptStringProtocol(scheme, handler)`
|
||||
|
||||
* `scheme` String
|
||||
* `handler` Function
|
||||
* `request` Object
|
||||
* `url` String
|
||||
* `headers` Record<String, String>
|
||||
* `referrer` String
|
||||
* `method` String
|
||||
* `uploadData` [UploadData[]](structures/upload-data.md)
|
||||
* `request` ProtocolRequest
|
||||
* `callback` Function
|
||||
* `data` (String | [StringProtocolResponse](structures/string-protocol-response.md)) (optional)
|
||||
* `completion` Function (optional)
|
||||
* `error` Error
|
||||
* `response` (String | [ProtocolResponse](structures/protocol-response.md))
|
||||
|
||||
Returns `Boolean` - Whether the protocol was successfully intercepted
|
||||
|
||||
Intercepts `scheme` protocol and uses `handler` as the protocol's new handler
|
||||
which sends a `String` as a response.
|
||||
|
||||
### `protocol.interceptBufferProtocol(scheme, handler[, completion])`
|
||||
### `protocol.interceptBufferProtocol(scheme, handler)`
|
||||
|
||||
* `scheme` String
|
||||
* `handler` Function
|
||||
* `request` Object
|
||||
* `url` String
|
||||
* `headers` Record<String, String>
|
||||
* `referrer` String
|
||||
* `method` String
|
||||
* `uploadData` [UploadData[]](structures/upload-data.md)
|
||||
* `request` ProtocolRequest
|
||||
* `callback` Function
|
||||
* `buffer` Buffer (optional)
|
||||
* `completion` Function (optional)
|
||||
* `error` Error
|
||||
* `response` (Buffer | [ProtocolResponse](structures/protocol-response.md))
|
||||
|
||||
Returns `Boolean` - Whether the protocol was successfully intercepted
|
||||
|
||||
Intercepts `scheme` protocol and uses `handler` as the protocol's new handler
|
||||
which sends a `Buffer` as a response.
|
||||
|
||||
### `protocol.interceptHttpProtocol(scheme, handler[, completion])`
|
||||
### `protocol.interceptHttpProtocol(scheme, handler)`
|
||||
|
||||
* `scheme` String
|
||||
* `handler` Function
|
||||
* `request` Object
|
||||
* `url` String
|
||||
* `headers` Record<String, String>
|
||||
* `referrer` String
|
||||
* `method` String
|
||||
* `uploadData` [UploadData[]](structures/upload-data.md)
|
||||
* `request` ProtocolRequest
|
||||
* `callback` Function
|
||||
* `redirectRequest` Object
|
||||
* `url` String
|
||||
* `method` String (optional)
|
||||
* `session` Session | null (optional)
|
||||
* `uploadData` [ProtocolResponseUploadData](structures/protocol-response-upload-data.md) (optional)
|
||||
* `completion` Function (optional)
|
||||
* `error` Error
|
||||
* `response` [ProtocolResponse](structures/protocol-response.md)
|
||||
|
||||
Returns `Boolean` - Whether the protocol was successfully intercepted
|
||||
|
||||
Intercepts `scheme` protocol and uses `handler` as the protocol's new handler
|
||||
which sends a new HTTP request as a response.
|
||||
|
||||
### `protocol.interceptStreamProtocol(scheme, handler[, completion])`
|
||||
### `protocol.interceptStreamProtocol(scheme, handler)`
|
||||
|
||||
* `scheme` String
|
||||
* `handler` Function
|
||||
* `request` Object
|
||||
* `url` String
|
||||
* `headers` Record<String, String>
|
||||
* `referrer` String
|
||||
* `method` String
|
||||
* `uploadData` [UploadData[]](structures/upload-data.md)
|
||||
* `request` ProtocolRequest
|
||||
* `callback` Function
|
||||
* `stream` (ReadableStream | [StreamProtocolResponse](structures/stream-protocol-response.md)) (optional)
|
||||
* `completion` Function (optional)
|
||||
* `error` Error
|
||||
* `response` (ReadableStream | [ProtocolResponse](structures/protocol-response.md))
|
||||
|
||||
Returns `Boolean` - Whether the protocol was successfully intercepted
|
||||
|
||||
Same as `protocol.registerStreamProtocol`, except that it replaces an existing
|
||||
protocol handler.
|
||||
|
||||
### `protocol.uninterceptProtocol(scheme[, completion])`
|
||||
### `protocol.uninterceptProtocol(scheme)`
|
||||
|
||||
* `scheme` String
|
||||
* `completion` Function (optional)
|
||||
* `error` Error
|
||||
|
||||
Returns `Boolean` - Whether the protocol was successfully unintercepted
|
||||
|
||||
Remove the interceptor installed for `scheme` and restore its original handler.
|
||||
|
||||
[net-error]: https://code.google.com/p/chromium/codesearch#chromium/src/net/base/net_error_list.h
|
||||
### `protocol.isProtocolIntercepted(scheme)`
|
||||
|
||||
* `scheme` String
|
||||
|
||||
Returns `Boolean` - Whether `scheme` is already intercepted.
|
||||
|
||||
[file-system-api]: https://developer.mozilla.org/en-US/docs/Web/API/LocalFileSystem
|
||||
|
|
|
@ -4,3 +4,4 @@
|
|||
* `referrer` String
|
||||
* `method` String
|
||||
* `uploadData` [UploadData[]](upload-data.md) (optional)
|
||||
* `headers` Record<String, String>
|
||||
|
|
|
@ -43,7 +43,6 @@ auto_filenames = {
|
|||
"docs/api/power-monitor.md",
|
||||
"docs/api/power-save-blocker.md",
|
||||
"docs/api/process.md",
|
||||
"docs/api/protocol-ns.md",
|
||||
"docs/api/protocol.md",
|
||||
"docs/api/remote.md",
|
||||
"docs/api/sandbox-option.md",
|
||||
|
|
|
@ -176,11 +176,12 @@ ProtocolError Protocol::RegisterProtocol(ProtocolType type,
|
|||
return added ? ProtocolError::OK : ProtocolError::REGISTERED;
|
||||
}
|
||||
|
||||
void Protocol::UnregisterProtocol(const std::string& scheme,
|
||||
bool Protocol::UnregisterProtocol(const std::string& scheme,
|
||||
gin::Arguments* args) {
|
||||
bool removed = protocol_registry_->UnregisterProtocol(scheme);
|
||||
HandleOptionalCallback(
|
||||
args, removed ? ProtocolError::OK : ProtocolError::NOT_REGISTERED);
|
||||
return removed;
|
||||
}
|
||||
|
||||
bool Protocol::IsProtocolRegistered(const std::string& scheme) {
|
||||
|
@ -194,11 +195,12 @@ ProtocolError Protocol::InterceptProtocol(ProtocolType type,
|
|||
return added ? ProtocolError::OK : ProtocolError::INTERCEPTED;
|
||||
}
|
||||
|
||||
void Protocol::UninterceptProtocol(const std::string& scheme,
|
||||
bool Protocol::UninterceptProtocol(const std::string& scheme,
|
||||
gin::Arguments* args) {
|
||||
bool removed = protocol_registry_->UninterceptProtocol(scheme);
|
||||
HandleOptionalCallback(
|
||||
args, removed ? ProtocolError::OK : ProtocolError::NOT_INTERCEPTED);
|
||||
return removed;
|
||||
}
|
||||
|
||||
bool Protocol::IsProtocolIntercepted(const std::string& scheme) {
|
||||
|
|
|
@ -58,13 +58,13 @@ class Protocol : public gin::Wrappable<Protocol> {
|
|||
ProtocolError RegisterProtocol(ProtocolType type,
|
||||
const std::string& scheme,
|
||||
const ProtocolHandler& handler);
|
||||
void UnregisterProtocol(const std::string& scheme, gin::Arguments* args);
|
||||
bool UnregisterProtocol(const std::string& scheme, gin::Arguments* args);
|
||||
bool IsProtocolRegistered(const std::string& scheme);
|
||||
|
||||
ProtocolError InterceptProtocol(ProtocolType type,
|
||||
const std::string& scheme,
|
||||
const ProtocolHandler& handler);
|
||||
void UninterceptProtocol(const std::string& scheme, gin::Arguments* args);
|
||||
bool UninterceptProtocol(const std::string& scheme, gin::Arguments* args);
|
||||
bool IsProtocolIntercepted(const std::string& scheme);
|
||||
|
||||
// Old async version of IsProtocolRegistered.
|
||||
|
@ -73,16 +73,20 @@ class Protocol : public gin::Wrappable<Protocol> {
|
|||
|
||||
// Helper for converting old registration APIs to new RegisterProtocol API.
|
||||
template <ProtocolType type>
|
||||
void RegisterProtocolFor(const std::string& scheme,
|
||||
bool RegisterProtocolFor(const std::string& scheme,
|
||||
const ProtocolHandler& handler,
|
||||
gin::Arguments* args) {
|
||||
HandleOptionalCallback(args, RegisterProtocol(type, scheme, handler));
|
||||
auto result = RegisterProtocol(type, scheme, handler);
|
||||
HandleOptionalCallback(args, result);
|
||||
return result == ProtocolError::OK;
|
||||
}
|
||||
template <ProtocolType type>
|
||||
void InterceptProtocolFor(const std::string& scheme,
|
||||
bool InterceptProtocolFor(const std::string& scheme,
|
||||
const ProtocolHandler& handler,
|
||||
gin::Arguments* args) {
|
||||
HandleOptionalCallback(args, InterceptProtocol(type, scheme, handler));
|
||||
auto result = InterceptProtocol(type, scheme, handler);
|
||||
HandleOptionalCallback(args, result);
|
||||
return result == ProtocolError::OK;
|
||||
}
|
||||
|
||||
// Be compatible with old interface, which accepts optional callback.
|
||||
|
|
|
@ -234,10 +234,10 @@ describe('BrowserWindow module', () => {
|
|||
let w = null as unknown as BrowserWindow;
|
||||
const scheme = 'other';
|
||||
const srcPath = path.join(fixtures, 'api', 'loaded-from-dataurl.js');
|
||||
before((done) => {
|
||||
before(() => {
|
||||
protocol.registerFileProtocol(scheme, (request, callback) => {
|
||||
callback(srcPath);
|
||||
}, (error) => done(error));
|
||||
});
|
||||
});
|
||||
|
||||
after(() => {
|
||||
|
@ -2525,26 +2525,20 @@ describe('BrowserWindow module', () => {
|
|||
['foo', path.join(fixtures, 'api', 'window-open-location-change.html')],
|
||||
['bar', path.join(fixtures, 'api', 'window-open-location-final.html')]
|
||||
];
|
||||
beforeEach(async () => {
|
||||
await Promise.all(protocols.map(([scheme, path]) => new Promise((resolve, reject) => {
|
||||
beforeEach(() => {
|
||||
for (const [scheme, path] of protocols) {
|
||||
protocol.registerBufferProtocol(scheme, (request, callback) => {
|
||||
callback({
|
||||
mimeType: 'text/html',
|
||||
data: fs.readFileSync(path)
|
||||
});
|
||||
}, (error) => {
|
||||
if (error != null) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
})));
|
||||
}
|
||||
});
|
||||
afterEach(async () => {
|
||||
await Promise.all(protocols.map(([scheme]) => {
|
||||
return new Promise(resolve => protocol.unregisterProtocol(scheme, () => resolve()));
|
||||
}));
|
||||
afterEach(() => {
|
||||
for (const [scheme] of protocols) {
|
||||
protocol.unregisterProtocol(scheme);
|
||||
}
|
||||
});
|
||||
it('retains the original web preferences when window.location is changed to a new origin', async () => {
|
||||
const w = new BrowserWindow({
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { expect } from 'chai';
|
||||
import { protocol, webContents, WebContents, session, BrowserWindow, ipcMain } from 'electron/main';
|
||||
import { promisify } from 'util';
|
||||
import { AddressInfo } from 'net';
|
||||
import * as ChildProcess from 'child_process';
|
||||
import * as path from 'path';
|
||||
|
@ -13,17 +12,17 @@ import { emittedOnce } from './events-helpers';
|
|||
|
||||
const fixturesPath = path.resolve(__dirname, '..', 'spec', 'fixtures');
|
||||
|
||||
const registerStringProtocol = promisify(protocol.registerStringProtocol);
|
||||
const registerBufferProtocol = promisify(protocol.registerBufferProtocol);
|
||||
const registerFileProtocol = promisify(protocol.registerFileProtocol);
|
||||
const registerHttpProtocol = promisify(protocol.registerHttpProtocol);
|
||||
const registerStreamProtocol = promisify(protocol.registerStreamProtocol);
|
||||
const interceptStringProtocol = promisify(protocol.interceptStringProtocol);
|
||||
const interceptBufferProtocol = promisify(protocol.interceptBufferProtocol);
|
||||
const interceptHttpProtocol = promisify(protocol.interceptHttpProtocol);
|
||||
const interceptStreamProtocol = promisify(protocol.interceptStreamProtocol);
|
||||
const unregisterProtocol = promisify(protocol.unregisterProtocol);
|
||||
const uninterceptProtocol = promisify(protocol.uninterceptProtocol);
|
||||
const registerStringProtocol = protocol.registerStringProtocol;
|
||||
const registerBufferProtocol = protocol.registerBufferProtocol;
|
||||
const registerFileProtocol = protocol.registerFileProtocol;
|
||||
const registerHttpProtocol = protocol.registerHttpProtocol;
|
||||
const registerStreamProtocol = protocol.registerStreamProtocol;
|
||||
const interceptStringProtocol = protocol.interceptStringProtocol;
|
||||
const interceptBufferProtocol = protocol.interceptBufferProtocol;
|
||||
const interceptHttpProtocol = protocol.interceptHttpProtocol;
|
||||
const interceptStreamProtocol = protocol.interceptStreamProtocol;
|
||||
const unregisterProtocol = protocol.unregisterProtocol;
|
||||
const uninterceptProtocol = protocol.uninterceptProtocol;
|
||||
|
||||
const text = 'valar morghulis';
|
||||
const protocolName = 'sp';
|
||||
|
@ -87,22 +86,22 @@ describe('protocol module', () => {
|
|||
return contents.executeJavaScript(`ajax("${url}", ${JSON.stringify(options)})`);
|
||||
}
|
||||
|
||||
afterEach(async () => {
|
||||
await new Promise(resolve => protocol.unregisterProtocol(protocolName, (/* ignore error */) => resolve()));
|
||||
await new Promise(resolve => protocol.uninterceptProtocol('http', () => resolve()));
|
||||
afterEach(() => {
|
||||
protocol.unregisterProtocol(protocolName);
|
||||
protocol.uninterceptProtocol('http');
|
||||
});
|
||||
|
||||
describe('protocol.register(Any)Protocol', () => {
|
||||
it('throws error when scheme is already registered', async () => {
|
||||
await registerStringProtocol(protocolName, (req, cb) => cb());
|
||||
await expect(registerBufferProtocol(protocolName, (req, cb) => cb())).to.be.eventually.rejectedWith(Error);
|
||||
it('fails when scheme is already registered', () => {
|
||||
expect(registerStringProtocol(protocolName, (req, cb) => cb(''))).to.equal(true);
|
||||
expect(registerBufferProtocol(protocolName, (req, cb) => cb(Buffer.from('')))).to.equal(false);
|
||||
});
|
||||
|
||||
it('does not crash when handler is called twice', async () => {
|
||||
await registerStringProtocol(protocolName, (request, callback) => {
|
||||
registerStringProtocol(protocolName, (request, callback) => {
|
||||
try {
|
||||
callback(text);
|
||||
callback();
|
||||
callback('');
|
||||
} catch (error) {
|
||||
// Ignore error
|
||||
}
|
||||
|
@ -112,12 +111,12 @@ describe('protocol module', () => {
|
|||
});
|
||||
|
||||
it('sends error when callback is called with nothing', async () => {
|
||||
await registerBufferProtocol(protocolName, (req, cb) => cb());
|
||||
await expect(ajax(protocolName + '://fake-host')).to.be.eventually.rejectedWith(Error, '404');
|
||||
registerBufferProtocol(protocolName, (req, cb: any) => cb());
|
||||
await expect(ajax(protocolName + '://fake-host')).to.eventually.be.rejectedWith(Error, '404');
|
||||
});
|
||||
|
||||
it('does not crash when callback is called in next tick', async () => {
|
||||
await registerStringProtocol(protocolName, (request, callback) => {
|
||||
registerStringProtocol(protocolName, (request, callback) => {
|
||||
setImmediate(() => callback(text));
|
||||
});
|
||||
const r = await ajax(protocolName + '://fake-host');
|
||||
|
@ -126,27 +125,27 @@ describe('protocol module', () => {
|
|||
});
|
||||
|
||||
describe('protocol.unregisterProtocol', () => {
|
||||
it('returns error when scheme does not exist', async () => {
|
||||
await expect(unregisterProtocol('not-exist')).to.be.eventually.rejectedWith(Error);
|
||||
it('returns false when scheme does not exist', () => {
|
||||
expect(unregisterProtocol('not-exist')).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('protocol.registerStringProtocol', () => {
|
||||
it('sends string as response', async () => {
|
||||
await registerStringProtocol(protocolName, (request, callback) => callback(text));
|
||||
registerStringProtocol(protocolName, (request, callback) => callback(text));
|
||||
const r = await ajax(protocolName + '://fake-host');
|
||||
expect(r.data).to.equal(text);
|
||||
});
|
||||
|
||||
it('sets Access-Control-Allow-Origin', async () => {
|
||||
await registerStringProtocol(protocolName, (request, callback) => callback(text));
|
||||
registerStringProtocol(protocolName, (request, callback) => callback(text));
|
||||
const r = await ajax(protocolName + '://fake-host');
|
||||
expect(r.data).to.equal(text);
|
||||
expect(r.headers).to.include('access-control-allow-origin: *');
|
||||
});
|
||||
|
||||
it('sends object as response', async () => {
|
||||
await registerStringProtocol(protocolName, (request, callback) => {
|
||||
registerStringProtocol(protocolName, (request, callback) => {
|
||||
callback({
|
||||
data: text,
|
||||
mimeType: 'text/html'
|
||||
|
@ -158,7 +157,7 @@ describe('protocol module', () => {
|
|||
|
||||
it('fails when sending object other than string', async () => {
|
||||
const notAString = () => {};
|
||||
await registerStringProtocol(protocolName, (request, callback) => callback(notAString as any));
|
||||
registerStringProtocol(protocolName, (request, callback) => callback(notAString as any));
|
||||
await expect(ajax(protocolName + '://fake-host')).to.be.eventually.rejectedWith(Error, '404');
|
||||
});
|
||||
});
|
||||
|
@ -166,20 +165,20 @@ describe('protocol module', () => {
|
|||
describe('protocol.registerBufferProtocol', () => {
|
||||
const buffer = Buffer.from(text);
|
||||
it('sends Buffer as response', async () => {
|
||||
await registerBufferProtocol(protocolName, (request, callback) => callback(buffer));
|
||||
registerBufferProtocol(protocolName, (request, callback) => callback(buffer));
|
||||
const r = await ajax(protocolName + '://fake-host');
|
||||
expect(r.data).to.equal(text);
|
||||
});
|
||||
|
||||
it('sets Access-Control-Allow-Origin', async () => {
|
||||
await registerBufferProtocol(protocolName, (request, callback) => callback(buffer));
|
||||
registerBufferProtocol(protocolName, (request, callback) => callback(buffer));
|
||||
const r = await ajax(protocolName + '://fake-host');
|
||||
expect(r.data).to.equal(text);
|
||||
expect(r.headers).to.include('access-control-allow-origin: *');
|
||||
});
|
||||
|
||||
it('sends object as response', async () => {
|
||||
await registerBufferProtocol(protocolName, (request, callback) => {
|
||||
registerBufferProtocol(protocolName, (request, callback) => {
|
||||
callback({
|
||||
data: buffer,
|
||||
mimeType: 'text/html'
|
||||
|
@ -190,7 +189,7 @@ describe('protocol module', () => {
|
|||
});
|
||||
|
||||
it('fails when sending string', async () => {
|
||||
await registerBufferProtocol(protocolName, (request, callback) => callback(text as any));
|
||||
registerBufferProtocol(protocolName, (request, callback) => callback(text as any));
|
||||
await expect(ajax(protocolName + '://fake-host')).to.be.eventually.rejectedWith(Error, '404');
|
||||
});
|
||||
});
|
||||
|
@ -202,20 +201,20 @@ describe('protocol module', () => {
|
|||
const normalContent = fs.readFileSync(normalPath);
|
||||
|
||||
it('sends file path as response', async () => {
|
||||
await registerFileProtocol(protocolName, (request, callback) => callback(filePath));
|
||||
registerFileProtocol(protocolName, (request, callback) => callback(filePath));
|
||||
const r = await ajax(protocolName + '://fake-host');
|
||||
expect(r.data).to.equal(String(fileContent));
|
||||
});
|
||||
|
||||
it('sets Access-Control-Allow-Origin', async () => {
|
||||
await registerFileProtocol(protocolName, (request, callback) => callback(filePath));
|
||||
registerFileProtocol(protocolName, (request, callback) => callback(filePath));
|
||||
const r = await ajax(protocolName + '://fake-host');
|
||||
expect(r.data).to.equal(String(fileContent));
|
||||
expect(r.headers).to.include('access-control-allow-origin: *');
|
||||
});
|
||||
|
||||
it('sets custom headers', async () => {
|
||||
await registerFileProtocol(protocolName, (request, callback) => callback({
|
||||
registerFileProtocol(protocolName, (request, callback) => callback({
|
||||
path: filePath,
|
||||
headers: { 'X-Great-Header': 'sogreat' }
|
||||
}));
|
||||
|
@ -231,31 +230,30 @@ describe('protocol module', () => {
|
|||
headers: { 'X-Great-Header': (42 as any) }
|
||||
})).to.throw(Error, 'Value of \'X-Great-Header\' header has to be a string');
|
||||
done();
|
||||
}).then(() => {
|
||||
ajax(protocolName + '://fake-host');
|
||||
});
|
||||
ajax(protocolName + '://fake-host');
|
||||
});
|
||||
|
||||
it('sends object as response', async () => {
|
||||
await registerFileProtocol(protocolName, (request, callback) => callback({ path: filePath }));
|
||||
registerFileProtocol(protocolName, (request, callback) => callback({ path: filePath }));
|
||||
const r = await ajax(protocolName + '://fake-host');
|
||||
expect(r.data).to.equal(String(fileContent));
|
||||
});
|
||||
|
||||
it('can send normal file', async () => {
|
||||
await registerFileProtocol(protocolName, (request, callback) => callback(normalPath));
|
||||
registerFileProtocol(protocolName, (request, callback) => callback(normalPath));
|
||||
const r = await ajax(protocolName + '://fake-host');
|
||||
expect(r.data).to.equal(String(normalContent));
|
||||
});
|
||||
|
||||
it('fails when sending unexist-file', async () => {
|
||||
const fakeFilePath = path.join(fixturesPath, 'test.asar', 'a.asar', 'not-exist');
|
||||
await registerFileProtocol(protocolName, (request, callback) => callback(fakeFilePath));
|
||||
registerFileProtocol(protocolName, (request, callback) => callback(fakeFilePath));
|
||||
await expect(ajax(protocolName + '://fake-host')).to.be.eventually.rejectedWith(Error, '404');
|
||||
});
|
||||
|
||||
it('fails when sending unsupported content', async () => {
|
||||
await registerFileProtocol(protocolName, (request, callback) => callback(new Date() as any));
|
||||
registerFileProtocol(protocolName, (request, callback) => callback(new Date() as any));
|
||||
await expect(ajax(protocolName + '://fake-host')).to.be.eventually.rejectedWith(Error, '404');
|
||||
});
|
||||
});
|
||||
|
@ -267,22 +265,22 @@ describe('protocol module', () => {
|
|||
res.end(text);
|
||||
server.close();
|
||||
});
|
||||
await server.listen(0, '127.0.0.1');
|
||||
await new Promise(resolve => server.listen(0, '127.0.0.1', resolve));
|
||||
|
||||
const port = (server.address() as AddressInfo).port;
|
||||
const url = 'http://127.0.0.1:' + port;
|
||||
await registerHttpProtocol(protocolName, (request, callback) => callback({ url }));
|
||||
registerHttpProtocol(protocolName, (request, callback) => callback({ url }));
|
||||
const r = await ajax(protocolName + '://fake-host');
|
||||
expect(r.data).to.equal(text);
|
||||
});
|
||||
|
||||
it('fails when sending invalid url', async () => {
|
||||
await registerHttpProtocol(protocolName, (request, callback) => callback({ url: 'url' }));
|
||||
registerHttpProtocol(protocolName, (request, callback) => callback({ url: 'url' }));
|
||||
await expect(ajax(protocolName + '://fake-host')).to.be.eventually.rejectedWith(Error, '404');
|
||||
});
|
||||
|
||||
it('fails when sending unsupported content', async () => {
|
||||
await registerHttpProtocol(protocolName, (request, callback) => callback(new Date() as any));
|
||||
registerHttpProtocol(protocolName, (request, callback) => callback(new Date() as any));
|
||||
await expect(ajax(protocolName + '://fake-host')).to.be.eventually.rejectedWith(Error, '404');
|
||||
});
|
||||
|
||||
|
@ -297,12 +295,12 @@ describe('protocol module', () => {
|
|||
}
|
||||
});
|
||||
after(() => server.close());
|
||||
await server.listen(0, '127.0.0.1');
|
||||
await new Promise(resolve => server.listen(0, '127.0.0.1', resolve));
|
||||
|
||||
const port = (server.address() as AddressInfo).port;
|
||||
const url = `${protocolName}://fake-host`;
|
||||
const redirectURL = `http://127.0.0.1:${port}/serverRedirect`;
|
||||
await registerHttpProtocol(protocolName, (request, callback) => callback({ url: redirectURL }));
|
||||
registerHttpProtocol(protocolName, (request, callback) => callback({ url: redirectURL }));
|
||||
|
||||
const r = await ajax(url);
|
||||
expect(r.data).to.equal(text);
|
||||
|
@ -312,28 +310,27 @@ describe('protocol module', () => {
|
|||
protocol.registerHttpProtocol(protocolName, (request) => {
|
||||
expect(request).to.have.property('headers');
|
||||
done();
|
||||
}, () => {
|
||||
ajax(protocolName + '://fake-host');
|
||||
});
|
||||
ajax(protocolName + '://fake-host');
|
||||
});
|
||||
});
|
||||
|
||||
describe('protocol.registerStreamProtocol', () => {
|
||||
it('sends Stream as response', async () => {
|
||||
await registerStreamProtocol(protocolName, (request, callback) => callback(getStream()));
|
||||
registerStreamProtocol(protocolName, (request, callback) => callback(getStream()));
|
||||
const r = await ajax(protocolName + '://fake-host');
|
||||
expect(r.data).to.equal(text);
|
||||
});
|
||||
|
||||
it('sends object as response', async () => {
|
||||
await registerStreamProtocol(protocolName, (request, callback) => callback({ data: getStream() }));
|
||||
registerStreamProtocol(protocolName, (request, callback) => callback({ data: getStream() }));
|
||||
const r = await ajax(protocolName + '://fake-host');
|
||||
expect(r.data).to.equal(text);
|
||||
expect(r.status).to.equal(200);
|
||||
});
|
||||
|
||||
it('sends custom response headers', async () => {
|
||||
await registerStreamProtocol(protocolName, (request, callback) => callback({
|
||||
registerStreamProtocol(protocolName, (request, callback) => callback({
|
||||
data: getStream(3),
|
||||
headers: {
|
||||
'x-electron': ['a', 'b']
|
||||
|
@ -346,9 +343,9 @@ describe('protocol module', () => {
|
|||
});
|
||||
|
||||
it('sends custom status code', async () => {
|
||||
await registerStreamProtocol(protocolName, (request, callback) => callback({
|
||||
registerStreamProtocol(protocolName, (request, callback) => callback({
|
||||
statusCode: 204,
|
||||
data: null
|
||||
data: null as any
|
||||
}));
|
||||
const r = await ajax(protocolName + '://fake-host');
|
||||
expect(r.data).to.be.undefined('data');
|
||||
|
@ -356,7 +353,7 @@ describe('protocol module', () => {
|
|||
});
|
||||
|
||||
it('receives request headers', async () => {
|
||||
await registerStreamProtocol(protocolName, (request, callback) => {
|
||||
registerStreamProtocol(protocolName, (request, callback) => {
|
||||
callback({
|
||||
headers: {
|
||||
'content-type': 'application/json'
|
||||
|
@ -369,7 +366,7 @@ describe('protocol module', () => {
|
|||
});
|
||||
|
||||
it('returns response multiple response headers with the same name', async () => {
|
||||
await registerStreamProtocol(protocolName, (request, callback) => {
|
||||
registerStreamProtocol(protocolName, (request, callback) => {
|
||||
callback({
|
||||
headers: {
|
||||
header1: ['value1', 'value2'],
|
||||
|
@ -387,7 +384,7 @@ describe('protocol module', () => {
|
|||
|
||||
it('can handle large responses', async () => {
|
||||
const data = Buffer.alloc(128 * 1024);
|
||||
await registerStreamProtocol(protocolName, (request, callback) => {
|
||||
registerStreamProtocol(protocolName, (request, callback) => {
|
||||
callback(getStream(data.length, data));
|
||||
});
|
||||
const r = await ajax(protocolName + '://fake-host');
|
||||
|
@ -402,7 +399,7 @@ describe('protocol module', () => {
|
|||
}
|
||||
});
|
||||
}
|
||||
await registerStreamProtocol(protocolName, (request, callback) => {
|
||||
registerStreamProtocol(protocolName, (request, callback) => {
|
||||
callback({
|
||||
statusCode: 200,
|
||||
headers: { 'Content-Type': 'text/plain' },
|
||||
|
@ -414,48 +411,38 @@ describe('protocol module', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('protocol.isProtocolHandled', () => {
|
||||
it('returns true for built-in protocols', async () => {
|
||||
for (const p of ['about', 'file', 'http', 'https']) {
|
||||
const handled = await protocol.isProtocolHandled(p);
|
||||
expect(handled).to.be.true(`${p}: is handled`);
|
||||
}
|
||||
});
|
||||
|
||||
it('returns false when scheme is not registered', async () => {
|
||||
const result = await protocol.isProtocolHandled('no-exist');
|
||||
describe('protocol.isProtocolRegistered', () => {
|
||||
it('returns false when scheme is not registered', () => {
|
||||
const result = protocol.isProtocolRegistered('no-exist');
|
||||
expect(result).to.be.false('no-exist: is handled');
|
||||
});
|
||||
|
||||
it('returns true for custom protocol', async () => {
|
||||
await registerStringProtocol(protocolName, (request, callback) => callback());
|
||||
const result = await protocol.isProtocolHandled(protocolName);
|
||||
it('returns true for custom protocol', () => {
|
||||
registerStringProtocol(protocolName, (request, callback) => callback(''));
|
||||
const result = protocol.isProtocolRegistered(protocolName);
|
||||
expect(result).to.be.true('custom protocol is handled');
|
||||
});
|
||||
});
|
||||
|
||||
it('returns true for intercepted protocol', async () => {
|
||||
await interceptStringProtocol('http', (request, callback) => callback());
|
||||
const result = await protocol.isProtocolHandled('http');
|
||||
describe('protocol.isProtocolIntercepted', () => {
|
||||
it('returns true for intercepted protocol', () => {
|
||||
interceptStringProtocol('http', (request, callback) => callback(''));
|
||||
const result = protocol.isProtocolIntercepted('http');
|
||||
expect(result).to.be.true('intercepted protocol is handled');
|
||||
});
|
||||
});
|
||||
|
||||
describe('protocol.intercept(Any)Protocol', () => {
|
||||
it('throws error when scheme is already intercepted', (done) => {
|
||||
protocol.interceptStringProtocol('http', (request, callback) => callback(), (error) => {
|
||||
expect(error).to.be.null('error');
|
||||
protocol.interceptBufferProtocol('http', (request, callback) => callback(), (error) => {
|
||||
expect(error).to.not.be.null('error');
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('returns false when scheme is already intercepted', () => {
|
||||
expect(protocol.interceptStringProtocol('http', (request, callback) => callback(''))).to.equal(true);
|
||||
expect(protocol.interceptBufferProtocol('http', (request, callback) => callback(Buffer.from('')))).to.equal(false);
|
||||
});
|
||||
|
||||
it('does not crash when handler is called twice', async () => {
|
||||
await interceptStringProtocol('http', (request, callback) => {
|
||||
interceptStringProtocol('http', (request, callback) => {
|
||||
try {
|
||||
callback(text);
|
||||
callback();
|
||||
callback('');
|
||||
} catch (error) {
|
||||
// Ignore error
|
||||
}
|
||||
|
@ -465,20 +452,20 @@ describe('protocol module', () => {
|
|||
});
|
||||
|
||||
it('sends error when callback is called with nothing', async () => {
|
||||
await interceptStringProtocol('http', (request, callback) => callback());
|
||||
interceptStringProtocol('http', (request, callback: any) => callback());
|
||||
await expect(ajax('http://fake-host')).to.be.eventually.rejectedWith(Error, '404');
|
||||
});
|
||||
});
|
||||
|
||||
describe('protocol.interceptStringProtocol', () => {
|
||||
it('can intercept http protocol', async () => {
|
||||
await interceptStringProtocol('http', (request, callback) => callback(text));
|
||||
interceptStringProtocol('http', (request, callback) => callback(text));
|
||||
const r = await ajax('http://fake-host');
|
||||
expect(r.data).to.equal(text);
|
||||
});
|
||||
|
||||
it('can set content-type', async () => {
|
||||
await interceptStringProtocol('http', (request, callback) => {
|
||||
interceptStringProtocol('http', (request, callback) => {
|
||||
callback({
|
||||
mimeType: 'application/json',
|
||||
data: '{"value": 1}'
|
||||
|
@ -490,7 +477,7 @@ describe('protocol module', () => {
|
|||
});
|
||||
|
||||
it('can set content-type with charset', async () => {
|
||||
await interceptStringProtocol('http', (request, callback) => {
|
||||
interceptStringProtocol('http', (request, callback) => {
|
||||
callback({
|
||||
mimeType: 'application/json; charset=UTF-8',
|
||||
data: '{"value": 1}'
|
||||
|
@ -502,8 +489,8 @@ describe('protocol module', () => {
|
|||
});
|
||||
|
||||
it('can receive post data', async () => {
|
||||
await interceptStringProtocol('http', (request, callback) => {
|
||||
const uploadData = request.uploadData[0].bytes.toString();
|
||||
interceptStringProtocol('http', (request, callback) => {
|
||||
const uploadData = request.uploadData![0].bytes.toString();
|
||||
callback({ data: uploadData });
|
||||
});
|
||||
const r = await ajax('http://fake-host', { type: 'POST', data: postData });
|
||||
|
@ -513,14 +500,14 @@ describe('protocol module', () => {
|
|||
|
||||
describe('protocol.interceptBufferProtocol', () => {
|
||||
it('can intercept http protocol', async () => {
|
||||
await interceptBufferProtocol('http', (request, callback) => callback(Buffer.from(text)));
|
||||
interceptBufferProtocol('http', (request, callback) => callback(Buffer.from(text)));
|
||||
const r = await ajax('http://fake-host');
|
||||
expect(r.data).to.equal(text);
|
||||
});
|
||||
|
||||
it('can receive post data', async () => {
|
||||
await interceptBufferProtocol('http', (request, callback) => {
|
||||
const uploadData = request.uploadData[0].bytes;
|
||||
interceptBufferProtocol('http', (request, callback) => {
|
||||
const uploadData = request.uploadData![0].bytes;
|
||||
callback(uploadData);
|
||||
});
|
||||
const r = await ajax('http://fake-host', { type: 'POST', data: postData });
|
||||
|
@ -544,19 +531,19 @@ describe('protocol module', () => {
|
|||
server.close();
|
||||
});
|
||||
after(() => server.close());
|
||||
await server.listen(0, '127.0.0.1');
|
||||
server.listen(0, '127.0.0.1');
|
||||
|
||||
const port = (server.address() as AddressInfo).port;
|
||||
const url = `http://127.0.0.1:${port}`;
|
||||
await interceptHttpProtocol('http', (request, callback) => {
|
||||
const data: Electron.RedirectRequest = {
|
||||
interceptHttpProtocol('http', (request, callback) => {
|
||||
const data: Electron.ProtocolResponse = {
|
||||
url: url,
|
||||
method: 'POST',
|
||||
uploadData: {
|
||||
contentType: 'application/x-www-form-urlencoded',
|
||||
data: request.uploadData[0].bytes
|
||||
data: request.uploadData![0].bytes
|
||||
},
|
||||
session: null
|
||||
session: undefined
|
||||
};
|
||||
callback(data);
|
||||
});
|
||||
|
@ -572,7 +559,7 @@ describe('protocol module', () => {
|
|||
});
|
||||
after(() => customSession.webRequest.onBeforeRequest(null));
|
||||
|
||||
await interceptHttpProtocol('http', (request, callback) => {
|
||||
interceptHttpProtocol('http', (request, callback) => {
|
||||
callback({
|
||||
url: request.url,
|
||||
session: customSession
|
||||
|
@ -585,33 +572,32 @@ describe('protocol module', () => {
|
|||
protocol.interceptHttpProtocol('http', (request) => {
|
||||
expect(request).to.have.property('headers');
|
||||
done();
|
||||
}, () => {
|
||||
ajax('http://fake-host');
|
||||
});
|
||||
ajax('http://fake-host');
|
||||
});
|
||||
});
|
||||
|
||||
describe('protocol.interceptStreamProtocol', () => {
|
||||
it('can intercept http protocol', async () => {
|
||||
await interceptStreamProtocol('http', (request, callback) => callback(getStream()));
|
||||
interceptStreamProtocol('http', (request, callback) => callback(getStream()));
|
||||
const r = await ajax('http://fake-host');
|
||||
expect(r.data).to.equal(text);
|
||||
});
|
||||
|
||||
it('can receive post data', async () => {
|
||||
await interceptStreamProtocol('http', (request, callback) => {
|
||||
callback(getStream(3, request.uploadData[0].bytes.toString()));
|
||||
interceptStreamProtocol('http', (request, callback) => {
|
||||
callback(getStream(3, request.uploadData![0].bytes.toString()));
|
||||
});
|
||||
const r = await ajax('http://fake-host', { type: 'POST', data: postData });
|
||||
expect({ ...qs.parse(r.data) }).to.deep.equal(postData);
|
||||
});
|
||||
|
||||
it('can execute redirects', async () => {
|
||||
await interceptStreamProtocol('http', (request, callback) => {
|
||||
interceptStreamProtocol('http', (request, callback) => {
|
||||
if (request.url.indexOf('http://fake-host') === 0) {
|
||||
setTimeout(() => {
|
||||
callback({
|
||||
data: null,
|
||||
data: '',
|
||||
statusCode: 302,
|
||||
headers: {
|
||||
Location: 'http://fake-redirect'
|
||||
|
@ -629,12 +615,12 @@ describe('protocol module', () => {
|
|||
});
|
||||
|
||||
describe('protocol.uninterceptProtocol', () => {
|
||||
it('returns error when scheme does not exist', async () => {
|
||||
await expect(uninterceptProtocol('not-exist')).to.be.eventually.rejectedWith(Error);
|
||||
it('returns false when scheme does not exist', () => {
|
||||
expect(uninterceptProtocol('not-exist')).to.equal(false);
|
||||
});
|
||||
|
||||
it('returns error when scheme is not intercepted', async () => {
|
||||
await expect(uninterceptProtocol('http')).to.be.eventually.rejectedWith(Error);
|
||||
it('returns false when scheme is not intercepted', () => {
|
||||
expect(uninterceptProtocol('http')).to.equal(false);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -677,14 +663,14 @@ describe('protocol module', () => {
|
|||
|
||||
afterEach(async () => {
|
||||
await closeWindow(w);
|
||||
await unregisterProtocol(standardScheme);
|
||||
unregisterProtocol(standardScheme);
|
||||
w = null as unknown as BrowserWindow;
|
||||
});
|
||||
|
||||
it('resolves relative resources', async () => {
|
||||
await registerFileProtocol(standardScheme, (request, callback) => {
|
||||
registerFileProtocol(standardScheme, (request, callback) => {
|
||||
if (request.url === imageURL) {
|
||||
callback();
|
||||
callback('');
|
||||
} else {
|
||||
callback(filePath);
|
||||
}
|
||||
|
@ -693,9 +679,9 @@ describe('protocol module', () => {
|
|||
});
|
||||
|
||||
it('resolves absolute resources', async () => {
|
||||
await registerStringProtocol(standardScheme, (request, callback) => {
|
||||
registerStringProtocol(standardScheme, (request, callback) => {
|
||||
if (request.url === imageURL) {
|
||||
callback();
|
||||
callback('');
|
||||
} else {
|
||||
callback({
|
||||
data: fileContent,
|
||||
|
@ -716,17 +702,15 @@ describe('protocol module', () => {
|
|||
await new Promise(resolve => server.listen(0, '127.0.0.1', resolve));
|
||||
const port = (server.address() as AddressInfo).port;
|
||||
const content = `<script>fetch("http://127.0.0.1:${port}")</script>`;
|
||||
await registerStringProtocol(standardScheme, (request, callback) => callback({ data: content, mimeType: 'text/html' }));
|
||||
registerStringProtocol(standardScheme, (request, callback) => callback({ data: content, mimeType: 'text/html' }));
|
||||
await w.loadURL(origin);
|
||||
await requestReceived;
|
||||
});
|
||||
|
||||
it.skip('can access files through the FileSystem API', (done) => {
|
||||
const filePath = path.join(fixturesPath, 'pages', 'filesystem.html');
|
||||
protocol.registerFileProtocol(standardScheme, (request, callback) => callback({ path: filePath }), (error) => {
|
||||
if (error) return done(error);
|
||||
w.loadURL(origin);
|
||||
});
|
||||
protocol.registerFileProtocol(standardScheme, (request, callback) => callback({ path: filePath }));
|
||||
w.loadURL(origin);
|
||||
ipcMain.once('file-system-error', (event, err) => done(err));
|
||||
ipcMain.once('file-system-write-end', () => done());
|
||||
});
|
||||
|
@ -735,10 +719,8 @@ describe('protocol module', () => {
|
|||
const filePath = path.join(fixturesPath, 'pages', 'cache-storage.html');
|
||||
ipcMain.once('success', () => done());
|
||||
ipcMain.once('failure', (event, err) => done(err));
|
||||
protocol.registerFileProtocol(standardScheme, (request, callback) => callback({ path: filePath }), (error) => {
|
||||
if (error) return done(error);
|
||||
w.loadURL(origin);
|
||||
});
|
||||
protocol.registerFileProtocol(standardScheme, (request, callback) => callback({ path: filePath }));
|
||||
w.loadURL(origin);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -752,11 +734,9 @@ describe('protocol module', () => {
|
|||
afterEach(async () => {
|
||||
await closeWindow(w);
|
||||
w = null as unknown as BrowserWindow;
|
||||
await Promise.all(
|
||||
[standardScheme, 'cors', 'no-cors', 'no-fetch'].map(scheme =>
|
||||
new Promise(resolve => protocol.unregisterProtocol(scheme, (/* ignore error */) => resolve()))
|
||||
)
|
||||
);
|
||||
for (const scheme of [standardScheme, 'cors', 'no-cors', 'no-fetch']) {
|
||||
protocol.unregisterProtocol(scheme);
|
||||
}
|
||||
});
|
||||
|
||||
it('supports fetch api by default', async () => {
|
||||
|
@ -818,10 +798,10 @@ describe('protocol module', () => {
|
|||
});
|
||||
|
||||
async function allowsCORSRequests (corsScheme: string, expected: any, expectedConsole: RegExp, content: Function) {
|
||||
await registerStringProtocol(standardScheme, (request, callback) => {
|
||||
registerStringProtocol(standardScheme, (request, callback) => {
|
||||
callback({ data: `<script>(${content})()</script>`, mimeType: 'text/html' });
|
||||
});
|
||||
await registerStringProtocol(corsScheme, (request, callback) => {
|
||||
registerStringProtocol(corsScheme, (request, callback) => {
|
||||
callback('');
|
||||
});
|
||||
|
||||
|
|
|
@ -312,11 +312,11 @@ describe('session module', () => {
|
|||
});
|
||||
afterEach(closeAllWindows);
|
||||
|
||||
it('does not affect defaultSession', async () => {
|
||||
const result1 = await protocol.isProtocolHandled(protocolName);
|
||||
it('does not affect defaultSession', () => {
|
||||
const result1 = protocol.isProtocolRegistered(protocolName);
|
||||
expect(result1).to.equal(false);
|
||||
|
||||
const result2 = await customSession.protocol.isProtocolHandled(protocolName);
|
||||
const result2 = customSession.protocol.isProtocolRegistered(protocolName);
|
||||
expect(result2).to.equal(true);
|
||||
});
|
||||
|
||||
|
@ -424,18 +424,16 @@ describe('session module', () => {
|
|||
if (request.method === 'GET') {
|
||||
callback({ data: content, mimeType: 'text/html' });
|
||||
} else if (request.method === 'POST') {
|
||||
const uuid = request.uploadData[1].blobUUID;
|
||||
const uuid = request.uploadData![1].blobUUID;
|
||||
expect(uuid).to.be.a('string');
|
||||
session.defaultSession.getBlobData(uuid!).then(result => {
|
||||
expect(result.toString()).to.equal(postData);
|
||||
done();
|
||||
});
|
||||
}
|
||||
}, (error) => {
|
||||
if (error) return done(error);
|
||||
const w = new BrowserWindow({ show: false });
|
||||
w.loadURL(url);
|
||||
});
|
||||
const w = new BrowserWindow({ show: false });
|
||||
w.loadURL(url);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -644,18 +642,16 @@ describe('session module', () => {
|
|||
const handler = (ignoredError: any, callback: Function) => {
|
||||
callback({ url: `${url}:${port}` });
|
||||
};
|
||||
protocol.registerHttpProtocol(protocolName, handler, (error) => {
|
||||
if (error) return done(error);
|
||||
const w = new BrowserWindow({ show: false });
|
||||
w.webContents.session.once('will-download', function (e, item) {
|
||||
item.savePath = downloadFilePath;
|
||||
item.on('done', function (e, state) {
|
||||
assertDownload(state, item, true);
|
||||
done();
|
||||
});
|
||||
protocol.registerHttpProtocol(protocolName, handler);
|
||||
const w = new BrowserWindow({ show: false });
|
||||
w.webContents.session.once('will-download', function (e, item) {
|
||||
item.savePath = downloadFilePath;
|
||||
item.on('done', function (e, state) {
|
||||
assertDownload(state, item, true);
|
||||
done();
|
||||
});
|
||||
w.webContents.downloadURL(`${protocolName}://item`);
|
||||
});
|
||||
w.webContents.downloadURL(`${protocolName}://item`);
|
||||
});
|
||||
|
||||
it('can download using WebView.downloadURL', async () => {
|
||||
|
|
|
@ -830,7 +830,7 @@ describe('webContents module', () => {
|
|||
host3: 0.2
|
||||
};
|
||||
|
||||
before((done) => {
|
||||
before(() => {
|
||||
const protocol = session.defaultSession.protocol;
|
||||
protocol.registerStringProtocol(scheme, (request, callback) => {
|
||||
const response = `<script>
|
||||
|
@ -841,12 +841,12 @@ describe('webContents module', () => {
|
|||
})
|
||||
</script>`;
|
||||
callback({ data: response, mimeType: 'text/html' });
|
||||
}, (error) => done(error));
|
||||
});
|
||||
});
|
||||
|
||||
after((done) => {
|
||||
after(() => {
|
||||
const protocol = session.defaultSession.protocol;
|
||||
protocol.unregisterProtocol(scheme, (error) => done(error));
|
||||
protocol.unregisterProtocol(scheme);
|
||||
});
|
||||
|
||||
afterEach(closeAllWindows);
|
||||
|
@ -981,29 +981,25 @@ describe('webContents module', () => {
|
|||
const protocol = w2.webContents.session.protocol;
|
||||
protocol.registerStringProtocol(scheme, (request, callback) => {
|
||||
callback('hello');
|
||||
}, (error) => {
|
||||
if (error) return done(error);
|
||||
w2.webContents.on('did-finish-load', () => {
|
||||
const zoomLevel1 = w.webContents.zoomLevel;
|
||||
expect(zoomLevel1).to.equal(hostZoomMap.host3);
|
||||
|
||||
const zoomLevel2 = w2.webContents.zoomLevel;
|
||||
expect(zoomLevel2).to.equal(0);
|
||||
expect(zoomLevel1).to.not.equal(zoomLevel2);
|
||||
|
||||
protocol.unregisterProtocol(scheme, (error) => {
|
||||
if (error) return done(error);
|
||||
w2.setClosable(true);
|
||||
w2.close();
|
||||
done();
|
||||
});
|
||||
});
|
||||
w.webContents.on('did-finish-load', () => {
|
||||
w.webContents.zoomLevel = hostZoomMap.host3;
|
||||
w2.loadURL(`${scheme}://host3`);
|
||||
});
|
||||
w.loadURL(`${scheme}://host3`);
|
||||
});
|
||||
w2.webContents.on('did-finish-load', () => {
|
||||
const zoomLevel1 = w.webContents.zoomLevel;
|
||||
expect(zoomLevel1).to.equal(hostZoomMap.host3);
|
||||
|
||||
const zoomLevel2 = w2.webContents.zoomLevel;
|
||||
expect(zoomLevel2).to.equal(0);
|
||||
expect(zoomLevel1).to.not.equal(zoomLevel2);
|
||||
|
||||
protocol.unregisterProtocol(scheme);
|
||||
w2.setClosable(true);
|
||||
w2.close();
|
||||
done();
|
||||
});
|
||||
w.webContents.on('did-finish-load', () => {
|
||||
w.webContents.zoomLevel = hostZoomMap.host3;
|
||||
w2.loadURL(`${scheme}://host3`);
|
||||
});
|
||||
w.loadURL(`${scheme}://host3`);
|
||||
});
|
||||
|
||||
it('can persist when it contains iframe', (done) => {
|
||||
|
|
|
@ -410,8 +410,6 @@ describe('chromium features', () => {
|
|||
|
||||
if (ext === '.js') type = 'application/javascript';
|
||||
callback({ data: content, mimeType: type } as any);
|
||||
}, (error) => {
|
||||
if (error) done(error);
|
||||
});
|
||||
|
||||
const w = new BrowserWindow({
|
||||
|
@ -431,7 +429,8 @@ describe('chromium features', () => {
|
|||
customSession.clearStorageData({
|
||||
storages: ['serviceworkers']
|
||||
}).then(() => {
|
||||
customSession.protocol.uninterceptProtocol('file', error => done(error));
|
||||
customSession.protocol.uninterceptProtocol('file');
|
||||
done();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -840,8 +839,8 @@ describe('chromium features', () => {
|
|||
];
|
||||
const s = (url: string) => url.startsWith('file') ? 'file://...' : url;
|
||||
|
||||
before(async () => {
|
||||
await promisify(protocol.registerFileProtocol)(scheme, (request, callback) => {
|
||||
before(() => {
|
||||
protocol.registerFileProtocol(scheme, (request, callback) => {
|
||||
if (request.url.includes('blank')) {
|
||||
callback(`${fixturesPath}/pages/blank.html`);
|
||||
} else {
|
||||
|
@ -849,8 +848,8 @@ describe('chromium features', () => {
|
|||
}
|
||||
});
|
||||
});
|
||||
after(async () => {
|
||||
await promisify(protocol.unregisterProtocol)(scheme);
|
||||
after(() => {
|
||||
protocol.unregisterProtocol(scheme);
|
||||
});
|
||||
afterEach(closeAllWindows);
|
||||
|
||||
|
@ -929,7 +928,7 @@ describe('chromium features', () => {
|
|||
describe('custom non standard schemes', () => {
|
||||
const protocolName = 'storage';
|
||||
let contents: WebContents;
|
||||
before((done) => {
|
||||
before(() => {
|
||||
protocol.registerFileProtocol(protocolName, (request, callback) => {
|
||||
const parsedUrl = url.parse(request.url);
|
||||
let filename;
|
||||
|
@ -942,11 +941,11 @@ describe('chromium features', () => {
|
|||
default : filename = '';
|
||||
}
|
||||
callback({ path: `${fixturesPath}/pages/storage/${filename}` });
|
||||
}, (error) => done(error));
|
||||
});
|
||||
});
|
||||
|
||||
after((done) => {
|
||||
protocol.unregisterProtocol(protocolName, () => done());
|
||||
after(() => {
|
||||
protocol.unregisterProtocol(protocolName);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
|
|
|
@ -217,16 +217,16 @@ describe('<webview> tag', function () {
|
|||
const zoomScheme = standardScheme;
|
||||
const webviewSession = session.fromPartition('webview-temp');
|
||||
|
||||
before((done) => {
|
||||
before(() => {
|
||||
const protocol = webviewSession.protocol;
|
||||
protocol.registerStringProtocol(zoomScheme, (request, callback) => {
|
||||
callback('hello');
|
||||
}, (error) => done(error));
|
||||
});
|
||||
});
|
||||
|
||||
after((done) => {
|
||||
after(() => {
|
||||
const protocol = webviewSession.protocol;
|
||||
protocol.unregisterProtocol(zoomScheme, (error) => done(error));
|
||||
protocol.unregisterProtocol(zoomScheme);
|
||||
});
|
||||
|
||||
it('inherits the zoomFactor of the parent window', async () => {
|
||||
|
|
|
@ -897,13 +897,9 @@ app.whenReady().then(() => {
|
|||
callback({ url: request.url, method: request.method })
|
||||
})
|
||||
|
||||
protocol.unregisterProtocol('atom', (error) => {
|
||||
console.log(error ? error.message : 'ok')
|
||||
})
|
||||
protocol.unregisterProtocol('atom')
|
||||
|
||||
protocol.isProtocolHandled('atom').then(handled => {
|
||||
console.log(handled)
|
||||
})
|
||||
const registered: boolean = protocol.isProtocolRegistered('atom')
|
||||
})
|
||||
|
||||
// tray
|
||||
|
@ -1195,10 +1191,6 @@ app.whenReady().then(function () {
|
|||
protocol.registerFileProtocol('atom', function (request, callback) {
|
||||
const url = request.url.substr(7)
|
||||
callback(path.normalize(__dirname + '/' + url))
|
||||
}, function (error) {
|
||||
if (error) {
|
||||
console.error('Failed to register protocol')
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче