From f3af7ea6fc703cf7ab14dbb1d6714650eac3d415 Mon Sep 17 00:00:00 2001
From: didierfred <didierfred@gmail.com>
Date: Sat, 10 Mar 2018 22:43:50 +0100
Subject: [PATCH] add apply_on filter

---
 background.js     | 104 +++++++++++++++++++++++++++++++++++++++++-----
 popup/config.html |   1 +
 popup/config.js   |  37 +++++++++++------
 3 files changed, 119 insertions(+), 23 deletions(-)

diff --git a/background.js b/background.js
index 497d4c9..8a0579e 100644
--- a/background.js
+++ b/background.js
@@ -18,6 +18,15 @@ if (localStorage.getItem('config'))
 	{
 	console.log("Load standard config");
 	config= JSON.parse(localStorage.getItem('config'));
+	
+	// If config 1.0 (Simple Modify headers V1.2) , save to format 1.1	
+	if (config.version=="1.0") 
+		{
+		config.version="1.1";
+		for (var line of config.headers) line.apply_on="req";
+		console.log("save new config"+JSON.stringify(config));
+		localStorage.setItem("config",JSON.stringify(config));
+		}
 	}
 else 
 	{
@@ -29,9 +38,9 @@ else
 			var modifyTable=JSON.parse(localStorage.getItem("modifyTable"));
 			for (var to_modify of modifyTable)
 				{
-					headers.push({action:to_modify[0],header_name:to_modify[1],header_value:to_modify[2],comment:"",status:to_modify[3]});
+					headers.push({action:to_modify[0],header_name:to_modify[1],header_value:to_modify[2],comment:"",apply_on:"req",status:to_modify[3]});
 				}
-			config = {format_version:"1.0",target_page:localStorage.getItem('targetPage'),headers:headers};
+			config = {format_version:"1.1",target_page:localStorage.getItem('targetPage'),headers:headers};
 			// save old config in new format 
 			localStorage.setItem("config",JSON.stringify(config));
 		}
@@ -40,8 +49,8 @@ else
 		{
 				console.log("Load default config");
 				var headers = [];
-				headers.push({action:"add",header_name:"test_header_name",header_value:"test_header_value",comment:"test",status:"on"});
-				config = {format_version:"1.0",target_page:"https://httpbin.org/*",headers:headers};
+				headers.push({action:"add",header_name:"test_header_name",header_value:"test_header_value",comment:"test",apply_on:"req",status:"on"});
+				config = {format_version:"1.1",target_page:"https://httpbin.org/*",headers:headers};
 				// save configuration 
 				localStorage.setItem("config",JSON.stringify(config));
 		}
@@ -63,15 +72,15 @@ browser.runtime.onMessage.addListener(notify);
 
 
 /*
-* Rewrite the header (add , modify or delete)
+* Rewrite the request header (add , modify or delete)
 *
 */
