Skip to content
Snippets Groups Projects
Commit 84bc9ab2 authored by didierfred's avatar didierfred
Browse files

do not need anymore specific pakage for chrome

parent dc8f28fb
No related branches found
No related tags found
No related merge requests found
Showing
with 0 additions and 847 deletions
/* 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
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* @author didierfred@gmail.com
* @version 0.3
*/
"use strict";
var config ;
var started = "off";
// if configuration exist
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.format_version=="1.0")
{
config.format_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
{
// else check if old config exist (Simple Modify headers V1.1)
if (localStorage.getItem('targetPage')&& localStorage.getItem('modifyTable'))
{
console.log("Load old config");
var headers = [];
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:"",apply_on:"req",status:to_modify[3]});
}
config = {format_version:"1.1",target_page:localStorage.getItem('targetPage'),headers:headers};
// save old config in new format
localStorage.setItem("config",JSON.stringify(config));
}
//else no config exists, create a default one
else
{
console.log("Load default config");
var 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));
}
}
// If no started value stored , use a default one
if (!localStorage.getItem('started')) localStorage.setItem('started',started);
else started = localStorage.getItem('started');
if (started=="on")
{
addListener();
chrome.browserAction.setIcon({ path: "icons/modify-green-32.png"});
}
// listen for change in configuration or start/stop
chrome.runtime.onMessage.addListener(notify);
/*
* Rewrite the request header (add , modify or delete)
*
*/
function rewriteRequestHeader(e)
{
for (var to_modify of config.headers)
{
if ((to_modify.status=="on")&&(to_modify.apply_on=="req"))
{
if (to_modify.action=="add")
{
var new_header = {"name" :to_modify.header_name,"value":to_modify.header_value};
e.requestHeaders.push(new_header);
}
else if (to_modify.action=="modify")
{
for (var header of e.requestHeaders)
{
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.requestHeaders.length; i++)
{
if (e.requestHeaders[i].name.toLowerCase() == to_modify.header_name.toLowerCase()) index=i;
}
if (index!=-1)
{
e.requestHeaders.splice(index,1);
}
}
}
}
return {requestHeaders: e.requestHeaders};
}
/*
* Rewrite the response header (add , modify or delete)
*
*/
function rewriteResponseHeader(e)
{
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);
}
}
}
}
return {responseHeaders: e.responseHeaders};
}
/*
* Listen for message form config.js
* if message is reload : reload the configuration
* if message is on : start the modify header
* if message is off : stop the modify header
*
**/
function notify(message)
{
if (message=="reload")
{
config=JSON.parse(localStorage.getItem("config"));
if (started=="on")
{
removeListener();
addListener();
}
}
else if (message=="off")
{
removeListener();
chrome.browserAction.setIcon({ path: "icons/modify-32.png"});
started="off";
}
else if (message=="on")
{
addListener();
chrome.browserAction.setIcon({ path: "icons/modify-green-32.png"});
started="on";
}
}
/*
* 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()
{
var target = config.target_page;
if ((target=="*")||(target=="")||(target==" ")) target="<all_urls>";
chrome.webRequest.onBeforeSendHeaders.addListener(rewriteRequestHeader,
{urls: [target]},
["blocking", "requestHeaders"]);
chrome.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()
{
chrome.webRequest.onBeforeSendHeaders.removeListener(rewriteRequestHeader);
chrome.webRequest.onHeadersReceived.removeListener(rewriteResponseHeader);
// for debug only
// browser.webRequest.onCompleted.removeListener(log_headers);
}
File deleted
chrome-version/icons/modify-32.png

939 B

chrome-version/icons/modify-48.png

1.29 KiB

chrome-version/icons/modify-green-128.png

5.01 KiB

chrome-version/icons/modify-green-32.png

1.1 KiB

chrome-version/icons/modify-green-48.png

1.6 KiB

chrome-version/icons/modify.png

17.6 KiB

{
"description": "Simple Modify headers ",
"manifest_version": 2,
"name": "simple-modify-headers",
"version": "1.4",
"homepage_url": "https://github.com/didierfred/SimpleModifyHeaders",
"icons": {
"48": "icons/modify-48.png"
},
"permissions": [
"activeTab","storage","webRequest", "webRequestBlocking", "<all_urls>" ,"tabs"
],
"background": {
"scripts": ["background.js"]
},
"browser_action": {
"default_icon": "icons/modify-32.png",
"default_title": "Simple Modify Headers",
"default_popup": "popup/menu.html"
}
}
This diff is collapsed.
<!DOCTYPE html>
<html lang="fr">
<head>
<title>Simple Modify Headers</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="bootstrap.min.css">
<style type="text/css">
.title{
color: #008CBA;
}
.select_field{
font-size: 14px;
height: 30px;
}
.input_field{
font-size: 14px;
height: 30px;
border: 1px solid #AAAAAA;
border-radius: 3px;
}
.input_url {
border: none;
border-bottom: 1px solid #AAAAAA;
}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-sm-6"> <h2 class="title"> SIMPLE MODIFY HEADERS </h2> </div>
<div class="col-sm-6"> <img id="start_img" src="img/start.png" align="right" valign="top"> </img> </div>
</div>
<br/>
<div class="row">
<div class="col-sm-8">
<b> Url Pattern* : </b> <input size="50" id="targetPage" class="form_control input_url" type="text" value="">
</div>
<div class="col-sm-4" align="right">
<a href="#" id="export_button" class="btn btn-primary btn-sm" style="width:100px">
<span class="glyphicon glyphicon-export"></span> Export
</a>
<a href="#" id="import_button" class="btn btn-primary btn-sm" style="width:100px">
<span class="glyphicon glyphicon-import"></span> Import
</a>
</div>
</div>
<br/>
<center>
<table class="table table-condensed " >
<thead>
<tr>
<th> Action </th>
<th> Header Field Name </th>
<th> Header Field Value </th>
<th> Comment </th>
<th> Apply on </th>
<th> Status </th>
<th> </th>
<th> </th>
<th> </th>
</tr>
</thead>
<tbody id="config_tab">
</tbody>
</table>
</center>
<center>
<a href="#" id="add_button" class="btn btn-primary btn-sm" style="width:100px">
<span class="glyphicon glyphicon-plus"></span> New line
</a>
<a href="#" id="save_button" class="btn btn-primary btn-sm" style="width:100px">
<span class="glyphicon glyphicon-save"></span> Save
</a>
<br>
</center>
<br>
<div class="row">
<div class="col-sm-10">
<i style="font-size:12pt"> * Informations on url pattern can be found <a href="https://developer.chrome.com/extensions/match_patterns" target="_blank"> here </a> &nbsp (An empty string on the field will select all urls.) </i>
</div>
<div class="col-sm-2" align="right">
<a href="https://github.com/didierfred/SimpleModifyHeaders/tree/V1.4" target="_blank"> <span class="glyphicon glyphicon-question-sign"></span> About </a>
</div>
</div>
<iframe id="download" width="0" height="0" frameBorder="0">
</iframe>
<br>
<script type="text/javascript" src="config.js"> </script>
</body>
</html>
/* 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
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* @author didierfred@gmail.com
* @version 0.3
*/
var line_number = 1;
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.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","-","-","","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();});
started = localStorage.getItem("started");
if (started=="on") document.getElementById("start_img").src = "img/stop.png";
} ;
/**
* Add a new configuration line on the UI
**/
function appendLine(action,header_name,header_value,comment,apply_on,status) {
var html = "<td><select class=\"form_control 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=\"form_control input_field\" id=\"header_name"+ line_number + "\"></input></td>";
html = html + "<td><input class=\"form_control input_field\" size=\"28\" id=\"header_value"+ line_number + "\"></input></td>";
html = html + "<td><input class=\"form_control input_field\" size=\"28\" id=\"comment"+ line_number + "\"></input></td>";
html = html + "<td><select class=\"form_control select_field\" id=\"apply_on" + line_number + "\"><option value=\"req\"> Request </option><option value=\"res\">Response</option></select></td>";
html = html + "<td><select class=\"form_control select_field\" id=\"select_status" + line_number + "\"><option value=\"on\"> ON </option><option value=\"off\">OFF</option></select></td>";
html = html + "<td> <a href=\"#\" title=\"Move line up\" id=\"up_button" + line_number + "\" class=\"btn btn-default btn-sm\"> <span class=\"glyphicon glyphicon-arrow-up\"></span></a></td>";
html = html + "<td> <a href=\"#\" title=\"Move line down\" id=\"down_button" + line_number + "\" class=\"btn btn-default btn-sm\"> <span class=\"glyphicon glyphicon-arrow-down\"></span></a></td>";
html = html + "<td> <a href=\"#\" title=\"Delete line\" id=\"delete_button" + line_number + "\" class=\"btn btn-primary btn-sm\"> <span class=\"glyphicon glyphicon-trash\"></span></a></td>";
var newTR = document.createElement("tr");
newTR.id="line" + line_number;
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;
var line_number_to_modify = line_number;
document.getElementById('delete_button'+line_number).addEventListener('click',function (e) {delete_line(line_number_to_modify)});
document.getElementById('up_button'+line_number).addEventListener('click',function (e) {invert_line(line_number_to_modify,line_number_to_modify-1)});
document.getElementById('down_button'+line_number).addEventListener('click',function (e) {invert_line(line_number_to_modify,line_number_to_modify+1)});
line_number++;
}
/**
* Create a JSON String representing the configuration data
*
**/
function create_configuration_data()
{
var tr_elements = document.querySelectorAll("#config_tab tr");
var headers = [];
for (i=0;i<tr_elements.length;i++)
{
var action = tr_elements[i].childNodes[0].childNodes[0].value;
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 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.1",target_page:document.getElementById('targetPage').value,headers:headers};
return JSON.stringify(to_export);
}
/**
* check if url pattern is valid , if not , set the font color to red
**/
function checkTargetPageField()
{
if (isTargetValid(document.getElementById('targetPage').value)) document.getElementById('targetPage').style.color="black";
else document.getElementById('targetPage').style.color="red";
}
/**
* check if url pattern is valid
**/
function isTargetValid(target)
{
if (target=="") return true;
if (target==" ") return true;
if (target=="*") return true;
return target.match("(http|https|[\*]):\/\/([\*][\.][^\*]*|[^\*]*|[\*])\/");
}
/**
* If url pattern is valid save the data to the local storage and restart modify header
**/
function save_data()
{
if (!isTargetValid(document.getElementById('targetPage').value))
{
alert("Can not save configuration: Url pattern is invalid");
return false;
}
localStorage.setItem("config",create_configuration_data());
chrome.runtime.sendMessage("reload");
return true;
}
/**
* If url pattern is valid save the data in a file
**/
function export_data()
{
if (!isTargetValid(document.getElementById('targetPage').value))
{
alert("Can not export : Url pattern is invalid");
return;
}
// Save in local storage
save_data();
// Create file data
var to_export= create_configuration_data();
// Create file to save
var a = document.createElement('a');
a.href = 'data:attachment/json,' + encodeURIComponent(to_export);
a.target = 'download';
a.download = 'SimpleModifyHeader.conf';
// use iframe "download" to put the link (in order not to be redirect in the parent frame)
var myf = document.getElementById("download");
myf = myf.contentWindow.document || myf.contentDocument;
myf.body.appendChild(a);
a.click();
}
/**
* Choose a file and import data from the choosen file
*
**/
function import_data(evt)
{
// create an input field in the iframe
if (window.confirm("This will erase your actual configuration, do you want to continue ?"))
{
var input = document.createElement("input");
input.type="file";
input.addEventListener('change', readSingleFile, false);
var myf = document.getElementById("download");
myf = myf.contentWindow.document || myf.contentDocument;
myf.body.appendChild(input);
input.click();
}
}
/**
* Import data from a file
*
* If format is not recognized , try modify header add-an file format
*
**/
function readSingleFile(e)
{
var file = e.target.files[0];
if (!file) {
return;
}
var reader = new FileReader();
reader.onload = function(e)
{
var contents = e.target.result;
var config="";
try
{
config = JSON.parse(contents);
// check file format
if (config.format_version && config.target_page)
{
// 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",JSON.stringify(config));
// load the new conf
chrome.runtime.sendMessage("reload");
// reload the configuration page with the new conf
document.location.href="config.html";
}
else
{
// try modify header add-on file format : array of {action,name,value,comment,enabled}
if (config[0].action)
{
var headers = [];
for (var line_to_load of config)
{
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,apply_on:"req",status:enabled});
}
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));
// load the new conf
chrome.runtime.sendMessage("reload");
// reload the configuration page with the new conf
document.location.href="config.html";
}
else alert("invalid file format");
}
}
catch(error)
{
console.log(error);
alert("Invalid file format");
}
};
reader.readAsText(file);
}
/**
* Delete a configuration line on the UI
**/
function delete_line(line_number_to_delete)
{
if (line_number_to_delete != line_number)
{
for (i=line_number_to_delete;i<line_number-1;i++)
{
var j = i+1;
document.getElementById("select_action"+i).value = document.getElementById("select_action"+j).value;
document.getElementById("header_name"+i).value = document.getElementById("header_name"+j).value;
document.getElementById("header_value"+i).value = document.getElementById("header_value"+j).value;
document.getElementById("comment"+i).value = document.getElementById("comment"+j).value;
document.getElementById("select_status"+i).value = document.getElementById("select_status"+j).value;
document.getElementById("apply_on"+i).value = document.getElementById("apply_on"+j).value;
}
}
var Node_to_delete = document.getElementById("line"+(line_number-1));
Node_to_delete.parentNode.removeChild(Node_to_delete);
line_number--;
}
/**
* Invert two configuration lines on the UI
**/
function invert_line(line1, line2)
{
// if a line does not exist , do nothing
if ((line1==0)||(line2==0)||(line1>=line_number)||(line2>=line_number)) return;
// Save data for line 1
var select_action1= document.getElementById("select_action"+line1).value;
var header_name1 = document.getElementById("header_name"+line1).value;
var header_value1= document.getElementById("header_value"+line1).value;
var comment1 = document.getElementById("comment"+line1).value;
var select_status1 = document.getElementById("select_status"+line1).value;
var apply_on1 = document.getElementById("apply_on"+line1).value;
// Copy line 2 to line 1
document.getElementById("select_action"+line1).value = document.getElementById("select_action"+line2).value;
document.getElementById("header_name"+line1).value = document.getElementById("header_name"+line2).value;
document.getElementById("header_value"+line1).value = document.getElementById("header_value"+line2).value;
document.getElementById("comment"+line1).value = document.getElementById("comment"+line2).value;
document.getElementById("select_status"+line1).value = document.getElementById("select_status"+line2).value;
document.getElementById("apply_on"+line1).value = document.getElementById("apply_on"+line2).value;
// Copy line 1 to line 2
document.getElementById("select_action"+line2).value = select_action1;
document.getElementById("header_name"+line2).value = header_name1;
document.getElementById("header_value"+line2).value = header_value1;
document.getElementById("comment"+line2).value = comment1;
document.getElementById("select_status"+line2).value = select_status1;
document.getElementById("apply_on"+line2).value = apply_on1;
}
/**
* Stop or Start modify header
**/
function start_modify()
{
if (started=="off")
{
if (save_data())
{
localStorage.setItem("started","on");
chrome.runtime.sendMessage("on");
started = "on";
document.getElementById("start_img").src = "img/stop.png";
}
}
else
{
localStorage.setItem("started","off");
chrome.runtime.sendMessage("off");
started = "off";
document.getElementById("start_img").src = "img/start.png";
}
}
chrome-version/popup/img/help.png

