electron/spec/api-session-spec.js

809 lines
27 KiB
JavaScript
Raw Normal View History

2016-03-25 20:03:49 +00:00
const assert = require('assert')
const http = require('http')
const https = require('https')
2016-03-25 20:03:49 +00:00
const path = require('path')
const fs = require('fs')
2016-11-24 15:16:39 +00:00
const send = require('send')
2016-11-30 20:02:17 +00:00
const auth = require('basic-auth')
2018-09-13 16:10:51 +00:00
const { closeWindow } = require('./window-helpers')
2016-01-12 02:40:23 +00:00
2018-09-13 16:10:51 +00:00
const { ipcRenderer, remote } = require('electron')
const { ipcMain, session, BrowserWindow, net } = remote
2016-01-12 02:40:23 +00:00
2017-11-23 22:22:43 +00:00
/* The whole session API doesn't use standard callbacks */
/* eslint-disable standard/no-callback-literal */
describe('session module', () => {
let fixtures = path.resolve(__dirname, 'fixtures')
let w = null
let webview = null
const url = 'http://127.0.0.1'
beforeEach(() => {
2016-02-17 01:39:11 +00:00
w = new BrowserWindow({
2016-01-12 02:40:23 +00:00
show: false,
width: 400,
height: 400
2016-03-25 20:03:49 +00:00
})
})
afterEach(() => {
2016-12-20 00:37:47 +00:00
if (webview != null) {
if (!document.body.contains(webview)) {
document.body.appendChild(webview)
}
webview.remove()
}
return closeWindow(w).then(() => { w = null })
2016-03-25 20:03:49 +00:00
})
2016-01-13 09:19:53 +00:00
describe('session.defaultSession', () => {
it('returns the default session', () => {
2018-09-13 16:10:51 +00:00
assert.strictEqual(session.defaultSession, session.fromPartition(''))
2016-07-12 13:24:09 +00:00
})
})
describe('session.fromPartition(partition, options)', () => {
it('returns existing session with same partition', () => {
2018-09-13 16:10:51 +00:00
assert.strictEqual(session.fromPartition('test'), session.fromPartition('test'))
})
it('created session is ref-counted', () => {
const partition = 'test2'
const userAgent = 'test-agent'
const ses1 = session.fromPartition(partition)
ses1.setUserAgent(userAgent)
2018-09-13 16:10:51 +00:00
assert.strictEqual(ses1.getUserAgent(), userAgent)
ses1.destroy()
const ses2 = session.fromPartition(partition)
2018-09-13 16:10:51 +00:00
assert.notStrictEqual(ses2.getUserAgent(), userAgent)
})
})
describe('ses.cookies', () => {
it('should get cookies', (done) => {
const server = http.createServer((req, res) => {
2016-03-25 20:03:49 +00:00
res.setHeader('Set-Cookie', ['0=0'])
res.end('finished')
server.close()
})
server.listen(0, '127.0.0.1', () => {
const port = server.address().port
w.loadURL(`${url}:${port}`)
w.webContents.on('did-finish-load', () => {
2018-09-13 16:10:51 +00:00
w.webContents.session.cookies.get({ url }, (error, list) => {
if (error) return done(error)
for (let i = 0; i < list.length; i++) {
const cookie = list[i]
2016-01-13 09:19:53 +00:00
if (cookie.name === '0') {
if (cookie.value === '0') {
2016-03-25 20:03:49 +00:00
return done()
2016-01-13 09:19:53 +00:00
} else {
return done(`cookie value is ${cookie.value} while expecting 0`)
2016-01-13 09:19:53 +00:00
}
}
}
done('Can\'t find cookie')
2016-03-25 20:03:49 +00:00
})
})
})
})
it('calls back with an error when setting a cookie with missing required fields', (done) => {
session.defaultSession.cookies.set({
url: '',
name: '1',
value: '1'
}, (error) => {
assert(error, 'Should have an error')
2018-09-13 16:10:51 +00:00
assert.strictEqual(error.message, 'Setting cookie failed')
done()
})
})
it('should over-write the existent cookie', (done) => {
2016-02-17 01:39:11 +00:00
session.defaultSession.cookies.set({
url,
2016-01-13 09:19:53 +00:00
name: '1',
value: '1'
}, (error) => {
if (error) return done(error)
2018-09-13 16:10:51 +00:00
session.defaultSession.cookies.get({ url }, (error, list) => {
if (error) return done(error)
for (let i = 0; i < list.length; i++) {
const cookie = list[i]
2016-01-13 09:19:53 +00:00
if (cookie.name === '1') {
if (cookie.value === '1') {
2016-03-25 20:03:49 +00:00
return done()
2016-01-12 02:40:23 +00:00
} else {
return done(`cookie value is ${cookie.value} while expecting 1`)
2016-01-12 02:40:23 +00:00
}
}
}
done('Can\'t find cookie')
2016-03-25 20:03:49 +00:00
})
})
})
it('should remove cookies', (done) => {
2016-02-17 01:39:11 +00:00
session.defaultSession.cookies.set({
2016-01-13 09:19:53 +00:00
url: url,
name: '2',
value: '2'
}, (error) => {
if (error) return done(error)
session.defaultSession.cookies.remove(url, '2', () => {
2018-09-13 16:10:51 +00:00
session.defaultSession.cookies.get({ url }, (error, list) => {
if (error) return done(error)
for (let i = 0; i < list.length; i++) {
const cookie = list[i]
if (cookie.name === '2') return done('Cookie not deleted')
2016-01-12 02:40:23 +00:00
}
2016-03-25 20:03:49 +00:00
done()
})
})
})
})
it('should set cookie for standard scheme', (done) => {
const standardScheme = remote.getGlobal('standardScheme')
const origin = standardScheme + '://fake-host'
session.defaultSession.cookies.set({
url: origin,
name: 'custom',
value: '1'
}, (error) => {
if (error) return done(error)
2018-09-13 16:10:51 +00:00
session.defaultSession.cookies.get({ url: origin }, (error, list) => {
if (error) return done(error)
2018-09-13 16:10:51 +00:00
assert.strictEqual(list.length, 1)
assert.strictEqual(list[0].name, 'custom')
assert.strictEqual(list[0].value, '1')
assert.strictEqual(list[0].domain, 'fake-host')
done()
})
})
})
2016-09-29 00:08:25 +00:00
it('emits a changed event when a cookie is added or removed', (done) => {
2018-09-13 16:10:51 +00:00
const { cookies } = session.fromPartition('cookies-changed')
2016-09-29 00:08:25 +00:00
cookies.once('changed', (event, cookie, cause, removed) => {
2018-09-13 16:10:51 +00:00
assert.strictEqual(cookie.name, 'foo')
assert.strictEqual(cookie.value, 'bar')
assert.strictEqual(cause, 'explicit')
assert.strictEqual(removed, false)
cookies.once('changed', (event, cookie, cause, removed) => {
2018-09-13 16:10:51 +00:00
assert.strictEqual(cookie.name, 'foo')
assert.strictEqual(cookie.value, 'bar')
assert.strictEqual(cause, 'explicit')
assert.strictEqual(removed, true)
2016-09-29 00:08:25 +00:00
done()
})
cookies.remove(url, 'foo', (error) => {
2016-09-29 00:08:25 +00:00
if (error) return done(error)
})
})
cookies.set({
url: url,
name: 'foo',
value: 'bar'
}, (error) => {
if (error) return done(error)
2016-09-29 00:08:25 +00:00
})
})
describe('ses.cookies.flushStore(callback)', () => {
it('flushes the cookies to disk and invokes the callback when done', (done) => {
session.defaultSession.cookies.set({
url: url,
name: 'foo',
value: 'bar'
}, (error) => {
if (error) return done(error)
session.defaultSession.cookies.flushStore(() => {
done()
})
})
})
})
2016-03-25 20:03:49 +00:00
})
2016-01-13 09:19:53 +00:00
describe('ses.clearStorageData(options)', () => {
2016-03-25 20:03:49 +00:00
fixtures = path.resolve(__dirname, 'fixtures')
it('clears localstorage data', (done) => {
ipcMain.on('count', (event, count) => {
2016-03-25 20:03:49 +00:00
ipcMain.removeAllListeners('count')
2018-09-13 16:10:51 +00:00
assert.strictEqual(count, 0)
2016-03-25 20:03:49 +00:00
done()
})
w.loadFile(path.join(fixtures, 'api', 'localstorage.html'))
w.webContents.on('did-finish-load', () => {
const options = {
2016-03-25 20:03:49 +00:00
origin: 'file://',
2016-01-12 02:40:23 +00:00
storages: ['localstorage'],
quotas: ['persistent']
2016-03-25 20:03:49 +00:00
}
w.webContents.session.clearStorageData(options, () => {
2016-03-25 20:03:49 +00:00
w.webContents.send('getcount')
})
})
})
})
describe('will-download event', () => {
beforeEach(() => {
if (w != null) w.destroy()
w = new BrowserWindow({
show: false,
width: 400,
height: 400
2016-03-25 20:03:49 +00:00
})
})
it('can cancel default download behavior', (done) => {
const mockFile = Buffer.alloc(1024)
2016-03-25 20:03:49 +00:00
const contentDisposition = 'inline; filename="mockFile.txt"'
const downloadServer = http.createServer((req, res) => {
res.writeHead(200, {
'Content-Length': mockFile.length,
'Content-Type': 'application/plain',
'Content-Disposition': contentDisposition
2016-03-25 20:03:49 +00:00
})
res.end(mockFile)
downloadServer.close()
})
downloadServer.listen(0, '127.0.0.1', () => {
2016-03-25 20:03:49 +00:00
const port = downloadServer.address().port
const url = `http://127.0.0.1:${port}/`
2016-03-25 20:03:49 +00:00
ipcRenderer.sendSync('set-download-option', false, true)
w.loadURL(url)
ipcRenderer.once('download-error', (event, downloadUrl, filename, error) => {
2018-09-13 16:10:51 +00:00
assert.strictEqual(downloadUrl, url)
assert.strictEqual(filename, 'mockFile.txt')
assert.strictEqual(error, 'Object has been destroyed')
2016-03-25 20:03:49 +00:00
done()
})
})
})
})
describe('DownloadItem', () => {
const mockPDF = Buffer.alloc(1024 * 1024 * 5)
const protocolName = 'custom-dl'
let contentDisposition = 'inline; filename="mock.pdf"'
const downloadFilePath = path.join(fixtures, 'mock.pdf')
const downloadServer = http.createServer((req, res) => {
if (req.url === '/?testFilename') contentDisposition = 'inline'
2016-01-12 02:40:23 +00:00
res.writeHead(200, {
'Content-Length': mockPDF.length,
'Content-Type': 'application/pdf',
'Content-Disposition': contentDisposition
2016-03-25 20:03:49 +00:00
})
res.end(mockPDF)
downloadServer.close()
})
const isPathEqual = (path1, path2) => {
return path.relative(path1, path2) === ''
}
const assertDownload = (event, state, url, mimeType,
2018-09-13 16:10:51 +00:00
receivedBytes, totalBytes, disposition,
filename, port, savePath, isCustom) => {
assert.strictEqual(state, 'completed')
assert.strictEqual(filename, 'mock.pdf')
assert.ok(path.isAbsolute(savePath))
assert.ok(isPathEqual(savePath, path.join(__dirname, 'fixtures', 'mock.pdf')))
if (isCustom) {
2018-09-13 16:10:51 +00:00
assert.strictEqual(url, `${protocolName}://item`)
} else {
2018-09-13 16:10:51 +00:00
assert.strictEqual(url, `http://127.0.0.1:${port}/`)
}
2018-09-13 16:10:51 +00:00
assert.strictEqual(mimeType, 'application/pdf')
assert.strictEqual(receivedBytes, mockPDF.length)
assert.strictEqual(totalBytes, mockPDF.length)
assert.strictEqual(disposition, contentDisposition)
2016-03-25 20:03:49 +00:00
assert(fs.existsSync(downloadFilePath))
fs.unlinkSync(downloadFilePath)
}
it('can download using WebContents.downloadURL', (done) => {
downloadServer.listen(0, '127.0.0.1', () => {
const port = downloadServer.address().port
2016-03-25 20:03:49 +00:00
ipcRenderer.sendSync('set-download-option', false, false)
w.webContents.downloadURL(`${url}:${port}`)
ipcRenderer.once('download-done', (event, state, url,
2018-09-13 16:10:51 +00:00
mimeType, receivedBytes,
totalBytes, disposition,
filename, savePath) => {
2016-11-24 15:16:39 +00:00
assertDownload(event, state, url, mimeType, receivedBytes,
2018-09-13 16:10:51 +00:00
totalBytes, disposition, filename, port, savePath)
2016-03-25 20:03:49 +00:00
done()
})
})
})
it('can download from custom protocols using WebContents.downloadURL', (done) => {
const protocol = session.defaultSession.protocol
downloadServer.listen(0, '127.0.0.1', () => {
const port = downloadServer.address().port
const handler = (ignoredError, callback) => {
2018-09-13 16:10:51 +00:00
callback({ url: `${url}:${port}` })
}
protocol.registerHttpProtocol(protocolName, handler, (error) => {
if (error) return done(error)
ipcRenderer.sendSync('set-download-option', false, false)
w.webContents.downloadURL(`${protocolName}://item`)
ipcRenderer.once('download-done', (event, state, url,
2018-09-13 16:10:51 +00:00
mimeType, receivedBytes,
totalBytes, disposition,
filename, savePath) => {
assertDownload(event, state, url, mimeType, receivedBytes,
2018-09-13 16:10:51 +00:00
totalBytes, disposition, filename, port, savePath,
true)
done()
})
})
})
})
it('can download using WebView.downloadURL', (done) => {
downloadServer.listen(0, '127.0.0.1', () => {
const port = downloadServer.address().port
2016-03-25 20:03:49 +00:00
ipcRenderer.sendSync('set-download-option', false, false)
webview = new WebView()
webview.src = `file://${fixtures}/api/blank.html`
webview.addEventListener('did-finish-load', () => {
webview.downloadURL(`${url}:${port}/`)
2016-03-25 20:03:49 +00:00
})
ipcRenderer.once('download-done', (event, state, url,
2018-09-13 16:10:51 +00:00
mimeType, receivedBytes,
totalBytes, disposition,
filename, savePath) => {
2016-11-24 15:16:39 +00:00
assertDownload(event, state, url, mimeType, receivedBytes,
2018-09-13 16:10:51 +00:00
totalBytes, disposition, filename, port, savePath)
2016-03-25 20:03:49 +00:00
document.body.removeChild(webview)
done()
})
document.body.appendChild(webview)
})
})
it('can cancel download', (done) => {
downloadServer.listen(0, '127.0.0.1', () => {
const port = downloadServer.address().port
2016-03-25 20:03:49 +00:00
ipcRenderer.sendSync('set-download-option', true, false)
w.webContents.downloadURL(`${url}:${port}/`)
ipcRenderer.once('download-done', (event, state, url,
2018-09-13 16:10:51 +00:00
mimeType, receivedBytes,
totalBytes, disposition,
filename) => {
assert.strictEqual(state, 'cancelled')
assert.strictEqual(filename, 'mock.pdf')
assert.strictEqual(mimeType, 'application/pdf')
assert.strictEqual(receivedBytes, 0)
assert.strictEqual(totalBytes, mockPDF.length)
assert.strictEqual(disposition, contentDisposition)
2016-03-25 20:03:49 +00:00
done()
})
})
})
it('can generate a default filename', function (done) {
if (process.env.APPVEYOR === 'True') {
// FIXME(alexeykuzmin): Skip the test.
// this.skip()
return done()
}
downloadServer.listen(0, '127.0.0.1', () => {
const port = downloadServer.address().port
2016-09-10 12:13:27 +00:00
ipcRenderer.sendSync('set-download-option', true, false)
w.webContents.downloadURL(`${url}:${port}/?testFilename`)
ipcRenderer.once('download-done', (event, state, url,
2018-09-13 16:10:51 +00:00
mimeType, receivedBytes,
totalBytes, disposition,
filename) => {
assert.strictEqual(state, 'cancelled')
assert.strictEqual(filename, 'download.pdf')
assert.strictEqual(mimeType, 'application/pdf')
assert.strictEqual(receivedBytes, 0)
assert.strictEqual(totalBytes, mockPDF.length)
assert.strictEqual(disposition, contentDisposition)
2016-09-10 12:13:27 +00:00
done()
})
})
})
describe('when a save path is specified and the URL is unavailable', () => {
it('does not display a save dialog and reports the done state as interrupted', (done) => {
ipcRenderer.sendSync('set-download-option', false, false)
ipcRenderer.once('download-done', (event, state) => {
2018-09-13 16:10:51 +00:00
assert.strictEqual(state, 'interrupted')
done()
})
w.webContents.downloadURL(`file://${path.join(__dirname, 'does-not-exist.txt')}`)
})
})
2016-03-25 20:03:49 +00:00
})
describe('ses.protocol', () => {
const partitionName = 'temp'
const protocolName = 'sp'
const partitionProtocol = session.fromPartition(partitionName).protocol
const protocol = session.defaultSession.protocol
const handler = (ignoredError, callback) => {
2018-09-13 16:10:51 +00:00
callback({ data: 'test', mimeType: 'text/html' })
}
beforeEach((done) => {
if (w != null) w.destroy()
w = new BrowserWindow({
show: false,
webPreferences: {
partition: partitionName
}
})
partitionProtocol.registerStringProtocol(protocolName, handler, (error) => {
2016-06-29 16:37:10 +00:00
done(error != null ? error : undefined)
})
})
afterEach((done) => {
partitionProtocol.unregisterProtocol(protocolName, () => done())
})
it('does not affect defaultSession', (done) => {
protocol.isProtocolHandled(protocolName, (result) => {
2018-09-13 16:10:51 +00:00
assert.strictEqual(result, false)
partitionProtocol.isProtocolHandled(protocolName, (result) => {
2018-09-13 16:10:51 +00:00
assert.strictEqual(result, true)
done()
})
})
})
xit('handles requests from partition', (done) => {
w.webContents.on('did-finish-load', () => done())
w.loadURL(`${protocolName}://fake-host`)
})
})
describe('ses.setProxy(options, callback)', () => {
let server = null
let customSession = null
beforeEach(() => {
customSession = session.fromPartition('proxyconfig')
})
afterEach(() => {
if (server) {
server.close()
}
if (customSession) {
customSession.destroy()
}
})
it('allows configuring proxy settings', (done) => {
2018-09-13 16:10:51 +00:00
const config = { proxyRules: 'http=myproxy:80' }
customSession.setProxy(config, () => {
customSession.resolveProxy('http://localhost', (proxy) => {
2018-09-13 16:10:51 +00:00
assert.strictEqual(proxy, 'PROXY myproxy:80')
done()
})
})
})
it('allows configuring proxy settings with pacScript', (done) => {
server = http.createServer((req, res) => {
const pac = `
function FindProxyForURL(url, host) {
return "PROXY myproxy:8132";
}
`
res.writeHead(200, {
'Content-Type': 'application/x-ns-proxy-autoconfig'
})
res.end(pac)
})
server.listen(0, '127.0.0.1', () => {
const config = { pacScript: `http://127.0.0.1:${server.address().port}` }
customSession.setProxy(config, () => {
customSession.resolveProxy('http://localhost', (proxy) => {
assert.strictEqual(proxy, 'PROXY myproxy:8132')
done()
})
})
})
})
it('allows bypassing proxy settings', (done) => {
const config = {
proxyRules: 'http=myproxy:80',
proxyBypassRules: '<local>'
}
customSession.setProxy(config, () => {
customSession.resolveProxy('http://localhost', (proxy) => {
2018-09-13 16:10:51 +00:00
assert.strictEqual(proxy, 'DIRECT')
done()
})
})
})
})
2016-08-23 05:59:21 +00:00
describe('ses.getBlobData(identifier, callback)', () => {
it('returns blob data for uuid', (done) => {
2016-08-23 05:59:21 +00:00
const scheme = 'temp'
const protocol = session.defaultSession.protocol
const url = `${scheme}://host`
before(() => {
2016-08-23 05:59:21 +00:00
if (w != null) w.destroy()
2018-09-13 16:10:51 +00:00
w = new BrowserWindow({ show: false })
2016-08-23 05:59:21 +00:00
})
after((done) => {
2016-08-23 05:59:21 +00:00
protocol.unregisterProtocol(scheme, () => {
closeWindow(w).then(() => {
w = null
done()
})
})
})
const postData = JSON.stringify({
type: 'blob',
value: 'hello'
})
const content = `<html>
<script>
const {webFrame} = require('electron')
webFrame.registerURLSchemeAsPrivileged('${scheme}')
let fd = new FormData();
fd.append('file', new Blob(['${postData}'], {type:'application/json'}));
fetch('${url}', {method:'POST', body: fd });
</script>
</html>`
protocol.registerStringProtocol(scheme, (request, callback) => {
2016-08-23 05:59:21 +00:00
if (request.method === 'GET') {
2018-09-13 16:10:51 +00:00
callback({ data: content, mimeType: 'text/html' })
2016-08-23 05:59:21 +00:00
} else if (request.method === 'POST') {
const uuid = request.uploadData[1].blobUUID
2016-08-23 05:59:21 +00:00
assert(uuid)
session.defaultSession.getBlobData(uuid, (result) => {
2018-09-13 16:10:51 +00:00
assert.strictEqual(result.toString(), postData)
2016-08-23 05:59:21 +00:00
done()
})
}
}, (error) => {
2016-08-23 05:59:21 +00:00
if (error) return done(error)
w.loadURL(url)
})
})
})
describe('ses.setCertificateVerifyProc(callback)', () => {
let server = null
beforeEach((done) => {
const certPath = path.join(__dirname, 'fixtures', 'certificates')
const options = {
key: fs.readFileSync(path.join(certPath, 'server.key')),
cert: fs.readFileSync(path.join(certPath, 'server.pem')),
ca: [
fs.readFileSync(path.join(certPath, 'rootCA.pem')),
fs.readFileSync(path.join(certPath, 'intermediateCA.pem'))
],
requestCert: true,
rejectUnauthorized: false
}
server = https.createServer(options, (req, res) => {
res.writeHead(200)
res.end('<title>hello</title>')
})
server.listen(0, '127.0.0.1', done)
})
afterEach(() => {
session.defaultSession.setCertificateVerifyProc(null)
server.close()
})
it('accepts the request when the callback is called with 0', (done) => {
2018-09-13 16:10:51 +00:00
session.defaultSession.setCertificateVerifyProc(({ hostname, certificate, verificationResult, errorCode }, callback) => {
2017-02-08 21:33:07 +00:00
assert(['net::ERR_CERT_AUTHORITY_INVALID', 'net::ERR_CERT_COMMON_NAME_INVALID'].includes(verificationResult), verificationResult)
assert([-202, -200].includes(errorCode), errorCode)
callback(0)
})
w.webContents.once('did-finish-load', () => {
2018-09-13 16:10:51 +00:00
assert.strictEqual(w.webContents.getTitle(), 'hello')
done()
})
w.loadURL(`https://127.0.0.1:${server.address().port}`)
})
it('rejects the request when the callback is called with -2', (done) => {
2018-09-13 16:10:51 +00:00
session.defaultSession.setCertificateVerifyProc(({ hostname, certificate, verificationResult }, callback) => {
assert.strictEqual(hostname, '127.0.0.1')
assert.strictEqual(certificate.issuerName, 'Intermediate CA')
assert.strictEqual(certificate.subjectName, 'localhost')
assert.strictEqual(certificate.issuer.commonName, 'Intermediate CA')
assert.strictEqual(certificate.subject.commonName, 'localhost')
assert.strictEqual(certificate.issuerCert.issuer.commonName, 'Root CA')
assert.strictEqual(certificate.issuerCert.subject.commonName, 'Intermediate CA')
assert.strictEqual(certificate.issuerCert.issuerCert.issuer.commonName, 'Root CA')
assert.strictEqual(certificate.issuerCert.issuerCert.subject.commonName, 'Root CA')
assert.strictEqual(certificate.issuerCert.issuerCert.issuerCert, undefined)
2017-02-08 21:33:07 +00:00
assert(['net::ERR_CERT_AUTHORITY_INVALID', 'net::ERR_CERT_COMMON_NAME_INVALID'].includes(verificationResult), verificationResult)
callback(-2)
})
const url = `https://127.0.0.1:${server.address().port}`
w.webContents.once('did-finish-load', () => {
2018-09-13 16:10:51 +00:00
assert.strictEqual(w.webContents.getTitle(), url)
done()
})
w.loadURL(url)
})
})
2016-11-24 15:16:39 +00:00
describe('ses.createInterruptedDownload(options)', () => {
it('can create an interrupted download item', (done) => {
2016-11-24 15:16:39 +00:00
ipcRenderer.sendSync('set-download-option', true, false)
const filePath = path.join(__dirname, 'fixtures', 'mock.pdf')
const options = {
path: filePath,
urlChain: ['http://127.0.0.1/'],
2016-11-24 15:16:39 +00:00
mimeType: 'application/pdf',
offset: 0,
length: 5242880
}
w.webContents.session.createInterruptedDownload(options)
ipcRenderer.once('download-created', (event, state, urlChain,
2018-09-13 16:10:51 +00:00
mimeType, receivedBytes,
totalBytes, filename,
savePath) => {
assert.strictEqual(state, 'interrupted')
assert.deepStrictEqual(urlChain, ['http://127.0.0.1/'])
assert.strictEqual(mimeType, 'application/pdf')
assert.strictEqual(receivedBytes, 0)
assert.strictEqual(totalBytes, 5242880)
assert.strictEqual(savePath, filePath)
2016-11-24 15:16:39 +00:00
done()
})
})
it('can be resumed', (done) => {
2016-11-24 15:16:39 +00:00
const fixtures = path.join(__dirname, 'fixtures')
const downloadFilePath = path.join(fixtures, 'logo.png')
const rangeServer = http.createServer((req, res) => {
const options = { root: fixtures }
2016-11-24 15:16:39 +00:00
send(req, req.url, options)
2018-09-13 16:10:51 +00:00
.on('error', (error) => { done(error) }).pipe(res)
2016-11-24 15:16:39 +00:00
})
ipcRenderer.sendSync('set-download-option', true, false, downloadFilePath)
rangeServer.listen(0, '127.0.0.1', () => {
2016-11-24 15:16:39 +00:00
const port = rangeServer.address().port
const downloadUrl = `http://127.0.0.1:${port}/assets/logo.png`
const callback = (event, state, url, mimeType,
2018-09-13 16:10:51 +00:00
receivedBytes, totalBytes, disposition,
filename, savePath, urlChain,
lastModifiedTime, eTag) => {
2016-11-24 15:16:39 +00:00
if (state === 'cancelled') {
const options = {
path: savePath,
urlChain: urlChain,
mimeType: mimeType,
offset: receivedBytes,
length: totalBytes,
lastModified: lastModifiedTime,
eTag: eTag
}
ipcRenderer.sendSync('set-download-option', false, false, downloadFilePath)
w.webContents.session.createInterruptedDownload(options)
} else {
2018-09-13 16:10:51 +00:00
assert.strictEqual(state, 'completed')
assert.strictEqual(filename, 'logo.png')
assert.strictEqual(savePath, downloadFilePath)
assert.strictEqual(url, downloadUrl)
assert.strictEqual(mimeType, 'image/png')
assert.strictEqual(receivedBytes, 14022)
assert.strictEqual(totalBytes, 14022)
2016-11-24 15:16:39 +00:00
assert(fs.existsSync(downloadFilePath))
fs.unlinkSync(downloadFilePath)
rangeServer.close()
ipcRenderer.removeListener('download-done', callback)
done()
}
}
ipcRenderer.on('download-done', callback)
w.webContents.downloadURL(downloadUrl)
})
})
})
2016-11-30 20:02:17 +00:00
describe('ses.clearAuthCache(options[, callback])', () => {
it('can clear http auth info from cache', (done) => {
2016-11-30 20:02:17 +00:00
const ses = session.fromPartition('auth-cache')
const server = http.createServer((req, res) => {
const credentials = auth(req)
2016-11-30 20:02:17 +00:00
if (!credentials || credentials.name !== 'test' || credentials.pass !== 'test') {
res.statusCode = 401
res.setHeader('WWW-Authenticate', 'Basic realm="Restricted"')
res.end()
} else {
2016-12-01 12:40:02 +00:00
res.end('authenticated')
2016-11-30 20:02:17 +00:00
}
})
server.listen(0, '127.0.0.1', () => {
2016-11-30 20:02:17 +00:00
const port = server.address().port
function issueLoginRequest (attempt = 1) {
if (attempt > 2) {
server.close()
return done()
}
const request = net.request({
url: `http://127.0.0.1:${port}`,
session: ses
})
request.on('login', (info, callback) => {
attempt += 1
2018-09-13 16:10:51 +00:00
assert.strictEqual(info.scheme, 'basic')
assert.strictEqual(info.realm, 'Restricted')
2016-11-30 20:02:17 +00:00
callback('test', 'test')
})
request.on('response', (response) => {
2016-11-30 20:02:17 +00:00
let data = ''
2016-12-01 12:40:02 +00:00
response.pause()
response.on('data', (chunk) => {
2016-11-30 20:02:17 +00:00
data += chunk
})
response.on('end', () => {
2018-09-13 16:10:51 +00:00
assert.strictEqual(data, 'authenticated')
ses.clearAuthCache({ type: 'password' }, () => {
2016-11-30 20:02:17 +00:00
issueLoginRequest(attempt)
})
})
response.on('error', (error) => { done(error) })
2016-12-01 12:40:02 +00:00
response.resume()
2016-11-30 20:02:17 +00:00
})
// Internal api to bypass cache for testing.
request.urlRequest._setLoadFlags(1 << 1)
request.end()
}
issueLoginRequest()
})
})
})
describe('ses.setPermissionRequestHandler(handler)', () => {
it('cancels any pending requests when cleared', (done) => {
const ses = session.fromPartition('permissionTest')
ses.setPermissionRequestHandler(() => {
ses.setPermissionRequestHandler(null)
})
webview = new WebView()
webview.addEventListener('ipc-message', (e) => {
2018-09-13 16:10:51 +00:00
assert.strictEqual(e.channel, 'message')
assert.deepStrictEqual(e.args, ['SecurityError'])
done()
})
webview.src = `file://${fixtures}/pages/permissions/midi-sysex.html`
webview.partition = 'permissionTest'
webview.setAttribute('nodeintegration', 'on')
document.body.appendChild(webview)
})
})
2016-03-25 20:03:49 +00:00
})