diff --git a/lib/rule_default.js b/lib/rule_default.js
index 81515b4..287f3f6 100644
--- a/lib/rule_default.js
+++ b/lib/rule_default.js
@@ -113,6 +113,16 @@ module.exports = {
});
cb();
+ },
+
+ _getCustomMenu : function(){
+ return [
+ // {
+ // name:"test",
+ // icon:"uk-icon-lemon-o",
+ // url :"http://anyproxy.io"
+ // }
+ ];
}
};
diff --git a/lib/webInterface.js b/lib/webInterface.js
index a1f2002..629953c 100644
--- a/lib/webInterface.js
+++ b/lib/webInterface.js
@@ -8,6 +8,7 @@ var express = require("express"),
util = require("./util"),
certMgr = require("./certMgr"),
logUtil = require("./log"),
+ juicer = require("juicer"),
compress = require('compression');
@@ -16,10 +17,12 @@ function webInterface(config){
wsPort = config.wsPort,
ipAddress = config.ip,
userRule = config.userRule,
- ruleSummary = "";
+ ruleSummary = "",
+ customMenu = [];
try{
ruleSummary = userRule.summary();
+ customMenu = userRule._getCustomMenu();
}catch(e){}
var self = this,
@@ -88,15 +91,16 @@ function webInterface(config){
app.use(function(req,res,next){
var indexTpl = fs.readFileSync(path.join(staticDir,"/index.html"),{encoding:"utf8"}),
- indexHTML = util.simpleRender(indexTpl, {
- rule : ruleSummary || "",
- wsPort : wsPort,
- ipAddress : ipAddress || "127.0.0.1"
- });
-
+ opt = {
+ rule : ruleSummary || "",
+ customMenu : customMenu || [],
+ wsPort : wsPort,
+ ipAddress : ipAddress || "127.0.0.1"
+ };
+
if(req.url == "/"){
res.setHeader("Content-Type", "text/html");
- res.end(indexHTML);
+ res.end(juicer(indexTpl, opt));
}else{
next();
}
diff --git a/web/build/filter.js b/web/build/filter.js
index 54eeef1..08372c2 100644
--- a/web/build/filter.js
+++ b/web/build/filter.js
@@ -21,19 +21,14 @@ function init(React){
return (
React.createElement("div", null,
React.createElement("h4", {className: "subTitle"}, "Log Filter"),
-
React.createElement("div", {className: "filterSection"},
React.createElement("form", {className: "uk-form"},
React.createElement("input", {className: "uk-form-large", ref: "keywordInput", onChange: self.dealChange, type: "text", placeholder: "keywords or /^regExp$/", width: "300"})
)
),
- React.createElement("dl", {className: "uk-description-list-horizontal"},
- React.createElement("dt", null, "wrap your RegExp between two slashes"),
- React.createElement("dd", null,
- "e.g. ", React.createElement("br", null),
- "type ", React.createElement("strong", null, "/id=\\d", 3, "/"), " will give you all the logs containing ", React.createElement("strong", null, "id=123")
- )
- )
+ React.createElement("p", null,
+ React.createElement("i", {className: "uk-icon-gift"}), " type ", React.createElement("strong", null, "/id=\\d", 3, "/"), " will give you all the logs containing ", React.createElement("strong", null, "id=123")
+ )
)
);
},
diff --git a/web/build/index.js b/web/build/index.js
index 744772a..e8d5aca 100644
--- a/web/build/index.js
+++ b/web/build/index.js
@@ -88,18 +88,10 @@ var showPop;
document.getElementById("J_popOuter")
);
- showPop = function(tag,props,popArg){
- var tagEl = PopupContent[tag];
- if(!tagEl) throw new Error("element not found, please make sure your panel has been pluged");
-
- var contentEl = React.createElement(tagEl, props);
- var defaultPopPara = {
- show : true,
- content : contentEl
- };
-
- pop.setState(util_merge(defaultPopPara,popArg));
- }
+ showPop = function(popArg){
+ var stateArg = util_merge({show : true },popArg);
+ pop.setState(stateArg);
+ };
})();
//init record panel
@@ -137,7 +129,7 @@ var recorder;
});
function showDetail(data){
- showPop("detail", {data:data}, {left:"35%"});
+ showPop({left:"35%",content:React.createElement(PopupContent["detail"], {data:data})});
}
//init recorder panel
@@ -198,14 +190,29 @@ var recorder;
}
$(".J_showFilter").on("click",function(){
- showPop("filter", {onChangeKeyword : updateKeyword}, { left : "50%"});
+ showPop({ left:"50%", content:React.createElement(PopupContent["filter"], {onChangeKeyword : updateKeyword})});
});
})();
//map local
(function(){
$(".J_showMapPanel").on("click",function(){
- showPop("map", {}, {left : "40%"});
+ showPop({left:"40%", content:React.createElement(PopupContent["map"],null)});
+ });
+ })();
+
+ //other button
+ (function(){
+ $(".J_customButton").on("click",function(){
+ var thisEl = $(this),
+ iframeUrl = thisEl.attr("iframeUrl");
+
+ if(!iframeUrl){
+ throw new Error("cannot find the url assigned for this button");
+ }
+
+ var iframeEl = React.createElement("iframe",{src:iframeUrl,frameBorder:0});
+ showPop({left:"35%", content: iframeEl });
});
})();
diff --git a/web/css/page.css b/web/css/page.css
index 49ecb60..dee8af2 100644
--- a/web/css/page.css
+++ b/web/css/page.css
@@ -205,7 +205,7 @@ body, html {
border-left: 1px solid #CCC;
top: 0;
padding: 10px 20px 10px 10px;
- overflow-y:scroll;
+ overflow-y:auto;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
@@ -225,6 +225,12 @@ body, html {
word-wrap: break-word;
}
+.recordDetailOverlay iframe{
+ position: relative;
+ height: 92vh;
+ width: 100%;
+}
+
.data_id{
color: #777;
}
diff --git a/web/index.html b/web/index.html
index 001d880..482850f 100644
--- a/web/index.html
+++ b/web/index.html
@@ -2,6 +2,7 @@
AnyProxy
+
@@ -35,7 +36,15 @@
|
- Rule : {{rule}}
+
+ {@if customMenu.length}
+ {@each customMenu as item}
+ ${item.name}
+ {@/each}
+ |
+ {@/if}
+
+ Rule : ${rule}
@@ -43,8 +52,8 @@
-
-
+
+
diff --git a/web/page.js b/web/page.js
index 82ad8d8..f315915 100644
--- a/web/page.js
+++ b/web/page.js
@@ -52,11 +52,11 @@
var WsIndicator = __webpack_require__(6).init(React),
RecordPanel = __webpack_require__(8).init(React),
- Popup = __webpack_require__(9).init(React);
+ Popup = __webpack_require__(7).init(React);
var PopupContent = {
- map : __webpack_require__(7).init(React),
- detail : __webpack_require__(1).init(React),
+ map : __webpack_require__(1).init(React),
+ detail : __webpack_require__(9).init(React),
filter : __webpack_require__(10).init(React)
};
@@ -134,18 +134,10 @@
document.getElementById("J_popOuter")
);
- showPop = function(tag,props,popArg){
- var tagEl = PopupContent[tag];
- if(!tagEl) throw new Error("element not found, please make sure your panel has been pluged");
-
- var contentEl = React.createElement(tagEl, props);
- var defaultPopPara = {
- show : true,
- content : contentEl
- };
-
- pop.setState(util_merge(defaultPopPara,popArg));
- }
+ showPop = function(popArg){
+ var stateArg = util_merge({show : true },popArg);
+ pop.setState(stateArg);
+ };
})();
//init record panel
@@ -183,7 +175,7 @@
});
function showDetail(data){
- showPop("detail", {data:data}, {left:"35%"});
+ showPop({left:"35%",content:React.createElement(PopupContent["detail"], {data:data})});
}
//init recorder panel
@@ -244,14 +236,29 @@
}
$(".J_showFilter").on("click",function(){
- showPop("filter", {onChangeKeyword : updateKeyword}, { left : "50%"});
+ showPop({ left:"50%", content:React.createElement(PopupContent["filter"], {onChangeKeyword : updateKeyword})});
});
})();
//map local
(function(){
$(".J_showMapPanel").on("click",function(){
- showPop("map", {}, {left : "40%"});
+ showPop({left:"40%", content:React.createElement(PopupContent["map"],null)});
+ });
+ })();
+
+ //other button
+ (function(){
+ $(".J_customButton").on("click",function(){
+ var thisEl = $(this),
+ iframeUrl = thisEl.attr("iframeUrl");
+
+ if(!iframeUrl){
+ throw new Error("cannot find the url assigned for this button");
+ }
+
+ var iframeEl = React.createElement("iframe",{src:iframeUrl,frameBorder:0});
+ showPop({left:"35%", content: iframeEl });
});
})();
@@ -261,107 +268,35 @@
/* 1 */
/***/ function(module, exports, __webpack_require__) {
+ __webpack_require__(12);
+
function init(React){
+ var MapForm = __webpack_require__(13).init(React),
+ MapList = __webpack_require__(14).init(React);
- var DetailPanel = React.createClass({displayName: "DetailPanel",
- getInitialState : function(){
- return {
- body : {id : -1, content : null},
- left : "35%"
- };
+ var MapPanel = React.createClass({displayName: "MapPanel",
+ appendRecord : function(data){
+ var self = this,
+ listComponent = self.refs.list;
+
+ listComponent.appendRecord(data);
},
- loadBody:function(){
- var self = this,
- id = self.props.data.id;
- if(!id) return;
-
- ws.reqBody(id,function(content){
- if(content.id == self.props.data.id){
- self.setState({
- body : content
- });
- }
- });
- },
- render : function(){
- var reqHeaderSection = [],
- resHeaderSection = [],
- summarySection,
- detailSection,
- bodyContent;
-
- if(this.props.data.reqHeader){
- for(var key in this.props.data.reqHeader){
- reqHeaderSection.push(React.createElement("li", {key: "reqHeader_" + key}, React.createElement("strong", null, key), " : ", this.props.data.reqHeader[key]))
- }
- }
-
- summarySection = (
- React.createElement("div", null,
- React.createElement("section", {className: "req"},
- React.createElement("h4", {className: "subTitle"}, "request"),
- React.createElement("div", {className: "detail"},
- React.createElement("ul", {className: "uk-list"},
- React.createElement("li", null, this.props.data.method, " ", React.createElement("span", {title: "{this.props.data.path}"}, this.props.data.path), " HTTP/1.1"),
- reqHeaderSection
- )
- )
- ),
-
- React.createElement("section", {className: "reqBody"},
- React.createElement("h4", {className: "subTitle"}, "request body"),
- React.createElement("div", {className: "detail"},
- React.createElement("p", null, this.props.data.reqBody)
- )
- )
- )
- );
-
- if(this.props.data.statusCode){
-
- if(this.state.body.id == this.props.data.id){
- bodyContent = (React.createElement("pre", {className: "resBodyContent"}, this.state.body.body));
- }else{
- bodyContent = null;
- this.loadBody();
- }
-
- if(this.props.data.resHeader){
- for(var key in this.props.data.resHeader){
- resHeaderSection.push(React.createElement("li", {key: "resHeader_" + key}, React.createElement("strong", null, key), " : ", this.props.data.resHeader[key]))
- }
- }
-
- detailSection = (
- React.createElement("div", null,
- React.createElement("section", {className: "resHeader"},
- React.createElement("h4", {className: "subTitle"}, "response header"),
- React.createElement("div", {className: "detail"},
- React.createElement("ul", {className: "uk-list"},
- React.createElement("li", null, "HTTP/1.1 ", React.createElement("span", {className: "http_status http_status_" + this.props.data.statusCode}, this.props.data.statusCode)),
- resHeaderSection
- )
- )
- ),
-
- React.createElement("section", {className: "resBody"},
- React.createElement("h4", {className: "subTitle"}, "response body"),
- React.createElement("div", {className: "detail"}, bodyContent)
- )
- )
- );
- }
-
+
+ render:function(){
+ var self = this;
return (
- React.createElement("div", null,
- summarySection,
- detailSection
+ React.createElement("div", {className: "mapWrapper"},
+ React.createElement("h4", {className: "subTitle"}, "Current Config"),
+ React.createElement(MapList, {ref: "list"}),
+
+ React.createElement("h4", {className: "subTitle"}, "Add Map Rule"),
+ React.createElement(MapForm, {onSubmit: self.appendRecord})
)
);
}
});
- return DetailPanel;
+ return MapPanel;
}
module.exports.init = init;
@@ -20156,120 +20091,6 @@
/***/ },
/* 7 */
-/***/ function(module, exports, __webpack_require__) {
-
- __webpack_require__(12);
-
- function init(React){
- var MapForm = __webpack_require__(13).init(React),
- MapList = __webpack_require__(14).init(React);
-
- var MapPanel = React.createClass({displayName: "MapPanel",
- appendRecord : function(data){
- var self = this,
- listComponent = self.refs.list;
-
- listComponent.appendRecord(data);
- },
-
- render:function(){
- var self = this;
- return (
- React.createElement("div", {className: "mapWrapper"},
- React.createElement("h4", {className: "subTitle"}, "Current Config"),
- React.createElement(MapList, {ref: "list"}),
-
- React.createElement("h4", {className: "subTitle"}, "Add Map Rule"),
- React.createElement(MapForm, {onSubmit: self.appendRecord})
- )
- );
- }
- });
-
- return MapPanel;
- }
-
- module.exports.init = init;
-
-/***/ },
-/* 8 */
-/***/ function(module, exports, __webpack_require__) {
-
- function init(React){
- var RecordRow = __webpack_require__(11).init(React);
-
- var RecordPanel = React.createClass({displayName: "RecordPanel",
- getInitialState : function(){
- return {
- list : [],
- filter: ""
- };
- },
- render : function(){
- var self = this,
- rowCollection = [],
- filterStr = self.state.filter,
- filter = filterStr;
-
- //regexp
- if(filterStr[0]=="/" && filterStr[filterStr.length-1]=="/"){
- try{
- filter = new RegExp(filterStr.substr(1,filterStr.length-2));
- }catch(e){}
- }
-
- for(var i = self.state.list.length-1 ; i >=0 ; i--){
- var item = self.state.list[i];
- if(item){
- if(filter && item){
- try{
- if(typeof filter == "object" && !filter.test(item.url)){
- continue;
- }else if(typeof filter == "string" && item.url.indexOf(filter) < 0){
- continue;
- }
- }catch(e){}
- }
-
- if(item._justUpdated){
- item._justUpdated = false;
- item._needRender = true;
- }else{
- item._needRender = false;
- }
-
- rowCollection.push(React.createElement(RecordRow, {key: item.id, data: item, onSelect: self.props.onSelect.bind(self,item)}));
- }
- }
-
- return (
- React.createElement("table", {className: "uk-table uk-table-condensed uk-table-hover"},
- React.createElement("thead", null,
- React.createElement("tr", null,
- React.createElement("th", {className: "col_id"}, "#"),
- React.createElement("th", {className: "col_method"}, "method"),
- React.createElement("th", {className: "col_code"}, "code"),
- React.createElement("th", {className: "col_host"}, "host"),
- React.createElement("th", {className: "col_path"}, "path"),
- React.createElement("th", {className: "col_mime"}, "mime type"),
- React.createElement("th", {className: "col_time"}, "time")
- )
- ),
- React.createElement("tbody", null,
- rowCollection
- )
- )
- );
- }
- });
-
- return RecordPanel;
- }
-
- module.exports.init = init;
-
-/***/ },
-/* 9 */
/***/ function(module, exports, __webpack_require__) {
function init(React){
@@ -20367,6 +20188,192 @@
module.exports.init = init;
+/***/ },
+/* 8 */
+/***/ function(module, exports, __webpack_require__) {
+
+ function init(React){
+ var RecordRow = __webpack_require__(11).init(React);
+
+ var RecordPanel = React.createClass({displayName: "RecordPanel",
+ getInitialState : function(){
+ return {
+ list : [],
+ filter: ""
+ };
+ },
+ render : function(){
+ var self = this,
+ rowCollection = [],
+ filterStr = self.state.filter,
+ filter = filterStr;
+
+ //regexp
+ if(filterStr[0]=="/" && filterStr[filterStr.length-1]=="/"){
+ try{
+ filter = new RegExp(filterStr.substr(1,filterStr.length-2));
+ }catch(e){}
+ }
+
+ for(var i = self.state.list.length-1 ; i >=0 ; i--){
+ var item = self.state.list[i];
+ if(item){
+ if(filter && item){
+ try{
+ if(typeof filter == "object" && !filter.test(item.url)){
+ continue;
+ }else if(typeof filter == "string" && item.url.indexOf(filter) < 0){
+ continue;
+ }
+ }catch(e){}
+ }
+
+ if(item._justUpdated){
+ item._justUpdated = false;
+ item._needRender = true;
+ }else{
+ item._needRender = false;
+ }
+
+ rowCollection.push(React.createElement(RecordRow, {key: item.id, data: item, onSelect: self.props.onSelect.bind(self,item)}));
+ }
+ }
+
+ return (
+ React.createElement("table", {className: "uk-table uk-table-condensed uk-table-hover"},
+ React.createElement("thead", null,
+ React.createElement("tr", null,
+ React.createElement("th", {className: "col_id"}, "#"),
+ React.createElement("th", {className: "col_method"}, "method"),
+ React.createElement("th", {className: "col_code"}, "code"),
+ React.createElement("th", {className: "col_host"}, "host"),
+ React.createElement("th", {className: "col_path"}, "path"),
+ React.createElement("th", {className: "col_mime"}, "mime type"),
+ React.createElement("th", {className: "col_time"}, "time")
+ )
+ ),
+ React.createElement("tbody", null,
+ rowCollection
+ )
+ )
+ );
+ }
+ });
+
+ return RecordPanel;
+ }
+
+ module.exports.init = init;
+
+/***/ },
+/* 9 */
+/***/ function(module, exports, __webpack_require__) {
+
+ function init(React){
+
+ var DetailPanel = React.createClass({displayName: "DetailPanel",
+ getInitialState : function(){
+ return {
+ body : {id : -1, content : null},
+ left : "35%"
+ };
+ },
+ loadBody:function(){
+ var self = this,
+ id = self.props.data.id;
+ if(!id) return;
+
+ ws.reqBody(id,function(content){
+ if(content.id == self.props.data.id){
+ self.setState({
+ body : content
+ });
+ }
+ });
+ },
+ render : function(){
+ var reqHeaderSection = [],
+ resHeaderSection = [],
+ summarySection,
+ detailSection,
+ bodyContent;
+
+ if(this.props.data.reqHeader){
+ for(var key in this.props.data.reqHeader){
+ reqHeaderSection.push(React.createElement("li", {key: "reqHeader_" + key}, React.createElement("strong", null, key), " : ", this.props.data.reqHeader[key]))
+ }
+ }
+
+ summarySection = (
+ React.createElement("div", null,
+ React.createElement("section", {className: "req"},
+ React.createElement("h4", {className: "subTitle"}, "request"),
+ React.createElement("div", {className: "detail"},
+ React.createElement("ul", {className: "uk-list"},
+ React.createElement("li", null, this.props.data.method, " ", React.createElement("span", {title: "{this.props.data.path}"}, this.props.data.path), " HTTP/1.1"),
+ reqHeaderSection
+ )
+ )
+ ),
+
+ React.createElement("section", {className: "reqBody"},
+ React.createElement("h4", {className: "subTitle"}, "request body"),
+ React.createElement("div", {className: "detail"},
+ React.createElement("p", null, this.props.data.reqBody)
+ )
+ )
+ )
+ );
+
+ if(this.props.data.statusCode){
+
+ if(this.state.body.id == this.props.data.id){
+ bodyContent = (React.createElement("pre", {className: "resBodyContent"}, this.state.body.body));
+ }else{
+ bodyContent = null;
+ this.loadBody();
+ }
+
+ if(this.props.data.resHeader){
+ for(var key in this.props.data.resHeader){
+ resHeaderSection.push(React.createElement("li", {key: "resHeader_" + key}, React.createElement("strong", null, key), " : ", this.props.data.resHeader[key]))
+ }
+ }
+
+ detailSection = (
+ React.createElement("div", null,
+ React.createElement("section", {className: "resHeader"},
+ React.createElement("h4", {className: "subTitle"}, "response header"),
+ React.createElement("div", {className: "detail"},
+ React.createElement("ul", {className: "uk-list"},
+ React.createElement("li", null, "HTTP/1.1 ", React.createElement("span", {className: "http_status http_status_" + this.props.data.statusCode}, this.props.data.statusCode)),
+ resHeaderSection
+ )
+ )
+ ),
+
+ React.createElement("section", {className: "resBody"},
+ React.createElement("h4", {className: "subTitle"}, "response body"),
+ React.createElement("div", {className: "detail"}, bodyContent)
+ )
+ )
+ );
+ }
+
+ return (
+ React.createElement("div", null,
+ summarySection,
+ detailSection
+ )
+ );
+ }
+ });
+
+ return DetailPanel;
+ }
+
+ module.exports.init = init;
+
/***/ },
/* 10 */
/***/ function(module, exports, __webpack_require__) {
@@ -20394,19 +20401,14 @@
return (
React.createElement("div", null,
React.createElement("h4", {className: "subTitle"}, "Log Filter"),
-
React.createElement("div", {className: "filterSection"},
React.createElement("form", {className: "uk-form"},
React.createElement("input", {className: "uk-form-large", ref: "keywordInput", onChange: self.dealChange, type: "text", placeholder: "keywords or /^regExp$/", width: "300"})
)
),
- React.createElement("dl", {className: "uk-description-list-horizontal"},
- React.createElement("dt", null, "wrap your RegExp between two slashes"),
- React.createElement("dd", null,
- "e.g. ", React.createElement("br", null),
- "type ", React.createElement("strong", null, "/id=\\d", 3, "/"), " will give you all the logs containing ", React.createElement("strong", null, "id=123")
- )
- )
+ React.createElement("p", null,
+ React.createElement("i", {className: "uk-icon-gift"}), " type ", React.createElement("strong", null, "/id=\\d", 3, "/"), " will give you all the logs containing ", React.createElement("strong", null, "id=123")
+ )
)
);
},
diff --git a/web/src/filter.js b/web/src/filter.js
index 140bdc1..1ac273c 100644
--- a/web/src/filter.js
+++ b/web/src/filter.js
@@ -21,19 +21,14 @@ function init(React){
return (
Log Filter
-
-
- - wrap your RegExp between two slashes
- -
- e.g.
- type /id=\d{3}/ will give you all the logs containing id=123
-
-
+
+ type /id=\d{3}/ will give you all the logs containing id=123
+
);
},
diff --git a/web/src/index.js b/web/src/index.js
index cbdbb2f..fe21237 100644
--- a/web/src/index.js
+++ b/web/src/index.js
@@ -88,18 +88,10 @@ var showPop;
document.getElementById("J_popOuter")
);
- showPop = function(tag,props,popArg){
- var tagEl = PopupContent[tag];
- if(!tagEl) throw new Error("element not found, please make sure your panel has been pluged");
-
- var contentEl = React.createElement(tagEl, props);
- var defaultPopPara = {
- show : true,
- content : contentEl
- };
-
- pop.setState(util_merge(defaultPopPara,popArg));
- }
+ showPop = function(popArg){
+ var stateArg = util_merge({show : true },popArg);
+ pop.setState(stateArg);
+ };
})();
//init record panel
@@ -137,7 +129,7 @@ var recorder;
});
function showDetail(data){
- showPop("detail", {data:data}, {left:"35%"});
+ showPop({left:"35%",content:React.createElement(PopupContent["detail"], {data:data})});
}
//init recorder panel
@@ -198,14 +190,29 @@ var recorder;
}
$(".J_showFilter").on("click",function(){
- showPop("filter", {onChangeKeyword : updateKeyword}, { left : "50%"});
+ showPop({ left:"50%", content:React.createElement(PopupContent["filter"], {onChangeKeyword : updateKeyword})});
});
})();
//map local
(function(){
$(".J_showMapPanel").on("click",function(){
- showPop("map", {}, {left : "40%"});
+ showPop({left:"40%", content:React.createElement(PopupContent["map"],null)});
+ });
+ })();
+
+ //other button
+ (function(){
+ $(".J_customButton").on("click",function(){
+ var thisEl = $(this),
+ iframeUrl = thisEl.attr("iframeUrl");
+
+ if(!iframeUrl){
+ throw new Error("cannot find the url assigned for this button");
+ }
+
+ var iframeEl = React.createElement("iframe",{src:iframeUrl,frameBorder:0});
+ showPop({left:"35%", content: iframeEl });
});
})();