1.15 KiB

chrome-version/popup/img/start.png

3.35 KiB

chrome-version/popup/img/stop.png

3.99 KiB

chrome-version/popup/img/stop_big.png

17.3 KiB

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style type="text/css">
.button {
background-color: #008CBA; /* Blue */
border: none;
color: white;
padding: 1px 5px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 14px;
border-radius: 4px;
transition-duration: 0.4s;
width="100px";
}
.button:hover {
background-color: #0070A0;
}
</style>
</head>
<body>
<table>
<tr>
<td>
<input type="button" class="button" style="width:100px" id="config" value="Configure"></input>
</td>
<td>
<input type="button" class="button" style="width:100px" id="start_stop" value="Start" ></input>
</td>
</tr>
</table>
</center>
<script type="text/javascript" src="menu.js"> </script>
</body>
</html>
/* 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
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* @author didierfred@gmail.com
* @version 0.2
*/
var started = "off";
window.onload = function() {
document.getElementById('config').addEventListener('click',function (e) {start_config();});
document.getElementById('start_stop').addEventListener('click',function (e) {start_modify();});
started = localStorage.getItem("started");
if (started=="on") document.getElementById("start_stop").value = "Stop";
} ;
function start_modify()
{
if (started=="off")
{
localStorage.setItem("started","on");
chrome.runtime.sendMessage("on");
started = "on";
document.getElementById("start_stop").value = "Stop";
}
else
{
localStorage.setItem("started","off");
chrome.runtime.sendMessage("off");
started = "off";
document.getElementById("start_stop").value = "Start";
}
// if exists reload config tab , to get the start/stop information correct
chrome.tabs.query({currentWindow: true},reloadConfigTab);
}
function reloadConfigTab(tabs)
{
var config_tab;
// search for config tab
for (let tab of tabs)
{
if (tab.url.startsWith(chrome.extension.getURL(""))) config_tab = tab;
}
// config tab exists , reload it
if (config_tab) chrome.tabs.reload(config_tab.id);
}
function start_config()
{
chrome.tabs.query({currentWindow: true},loadConfigTab);
}
function loadConfigTab(tabs)
{
var config_tab;
// search for config tab
for (let tab of tabs)
{
if (tab.url.startsWith(chrome.extension.getURL(""))) config_tab = tab;
}
// config tab exits , put the focus on it
if (config_tab) chrome.tabs.update(config_tab.id,{active:true})
// else create a new tab
else chrome.tabs.create({url:"popup/config.html"});
}
chrome-version/screenshot1280x800.png

58.6 KiB

0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment