Browse Source

Finalized browser proxy rewrite feature

Toby Chui 3 years ago
parent
commit
d1ea78d60c
3 changed files with 107 additions and 10 deletions
  1. 13 0
      web/Browser/functions/getTitle.js
  2. 50 6
      web/Browser/functions/proxy.js
  3. 44 4
      web/Browser/index.html

+ 13 - 0
web/Browser/functions/getTitle.js

@@ -0,0 +1,13 @@
+/*
+    getTitle.js
+    Get the title of the page
+*/  
+
+requirelib("http");
+var pageContent = http.get(url);
+var matches = pageContent.match(/<title>(.*?)<\/title>/);
+if (matches == null || matches.length == 0){
+    sendResp("");
+}else{
+    sendResp(matches[0].replace(/(<([^>]+)>)/gi, ""));
+}

+ 50 - 6
web/Browser/functions/proxy.js

@@ -6,14 +6,58 @@
 //Get the target webpage body
 requirelib("http");
 var websiteContent = http.get(url);
-var rootURL = url.split("/");
-rootURL.pop();
-rootURL = rootURL.join("/");
+var protocol = url.substring(0, url.indexOf("/") + 2);
+var domain = url.substring(url.indexOf("/") + 2).split("/").shift();
+rootURL = protocol + domain;
 
 
-//replace the relative path files with absolutes
-websiteContent = websiteContent.split('src="/').join('src="' + rootURL + '/');
-websiteContent = websiteContent.split('href="/').join('href="' + rootURL + '/');
+var currentDirUrl = url;
+currentDirUrl = currentDirUrl.split("?")[0];
+var lastSegment = currentDirUrl.split("/").pop();
+if (lastSegment.indexOf(".") >= 0){
+    //Contain filename. Pop the filename as well
+    currentDirUrl = currentDirUrl.split("/");
+    currentDirUrl.pop();
+    currentDirUrl = currentDirUrl.join("/");
+}
+
+//Replace the src path with remote domain path
+var srcChunks = websiteContent.split('src="');
+var patchedSrcChunks = [srcChunks[0]];
+for (var i = 1; i < srcChunks.length; i++){
+    var thisChunk = srcChunks[i];
+    if (thisChunk.substr(0,1) == "/"){
+        //Inject the root URL in front
+        patchedSrcChunks.push(rootURL + "/" + thisChunk);
+    }else if (thisChunk.trim().substr(0,4) != "http" && thisChunk.trim().substr(0,5) != "data:"){
+        //Inject the current dir into it
+        patchedSrcChunks.push(currentDirUrl + "/" + thisChunk);
+    }else{
+        patchedSrcChunks.push(thisChunk);
+    }
+}
+websiteContent = patchedSrcChunks.join('src="');
+
+//Replace css url("xxx") if exists
+websiteContent = websiteContent.split('url("/').join("{url_root_dummy}");
+websiteContent = websiteContent.split('url("').join('url("' + currentDirUrl + "/");
+websiteContent = websiteContent.split('{url_root_dummy}').join('url("/' + rootURL + "/");
+
+var hrefChunks = websiteContent.split('href="');
+var patchedHrefChunks = [hrefChunks[0]];
+for (var j = 1; j < hrefChunks.length; j++){
+    var thisChunk = hrefChunks[j];
+    if (thisChunk.substr(0,1) == "/"){
+        //Inject the root URL in front
+        patchedHrefChunks.push(rootURL + "/" + thisChunk);
+    }else if (thisChunk.trim().substr(0,4) != "http"){
+        //Inject the current dir into it
+        patchedHrefChunks.push(currentDirUrl + "/" + thisChunk);
+    }else{
+        patchedHrefChunks.push(thisChunk);
+    }
+}
+websiteContent = patchedHrefChunks.join('href="');
 
 //Replace href with redirection code
 var htmlSegmentChunks = websiteContent.split(" ");

+ 44 - 4
web/Browser/index.html

@@ -68,10 +68,15 @@
 				padding: 0.4em;
 				display: none;
 			}
+
+			#toolbar.proxy{
+				border-bottom: 2px solid #41e8e5;
+			}
+
 		</style>
 	</head>
 	<body>
-		<div class="ui top small attached menu" style="background-color: #eceef2; padding-left: 12px; padding-right: 12px;">
+		<div id="toolbar" class="ui top small attached menu" style="background-color: #eceef2; padding-left: 12px; padding-right: 12px;">
 			<div class="ui menuitem">
 				<button class="ui circular tiny icon button" onclick="undoPage();">
 					<i class="arrow left icon"></i>
@@ -105,8 +110,8 @@
 					</button>
 				</div>
 				<div class="ui rightMenuItem">
-					<button class="ui tiny icon button">
-						<i class="grey download icon"></i>
+					<button class="ui tiny icon button" title="Open in new Window" onclick="openInNewWindow();">
+						<i class="grey external icon"></i>
 					</button>
 				</div>
 			</div>
@@ -185,6 +190,15 @@
 				loadWebsite(restorePage, false);
 			}
 
+			function openInNewWindow(){
+				window.open(currentURL);
+			}
+
+			function getTitleFromURL(url){
+				var title = targetURL.substr(targetURL.indexOf("/") + 2, targetURL.length);
+				return title;
+			}
+
 			function loadWebsite(targetURL, writeRestoreRecord = true){
 				if (writeRestoreRecord && currentURL != targetURL){
 					historyPopStack = [];
@@ -192,8 +206,10 @@
 				
 				//Handle special case
 				if (targetURL == "about:blank"){
+					$("#xframe").removeAttr("srcdoc");
 					$("#xframe").attr("src", "blank.html");
 					$("#urlText").val(targetURL);
+					$("#toolbar").removeClass("proxy");
 					if (writeRestoreRecord && currentURL != targetURL){
 						historyStack.push(JSON.parse(JSON.stringify(currentURL)));
 					}
@@ -234,11 +250,35 @@
 						if (allowIframe == true){
 							$("#xframe").removeAttr("srcdoc");
 							$("#xframe").attr("src", targetURL);
+							$("#toolbar").removeClass("proxy");
+							$("#xframe").on("load", function(){
+								//Get the page title
+								ao_module_agirun("Browser/functions/getTitle.js", {url: targetURL}, function(data){
+									if (data == ""){
+										let title = getTitleFromURL(targetURL);
+										ao_module_setWindowTitle(title);
+									}else{
+										ao_module_setWindowTitle(data);
+									}
+								});
+								$("#xframe").off("load");
+							});
 						}else{
 							proxyWebContent(targetURL, function(content){
 								$("#xframe").attr("src", "");
 								$("#xframe").attr("srcdoc", content);
-							
+								$("#toolbar").addClass("proxy");
+
+								//Extract the title
+								var matches = content.match(/<title>(.*?)<\/title>/);
+								if (matches == null){
+									let title = getTitleFromURL(targetURL);
+									ao_module_setWindowTitle(title);
+								}else{
+									var title = matches[0].replace(/(<([^>]+)>)/gi, "");
+									ao_module_setWindowTitle(title);
+								}
+    							
 							});
 							//alert("Target website do not allow embedding");
 						}