-function rewriteHeader(e) 
+function rewriteRequestHeader(e) 
 {
 
   for (var to_modify of config.headers)
 	{
-		if (to_modify.status=="on")
+		if ((to_modify.status=="on")&&(to_modify.apply_on=="req"))
 			{
 			if (to_modify.action=="add")  
 				{
@@ -105,6 +114,50 @@ function rewriteHeader(e)
 }
 
 
+/*
+* Rewrite the response header (add , modify or delete)
+*
+*/
+function rewriteResponseHeader(e) 
+{
+//console.log("modify response header");
+  for (var to_modify of config.headers)
+	{
+		if ((to_modify.status=="on")&&(to_modify.apply_on=="res"))
+			{
+			if (to_modify.action=="add")  
+				{
+					var new_header = {"name" :to_modify.header_name,"value":to_modify.header_value};
+					e.responseHeaders.push(new_header);
+				}
+			else if (to_modify.action=="modify")
+				{
+				for (var header of e.responseHeaders) 
+					{
+					if (header.name.toLowerCase() == to_modify.header_name.toLowerCase()) header.value = to_modify.header_value;
+					}
+				}
+			else if (to_modify.action=="delete")
+				{
+				var index = -1;
+			
+				for (var i=0; i < e.responseHeaders.length; i++)
+					{
+				 	if (e.responseHeaders[i].name.toLowerCase() == to_modify.header_name.toLowerCase())  index=i;
+					}
+				if (index!=-1) 
+					{
+					e.responseHeaders.splice(index,1);	
+					}
+				}
+			}
+
+	}
+
+// console.log("response=" +JSON.stringify(e.responseHeaders));
+  return {responseHeaders: e.responseHeaders};
+}
+
 
 /*
 * Listen for message form config.js
@@ -120,14 +173,14 @@ function notify(message)
 		config=JSON.parse(localStorage.getItem("config"));
 		if (started=="on")
 			{		
-			browser.webRequest.onBeforeSendHeaders.removeListener(rewriteHeader);
+			removeListener();
 			addListener();
 			}
 		}
 
 	else if (message=="off")
 		{
-		browser.webRequest.onBeforeSendHeaders.removeListener(rewriteHeader);
+		removeListener();
 		browser.browserAction.setIcon({ path: "icons/modify-32.png"});
 		started="off";
 		}
@@ -141,7 +194,8 @@ function notify(message)
   	}
 
 /*
-* Add rewriteHeader as a listener to onBeforeSendHeaders, only for the target page.
+* Add rewriteRequestHeader as a listener to onBeforeSendHeaders, only for the target page.
+* Add rewriteResponseHeader as a listener to onHeadersReceived, only for the target page.
 * Make it "blocking" so we can modify the headers.
 */
 function addListener()
@@ -149,9 +203,37 @@ function addListener()
 	var target = config.target_page;
 	if ((target=="*")||(target=="")||(target==" ")) target="<all_urls>";
 	
-	browser.webRequest.onBeforeSendHeaders.addListener(rewriteHeader,
+	browser.webRequest.onBeforeSendHeaders.addListener(rewriteRequestHeader,
                                           {urls: [target]},
                                           ["blocking", "requestHeaders"]);
+
+	browser.webRequest.onHeadersReceived.addListener(rewriteResponseHeader,
+                                          {urls: [target]},
+                                          ["blocking", "responseHeaders"]);
+
+// for debug only
+	browser.webRequest.onCompleted.addListener(log_headers,
+                                          {urls: [target]},
+                                          ["responseHeaders"]);
+	}
+
+function log_headers(e)
+{
+console.log("response=" +JSON.stringify(e.responseHeaders));
+}
+
+
+
+/*
+* Remove the two listener 
+*
+*/
+function removeListener()
+	{
+	browser.webRequest.onBeforeSendHeaders.removeListener(rewriteRequestHeader);
+	browser.webRequest.onHeadersReceived.removeListener(rewriteResponseHeader);
+// for debug only
+	browser.webRequest.onCompleted.removeListener(log_headers);
 	}
 
 
diff --git a/popup/config.html b/popup/config.html
index 08b6a61..ad18d02 100644
--- a/popup/config.html
+++ b/popup/config.html
@@ -81,6 +81,7 @@
 		<td> Header Field Name </td>
 		<td> Header Field Value </td>
 		<td> Comment </td>
+		<td> Apply on </td>
 		<td> Status </td>
 	</tr>
   </table>
diff --git a/popup/config.js b/popup/config.js
index a5c8dba..0f3bf67 100644
--- a/popup/config.js
+++ b/popup/config.js
@@ -1,4 +1,4 @@
- 
+ 	
 
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -14,12 +14,14 @@ var started = "off";
 
 window.onload = function() {
 	// load configuration from local storage
-	var config = JSON.parse(localStorage.getItem("config"));	
-	for (var to_add of config.headers) appendLine(to_add.action,to_add.header_name,to_add.header_value,to_add.comment,to_add.status);
+	var config = JSON.parse(localStorage.getItem("config"));
+
+		
+	for (var to_add of config.headers) appendLine(to_add.action,to_add.header_name,to_add.header_value,to_add.comment,to_add.apply_on,to_add.status);
 	document.getElementById('save_button').addEventListener('click',function (e) {save_data();});
 	document.getElementById('export_button').addEventListener('click',function (e) {export_data();});
 	document.getElementById('import_button').addEventListener('click',function (e) {import_data(e);});
-	document.getElementById('add_button').addEventListener('click',function (e) {appendLine("add","-","-","","off");});
+	document.getElementById('add_button').addEventListener('click',function (e) {appendLine("add","-","-","","req","off");});
 	document.getElementById('start_img').addEventListener('click',function (e) {start_modify();});
 	document.getElementById('targetPage').value=config.target_page;
 	document.getElementById('targetPage').addEventListener('keyup',function (e) {checkTargetPageField();});
@@ -30,12 +32,13 @@ window.onload = function() {
 /**
 * Add a new configuration line on the UI 
 **/
-function appendLine(action,header_name,header_value,comment,status) {
+function appendLine(action,header_name,header_value,comment,apply_on,status) {
 
 var html = "<td><select class=\"select_field\" id=\"select_action" + line_number + "\" disable=false><option value=\"add\">add</option><option value=\"modify\">modify</option><option value=\"delete\">delete</option></select></td>";
 html = html + "<td><input class=\"input_field\" size=\"15\" id=\"header_name"+ line_number + "\"></input></td>";
 html = html + "<td><input class=\"input_field\" size=\"20\" id=\"header_value"+ line_number + "\"></input></td>";
 html = html + "<td><input class=\"input_field\" size=\"20\" id=\"comment"+ line_number + "\"></input></td>";
+html = html + "<td><select class=\"select_field\" id=\"apply_on" + line_number + "\"><option value=\"req\"> Request </option><option value=\"res\">Response</option></select></td>";
 html = html + "<td><select class=\"select_field\" id=\"select_status" + line_number + "\"><option value=\"on\"> on </option><option value=\"off\">off</option></select></td>";
 html = html + "<td><input class=\"button\" type=\"button\" value=\"Delete\" id=\"delete_button" + line_number + "\"></input> </td>";
 
@@ -45,6 +48,7 @@ newTR.innerHTML = html;
 document.getElementById("config_tab").appendChild(newTR);
 document.getElementById("select_action"+line_number).value = action;
 document.getElementById("select_status"+line_number).value = status;
+document.getElementById("apply_on"+line_number).value = apply_on;
 document.getElementById("header_name"+line_number).value = header_name;
 document.getElementById("header_value"+line_number).value = header_value;
 document.getElementById("comment"+line_number).value = comment;
@@ -69,10 +73,11 @@ function create_configuration_data()
 		var header_name = tr_elements[i].childNodes[1].childNodes[0].value;
 		var header_value = tr_elements[i].childNodes[2].childNodes[0].value;
 		var comment = tr_elements[i].childNodes[3].childNodes[0].value;
-		var status = tr_elements[i].childNodes[4].childNodes[0].value;
-		headers.push({action:action,header_name:header_name,header_value:header_value,comment:comment,status:status});
+		var apply_on = tr_elements[i].childNodes[4].childNodes[0].value;
+		var status = tr_elements[i].childNodes[5].childNodes[0].value;
+		headers.push({action:action,header_name:header_name,header_value:header_value,comment:comment,apply_on:apply_on,status:status});
 		}
-	var to_export = {format_version:"1.0",target_page:document.getElementById('targetPage').value,headers:headers};
+	var to_export = {format_version:"1.1",target_page:document.getElementById('targetPage').value,headers:headers};
 	return JSON.stringify(to_export);
 }
 
@@ -175,7 +180,7 @@ function readSingleFile(e)
   	var reader = new FileReader();
   	reader.onload = function(e) 
 		{
-    	var contents = e.target.result;
+    		var contents = e.target.result;
 		var config="";	
 		try
 			{
@@ -185,8 +190,16 @@ function readSingleFile(e)
 				{
 				// if url pattern invalid , set to "" 
 				if (!isTargetValid(config.target_page)) config.target_page=""; 
+
+				// if format file is 1.0 , need to add the apply_on value 
+				if (config.format_version=="1.0") 
+					{
+					config.format_version="1.1";
+					for (var line of config.headers) line.apply_on="req";
+					}
+
 				// store the conf in the local storage 
-				localStorage.setItem("config",contents);
+				localStorage.setItem("config",JSON.stringify(config));
 				// load the new conf 
 				browser.runtime.sendMessage("reload");
 				// reload the configuration page with the new conf
@@ -203,9 +216,9 @@ function readSingleFile(e)
 						var enabled = "off"; 
 						if (line_to_load.enabled) enabled = "on"
 						if (line_to_load.action=="Filter") line_to_load.action="delete";
-						headers.push({action:line_to_load.action.toLowerCase(),header_name:line_to_load.name,header_value:line_to_load.value,comment:line_to_load.comment,status:enabled});
+						headers.push({action:line_to_load.action.toLowerCase(),header_name:line_to_load.name,header_value:line_to_load.value,comment:line_to_load.comment,apply_on:"req",status:enabled});
 						}
-					var to_load = {format_version:"1.0",target_page:"",headers:headers};
+					var to_load = {format_version:"1.1",target_page:"",headers:headers};
 					
 					// store the conf in the local storage 
 					localStorage.setItem("config",JSON.stringify(to_load));
-- 
GitLab