Selaa lähdekoodia

added support of same-origin policy

Former-commit-id: 761f7ae8e4f361ddb1fbbd3545a7d0ca2eee5dd5
Gildas 6 vuotta sitten
vanhempi
sitoutus
aaa84b728c

+ 4 - 1
extension/core/content/content-main.js

@@ -31,7 +31,10 @@ this.singlefile.extension.core.content.main = this.singlefile.extension.core.con
 
 	let ui, processing = false, processor;
 
-	singlefile.lib.main.init({ fetch: singlefile.extension.lib.fetch.content.resources.fetch });
+	singlefile.lib.main.init({
+		fetch: singlefile.extension.lib.fetch.content.resources.fetch,
+		frameFetch: singlefile.extension.lib.fetch.content.resources.frameFetch
+	});
 	browser.runtime.onMessage.addListener(async message => {
 		if (!ui) {
 			ui = singlefile.extension.ui.content.main;

+ 10 - 3
extension/lib/fetch/bg/fetch-resources.js

@@ -29,10 +29,10 @@ singlefile.extension.lib.fetch.bg.resources = (() => {
 
 	let requestId = 1;
 
-	browser.runtime.onMessage.addListener(message => {
+	browser.runtime.onMessage.addListener((message, sender) => {
 		if (message.method.startsWith("fetch")) {
 			return new Promise(resolve => {
-				onRequest(message)
+				onRequest(message, sender)
 					.then(resolve)
 					.catch(error => resolve({ error: error.toString() }));
 			});
@@ -40,7 +40,7 @@ singlefile.extension.lib.fetch.bg.resources = (() => {
 	});
 	return {};
 
-	async function onRequest(message) {
+	async function onRequest(message, sender) {
 		if (message.method == "fetch") {
 			const responseId = requestId;
 			requestId = requestId + 1;
@@ -59,6 +59,13 @@ singlefile.extension.lib.fetch.bg.resources = (() => {
 					response.xhrRequest.onload = () => resolve(getResponse(response.xhrRequest));
 				}
 			});
+		} else if (message.method == "fetch.frame") {
+			const response = await browser.tabs.sendMessage(sender.tab.id, message);
+			if (response.error) {
+				throw response.error;
+			} else {
+				return response;
+			}
 		}
 	}
 

+ 30 - 1
extension/lib/fetch/content/content-fetch-resources.js

@@ -21,13 +21,34 @@
  *   Source.
  */
 
-/* global browser, addEventListener, fetch, CustomEvent, dispatchEvent, removeEventListener */
+/* global browser, window, addEventListener, fetch, CustomEvent, dispatchEvent, removeEventListener */
 
 this.singlefile.extension.lib.fetch.content.resources = this.singlefile.extension.lib.fetch.content.resources || (() => {
 
 	const FETCH_REQUEST_EVENT = "single-file-request-fetch";
 	const FETCH_RESPONSE_EVENT = "single-file-response-fetch";
 
+
+	browser.runtime.onMessage.addListener(async message => {
+		if (message.method == "fetch.frame" && window.frameId && window.frameId == message.frameId) {
+			try {
+				let response = await fetch(message.url, { cache: "force-cache" });
+				if (response.status == 403) {
+					response = hostFetch(message.url);
+				}
+				return {
+					status: response.status,
+					headers: Array.from(response.headers),
+					array: Array.from(new Uint8Array(await response.arrayBuffer()))
+				};
+			} catch (error) {
+				return {
+					error: error.toString()
+				};
+			}
+		}
+	});
+
 	return {
 		fetch: async url => {
 			try {
@@ -48,6 +69,14 @@ this.singlefile.extension.lib.fetch.content.resources = this.singlefile.extensio
 					}
 				};
 			}
+		},
+		frameFetch: async (url, frameId) => {
+			const response = await sendMessage({ method: "fetch.frame", url, frameId });
+			return {
+				status: response.status,
+				headers: { get: headerName => response.headers[headerName] },
+				arrayBuffer: async () => new Uint8Array(response.array).buffer
+			};
 		}
 	};
 

+ 2 - 2
lib/frame-tree/content/content-frame-tree.js

@@ -43,7 +43,7 @@ this.singlefile.lib.frameTree.content.frames = this.singlefile.lib.frameTree.con
 	const addEventListener = window.addEventListener;
 	const top = window.top;
 	const MessageChannel = window.MessageChannel;
-	const document = window.document;	
+	const document = window.document;
 	const setTimeout = window.setTimeout;
 
 	const sessions = new Map();
@@ -106,7 +106,7 @@ this.singlefile.lib.frameTree.content.frames = this.singlefile.lib.frameTree.con
 	function initRequest(message) {
 		const sessionId = message.sessionId;
 		if (!TOP_WINDOW) {
-			windowId = message.windowId;
+			windowId = window.frameId = message.windowId;
 		}
 		processFrames(document, message.options, windowId, sessionId);
 		if (!TOP_WINDOW) {

+ 12 - 6
lib/single-file/single-file-core.js

@@ -340,7 +340,8 @@ this.singlefile.lib.core = this.singlefile.lib.core || (() => {
 					const content = await util.getContent(resourceURL, {
 						asBinary,
 						maxResourceSize: options.maxResourceSize,
-						maxResourceSizeEnabled: options.maxResourceSizeEnabled
+						maxResourceSizeEnabled: options.maxResourceSizeEnabled,
+						frameId: options.windowId
 					});
 					indexResource = indexResource + 1;
 					onloadListener({ url: resourceURL });
@@ -416,7 +417,8 @@ this.singlefile.lib.core = this.singlefile.lib.core || (() => {
 				content = await util.getContent(this.baseURI, {
 					maxResourceSize: this.options.maxResourceSize,
 					maxResourceSizeEnabled: this.options.maxResourceSizeEnabled,
-					charset
+					charset,
+					frameId: this.options.windowId
 				});
 				pageContent = content.data;
 			}
@@ -834,7 +836,8 @@ this.singlefile.lib.core = this.singlefile.lib.core || (() => {
 				charset: this.charset,
 				compressCSS: this.options.compressCSS,
 				updatedResources: this.options.updatedResources,
-				rootDocument: this.options.rootDocument
+				rootDocument: this.options.rootDocument,
+				frameId: this.options.windowId
 			};
 			await Promise.all(Array.from(this.doc.querySelectorAll("style, link[rel*=stylesheet]"))
 				.map(async element => {
@@ -1118,7 +1121,8 @@ this.singlefile.lib.core = this.singlefile.lib.core || (() => {
 					const content = await util.getContent(resourceURL, {
 						asBinary: true,
 						maxResourceSize: this.options.maxResourceSize,
-						maxResourceSizeEnabled: this.options.maxResourceSizeEnabled
+						maxResourceSizeEnabled: this.options.maxResourceSizeEnabled,
+						frameId: this.options.windowId
 					});
 					content.data = Util.getUpdatedResourceContent(resourceURL, content, this.options);
 					scriptElement.setAttribute("src", content.data);
@@ -1442,7 +1446,8 @@ this.singlefile.lib.core = this.singlefile.lib.core || (() => {
 							const content = await util.getContent(resourceURL, {
 								maxResourceSize: options.maxResourceSize,
 								maxResourceSizeEnabled: options.maxResourceSizeEnabled,
-								validateTextContentType: true
+								validateTextContentType: true,
+								frameId: options.windowId
 							});
 							resourceURL = content.resourceURL;
 							content.data = Util.getUpdatedResourceContent(resourceURL, content, options);
@@ -1511,7 +1516,8 @@ this.singlefile.lib.core = this.singlefile.lib.core || (() => {
 				const content = await util.getContent(resourceURL, {
 					maxResourceSize: options.maxResourceSize,
 					maxResourceSizeEnabled: options.maxResourceSizeEnabled,
-					charset: options.charset
+					charset: options.charset,
+					frameId: options.windowId
 				});
 				resourceURL = content.resourceURL;
 				content.data = Util.getUpdatedResourceContent(content.resourceURL, content, options);

+ 7 - 1
lib/single-file/single-file-util.js

@@ -69,6 +69,7 @@ this.singlefile.lib.util = this.singlefile.lib.util || (() => {
 
 			utilOptions = utilOptions || {};
 			utilOptions.fetch = utilOptions.fetch || fetch;
+			utilOptions.frameFetch = utilOptions.frameFetch || utilOptions.fetch || fetch;
 			return {
 				getContent,
 				parseURL(resourceURL, baseURI) {
@@ -196,12 +197,17 @@ this.singlefile.lib.util = this.singlefile.lib.util || (() => {
 			async function getContent(resourceURL, options) {
 				let response, startTime;
 				const fetchResource = utilOptions.fetch;
+				const fetchFrameResource = utilOptions.frameFetch;
 				if (DEBUG) {
 					startTime = Date.now();
 					log("  // STARTED download url =", resourceURL, "asBinary =", options.asBinary);
 				}
 				try {
-					response = await fetchResource(resourceURL);
+					if (options.frameId) {
+						response = await fetchFrameResource(resourceURL, options.frameId);
+					} else {
+						response = await fetchResource(resourceURL);
+					}
 				} catch (error) {
 					return { data: options.asBinary ? "data:base64," : "", resourceURL };
 				}