Skip to content

Commit

Permalink
fix(mitm): double-headers
Browse files Browse the repository at this point in the history
  • Loading branch information
blakebyrnes committed Apr 1, 2022
1 parent a4f79cd commit a424c61
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 17 deletions.
6 changes: 2 additions & 4 deletions core/lib/InjectedScripts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,12 @@ export default class InjectedScripts {
return puppetPage.addNewDocumentScript(showInteractionScript, true);
}

public static getIndexedDbStorageRestoreScript(restoreDBs: IIndexedDB[]): string {
public static getIndexedDbStorageRestoreScript(): string {
return `(function restoreIndexedDB(dbs) {
const exports = {}; // workaround for ts adding an exports variable
${stringifiedTypeSerializerClass};
${pageScripts.indexedDbRestore};
restoreUserStorage(dbs);
})(${JSON.stringify(restoreDBs)});`;

})();`;
}
}
42 changes: 32 additions & 10 deletions core/lib/UserProfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,15 @@ export default class UserProfile {

public static async installStorage(session: Session, page: IPuppetPage): Promise<void> {
const { userProfile } = session;
const domStorage = userProfile.storage;
if (!domStorage) return;
const sessionId = session.id;
const origins = Object.keys(domStorage);

const domStorage: IDomStorage = {};
const origins: string[] = [];
for (const [origin, storage] of Object.entries(userProfile.storage)) {
const og = origin.toLowerCase();
origins.push(og);
domStorage[og] = storage;
}
if (!origins.length) return;
const sessionId = session.id;

const interceptorHandlers = session.mitmRequestSession.interceptorHandlers;

Expand Down Expand Up @@ -109,12 +112,19 @@ for (const [key,value] of ${JSON.stringify(localStorage)}) {
}\n`;
}

if (originStorage?.indexedDB) {
let readyClass = 'ready';
if (originStorage?.indexedDB?.length) {
readyClass ='';
script += `\n\n
${InjectedScripts.getIndexedDbStorageRestoreScript(originStorage.indexedDB)}`;
${InjectedScripts.getIndexedDbStorageRestoreScript()}
const dbs = ${JSON.stringify(originStorage.indexedDB)};
restoreUserStorage(dbs).then(() => {
document.body.setAttribute('class', 'ready');
});`;
}

res.end(`<html><body>
res.end(`<html><body class="${readyClass}">
<h5>${url.origin}</h5>
<script>
${script}
Expand All @@ -138,12 +148,24 @@ ${origins.map(x => `<iframe src="${x}"></iframe>`).join('\n')}
for (const frame of page.frames) {
if (frame === page.mainFrame) {
// no loader is set, so need to have special handling
if (!page.mainFrame.activeLoader.lifecycle.load) {
await page.mainFrame.waitOn('frame-lifecycle', x => x.name === 'load');
if (!frame.activeLoader.lifecycle.load) {
await frame.waitOn('frame-lifecycle', x => x.name === 'load');
}
continue;
}
await frame.waitForLifecycleEvent('load');

await frame.evaluate(
`(async function() {
while (!document.querySelector("body.ready")) {
await new Promise(resolve => setTimeout(resolve, 20));
}
})()`,
true,
{
shouldAwaitExpression: true,
},
);
}
} finally {
session.mitmRequestSession.interceptorHandlers = interceptorHandlers;
Expand Down
4 changes: 2 additions & 2 deletions core/test/user-profile.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ document.querySelector('#session').innerHTML = [session1,session2,session3].join
},
};
for (let i = 0; i < 100; i += 1) {
storage[`https://domain${i}.com`] = {
storage[`https://${(i === 1 ? 'D' : 'd')}omain${i}.com`] = {
indexedDB: [],
localStorage: [
['1', '2'],
Expand Down Expand Up @@ -324,7 +324,7 @@ localStorage.setItem('Test1', 'value1');
localStorage: [['test', 'site1.org']],
sessionStorage: [],
},
'https://site2.org': {
'https://SITE2.org': {
indexedDB: [],
localStorage: [['test2', 'site2.org']],
sessionStorage: [],
Expand Down
2 changes: 1 addition & 1 deletion mitm/handlers/HttpRequestHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,9 @@ export default class HttpRequestHandler extends BaseHttpHandler {
const { serverToProxyResponse, proxyToClientResponse, requestSession, events } = context;

proxyToClientResponse.statusCode = context.status;

// write individually so we properly write header-lists
for (const [key, value] of Object.entries(context.responseHeaders)) {
proxyToClientResponse.setHeader(key, value);
try {
proxyToClientResponse.setHeader(key, value);
} catch (error) {
Expand Down
3 changes: 3 additions & 0 deletions puppet-chrome/lib/Frame.ts
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,9 @@ export default class Frame extends TypedEventEmitter<IPuppetFrameEvents> impleme
private async createIsolatedWorld(): Promise<number> {
try {
if (!this.isAttached) return;
await new Promise(setImmediate);
if (this.isolatedContextId) return this.isolatedContextId;

const isolatedWorld = await this.devtoolsSession.send(
'Page.createIsolatedWorld',
{
Expand Down

0 comments on commit a424c61

Please sign in to comment.