fix: pass postData to new-window event (#28513)
This commit is contained in:
parent
641e9337f3
commit
77dcf1020a
5 changed files with 87 additions and 19 deletions
|
@ -1,6 +1,6 @@
|
||||||
# UploadFile Object
|
# UploadFile Object
|
||||||
|
|
||||||
* `type` String - `file`.
|
* `type` 'file' - `file`.
|
||||||
* `filePath` String - Path of file to be uploaded.
|
* `filePath` String - Path of file to be uploaded.
|
||||||
* `offset` Integer - Defaults to `0`.
|
* `offset` Integer - Defaults to `0`.
|
||||||
* `length` Integer - Number of bytes to read from `offset`.
|
* `length` Integer - Number of bytes to read from `offset`.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# UploadRawData Object
|
# UploadRawData Object
|
||||||
|
|
||||||
* `type` String - `rawData`.
|
* `type` 'rawData' - `rawData`.
|
||||||
* `bytes` Buffer - Data to be uploaded.
|
* `bytes` Buffer - Data to be uploaded.
|
||||||
|
|
|
@ -56,6 +56,7 @@ export function openGuestWindow ({ event, embedder, guest, referrer, disposition
|
||||||
windowOpenArgs,
|
windowOpenArgs,
|
||||||
additionalFeatures,
|
additionalFeatures,
|
||||||
disposition,
|
disposition,
|
||||||
|
postData,
|
||||||
referrer
|
referrer
|
||||||
});
|
});
|
||||||
if (didCancelEvent) return;
|
if (didCancelEvent) return;
|
||||||
|
@ -148,7 +149,7 @@ function emitDeprecatedNewWindowEvent ({ event, embedder, guest, windowOpenArgs,
|
||||||
const isWebViewWithPopupsDisabled = embedder.getType() === 'webview' && embedder.getLastWebPreferences().disablePopups;
|
const isWebViewWithPopupsDisabled = embedder.getType() === 'webview' && embedder.getLastWebPreferences().disablePopups;
|
||||||
const postBody = postData ? {
|
const postBody = postData ? {
|
||||||
data: postData,
|
data: postData,
|
||||||
headers: formatPostDataHeaders(postData as Electron.UploadRawData[])
|
...parseContentTypeFormat(postData)
|
||||||
} : null;
|
} : null;
|
||||||
|
|
||||||
embedder.emit(
|
embedder.emit(
|
||||||
|
@ -277,22 +278,40 @@ function getDeprecatedInheritedOptions (embedder: WebContents) {
|
||||||
return inheritableOptions;
|
return inheritableOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatPostDataHeaders (postData: Electron.UploadRawData[]) {
|
function formatPostDataHeaders (postData: PostData) {
|
||||||
if (!postData) return;
|
if (!postData) return;
|
||||||
|
|
||||||
let extraHeaders = 'content-type: application/x-www-form-urlencoded';
|
const { contentType, boundary } = parseContentTypeFormat(postData);
|
||||||
|
if (boundary != null) { return `content-type: ${contentType}; boundary=${boundary}`; }
|
||||||
|
|
||||||
if (postData.length > 0) {
|
return `content-type: ${contentType}`;
|
||||||
const postDataFront = postData[0].bytes.toString();
|
|
||||||
const boundary = /^--.*[^-\r\n]/.exec(
|
|
||||||
postDataFront
|
|
||||||
);
|
|
||||||
if (boundary != null) {
|
|
||||||
extraHeaders = `content-type: multipart/form-data; boundary=${boundary[0].substr(
|
|
||||||
2
|
|
||||||
)}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return extraHeaders;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const MULTIPART_CONTENT_TYPE = 'multipart/form-data';
|
||||||
|
const URL_ENCODED_CONTENT_TYPE = 'application/x-www-form-urlencoded';
|
||||||
|
|
||||||
|
// Figure out appropriate headers for post data.
|
||||||
|
const parseContentTypeFormat = function (postData: Exclude<PostData, undefined>) {
|
||||||
|
if (postData.length) {
|
||||||
|
if (postData[0].type === 'rawData') {
|
||||||
|
// For multipart forms, the first element will start with the boundary
|
||||||
|
// notice, which looks something like `------WebKitFormBoundary12345678`
|
||||||
|
// Note, this regex would fail when submitting a urlencoded form with an
|
||||||
|
// input attribute of name="--theKey", but, uhh, don't do that?
|
||||||
|
const postDataFront = postData[0].bytes.toString();
|
||||||
|
const boundary = /^--.*[^-\r\n]/.exec(postDataFront);
|
||||||
|
if (boundary) {
|
||||||
|
return {
|
||||||
|
boundary: boundary[0].substr(2),
|
||||||
|
contentType: MULTIPART_CONTENT_TYPE
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Either the form submission didn't contain any inputs (the postData array
|
||||||
|
// was empty), or we couldn't find the boundary and thus we can assume this is
|
||||||
|
// a key=value style form.
|
||||||
|
return {
|
||||||
|
contentType: URL_ENCODED_CONTENT_TYPE
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
|
@ -62,7 +62,7 @@ export function parseCommaSeparatedKeyValue (source: string, useSoonToBeDeprecat
|
||||||
for (const keyValuePair of source.split(',')) {
|
for (const keyValuePair of source.split(',')) {
|
||||||
const [key, value] = keyValuePair.split('=').map(str => str.trim());
|
const [key, value] = keyValuePair.split('=').map(str => str.trim());
|
||||||
if (useSoonToBeDeprecatedBehaviorForBareKeys && value === undefined) {
|
if (useSoonToBeDeprecatedBehaviorForBareKeys && value === undefined) {
|
||||||
bareKeys.push(key);
|
if (key) { bareKeys.push(key); }
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
parsed[key] = coerce(key, value);
|
parsed[key] = coerce(key, value);
|
||||||
|
|
|
@ -6,7 +6,7 @@ import * as os from 'os';
|
||||||
import * as qs from 'querystring';
|
import * as qs from 'querystring';
|
||||||
import * as http from 'http';
|
import * as http from 'http';
|
||||||
import { AddressInfo } from 'net';
|
import { AddressInfo } from 'net';
|
||||||
import { app, BrowserWindow, BrowserView, ipcMain, OnBeforeSendHeadersListenerDetails, protocol, screen, webContents, session, WebContents } from 'electron/main';
|
import { app, BrowserWindow, BrowserView, ipcMain, OnBeforeSendHeadersListenerDetails, protocol, screen, webContents, session, WebContents, BrowserWindowConstructorOptions } from 'electron/main';
|
||||||
|
|
||||||
import { emittedOnce, emittedUntil } from './events-helpers';
|
import { emittedOnce, emittedUntil } from './events-helpers';
|
||||||
import { ifit, ifdescribe, defer, delay } from './spec-helpers';
|
import { ifit, ifdescribe, defer, delay } from './spec-helpers';
|
||||||
|
@ -3047,6 +3047,55 @@ describe('BrowserWindow module', () => {
|
||||||
});
|
});
|
||||||
w.loadFile(path.join(fixtures, 'pages', 'target-name.html'));
|
w.loadFile(path.join(fixtures, 'pages', 'target-name.html'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('includes all properties', async () => {
|
||||||
|
const w = new BrowserWindow({ show: false });
|
||||||
|
|
||||||
|
const p = new Promise<{
|
||||||
|
url: string,
|
||||||
|
frameName: string,
|
||||||
|
disposition: string,
|
||||||
|
options: BrowserWindowConstructorOptions,
|
||||||
|
additionalFeatures: string[],
|
||||||
|
referrer: Electron.Referrer,
|
||||||
|
postBody: Electron.PostBody
|
||||||
|
}>((resolve) => {
|
||||||
|
w.webContents.once('new-window', (e, url, frameName, disposition, options, additionalFeatures, referrer, postBody) => {
|
||||||
|
e.preventDefault();
|
||||||
|
resolve({ url, frameName, disposition, options, additionalFeatures, referrer, postBody });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
w.loadURL(`data:text/html,${encodeURIComponent(`
|
||||||
|
<form target="_blank" method="POST" id="form" action="http://example.com/test">
|
||||||
|
<input type="text" name="post-test-key" value="post-test-value"></input>
|
||||||
|
</form>
|
||||||
|
<script>form.submit()</script>
|
||||||
|
`)}`);
|
||||||
|
const { url, frameName, disposition, options, additionalFeatures, referrer, postBody } = await p;
|
||||||
|
expect(url).to.equal('http://example.com/test');
|
||||||
|
expect(frameName).to.equal('');
|
||||||
|
expect(disposition).to.equal('foreground-tab');
|
||||||
|
expect(options).to.deep.equal({
|
||||||
|
show: true,
|
||||||
|
width: 800,
|
||||||
|
height: 600,
|
||||||
|
webPreferences: {
|
||||||
|
contextIsolation: true,
|
||||||
|
nodeIntegration: false,
|
||||||
|
webviewTag: false,
|
||||||
|
nodeIntegrationInSubFrames: false,
|
||||||
|
openerId: options.webPreferences!.openerId
|
||||||
|
},
|
||||||
|
webContents: undefined
|
||||||
|
});
|
||||||
|
expect(referrer.policy).to.equal('strict-origin-when-cross-origin');
|
||||||
|
expect(referrer.url).to.equal('');
|
||||||
|
expect(additionalFeatures).to.deep.equal([]);
|
||||||
|
expect(postBody.data).to.have.length(1);
|
||||||
|
expect(postBody.data[0].type).to.equal('rawData');
|
||||||
|
expect(postBody.data[0].bytes).to.deep.equal(Buffer.from('post-test-key=post-test-value'));
|
||||||
|
expect(postBody.contentType).to.equal('application/x-www-form-urlencoded');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
ifdescribe(process.platform !== 'linux')('max/minimize events', () => {
|
ifdescribe(process.platform !== 'linux')('max/minimize events', () => {
|
||||||
|
|
Loading…
Reference in a new issue