Unverified Commit a5cbe4c1 authored by Medicean's avatar Medicean Committed by GitHub

Release v2.0.5

Merge pull request #130 from AntSwordProject/v2.0.x
parents 942c059a f2b12127
...@@ -2,6 +2,38 @@ ...@@ -2,6 +2,38 @@
> 有空会补补BUG、添添新功能。 > 有空会补补BUG、添添新功能。
> 同时也欢迎大家的参与!感谢各位朋友的支持! .TAT. > 同时也欢迎大家的参与!感谢各位朋友的支持! .TAT.
## 2019/03/04 `v(2.0.5)`
### 后端模块
* 新增 chunked 流式传输
![chunk-2.png](https://i.loli.net/2019/01/28/5c4e8869c83ae.png)
### Shell 管理
* 新增「测试连接」功能
* 其它设置增加「开启分块传输」开关,设置「最小分块」和「最大分块」。每次分块大小为[n, m]区间。
![chunk-1.png](https://i.loli.net/2019/01/28/5c4e8868f178a.png)
### 文件管理
* 编辑文件标签打开时显示正在编辑的文件的「IP地址」和「绝对路径」 (#129)
* 编辑文件「保存」按钮移动到右侧
### 插件市场
* 支持使用代理访问插件市场,当配置了代理之后,默认开启
### 浏览网站
* 新增代理开关, 在配置了代理之后,可通过该开关控制是否使用代理浏览目标网站
### Other
* 调整 aproxy uri 初始化 URL 格式
## 2019/01/21 `v(2.0.4)` ## 2019/01/21 `v(2.0.4)`
### 后端模块 ### 后端模块
......
# AntSword [![release](https://img.shields.io/badge/release-v2.0.4-blue.svg?style=flat-square)][url-release] # AntSword [![release](https://img.shields.io/badge/release-v2.0.5-blue.svg?style=flat-square)][url-release]
> AntSword in your hands, no worries in your mind! > AntSword in your hands, no worries in your mind!
...@@ -22,6 +22,17 @@ This software, of which the development thought is modularization, is intended t ...@@ -22,6 +22,17 @@ This software, of which the development thought is modularization, is intended t
![][url-mainui] ![][url-mainui]
<details>
<summary>More Screenshots</summary>
![][url-filemanager]
![][url-terminal]
![][url-database]
![][url-pluginstore]
</details>
## Quick Start ## Quick Start
See document: [Quick Start][url-quickstart] See document: [Quick Start][url-quickstart]
...@@ -41,7 +52,7 @@ See document: [Make contributions to AntSword][url-contribute] ...@@ -41,7 +52,7 @@ See document: [Make contributions to AntSword][url-contribute]
[url-doczh]: README_CN.md [url-doczh]: README_CN.md
[url-changelog]: CHANGELOG.md [url-changelog]: CHANGELOG.md
[url-document]: http://doc.u0u.us/en/ [url-document]: http://doc.u0u.us/en/
[url-release]: https://github.com/AntSwordProject/AntSword/releases/tag/2.0.0 [url-release]: https://github.com/AntSwordProject/AntSword/releases/
[url-electron]: http://electron.atom.io/ [url-electron]: http://electron.atom.io/
[url-es6]: http://es6.ruanyifeng.com/ [url-es6]: http://es6.ruanyifeng.com/
[url-dhtmlx]: http://dhtmlx.com/ [url-dhtmlx]: http://dhtmlx.com/
...@@ -50,4 +61,8 @@ See document: [Make contributions to AntSword][url-contribute] ...@@ -50,4 +61,8 @@ See document: [Make contributions to AntSword][url-contribute]
[url-release]: https://github.com/AntSwordProject/AntSword/releases [url-release]: https://github.com/AntSwordProject/AntSword/releases
[url-quickstart]: https://doc.u0u.us/en/getting_started/index.html [url-quickstart]: https://doc.u0u.us/en/getting_started/index.html
[url-contribute]: https://doc.u0u.us/en/contribute_docs.html [url-contribute]: https://doc.u0u.us/en/contribute_docs.html
[url-mainui]: http://7xtigg.com1.z0.glb.clouddn.com/doc/getting_started/get_antsword_2.jpg [url-mainui]: http://as.xuanbo.cc/doc/getting_started/get_antsword_2.jpg
\ No newline at end of file [url-filemanager]: http://as.xuanbo.cc/doc/file_manager/main_page_1.png
[url-terminal]: http://as.xuanbo.cc/doc/terminal/main_page_1.png
[url-database]: http://as.xuanbo.cc/doc/database/main_page_1.png
[url-pluginstore]: http://as.xuanbo.cc/doc/plugin_store/main_page_2.jpg
# 中国蚁剑 [![release](https://img.shields.io/badge/release-v2.0.4-blue.svg?style=flat-square)][url-release] # 中国蚁剑 [![release](https://img.shields.io/badge/release-v2.0.5-blue.svg?style=flat-square)][url-release]
> 一剑在手,纵横无忧! > 一剑在手,纵横无忧!
...@@ -20,6 +20,17 @@ ...@@ -20,6 +20,17 @@
![][url-mainui] ![][url-mainui]
<details>
<summary>更多截图</summary>
![][url-filemanager]
![][url-terminal]
![][url-database]
![][url-pluginstore]
</details>
## 快速入门 ## 快速入门
参见文档 [快速入门][url-quickstart] 参见文档 [快速入门][url-quickstart]
...@@ -41,7 +52,7 @@ ...@@ -41,7 +52,7 @@
[url-docen]: README.md [url-docen]: README.md
[url-changelog]: CHANGELOG.md [url-changelog]: CHANGELOG.md
[url-document]: http://doc.u0u.us/zh-hans/ [url-document]: http://doc.u0u.us/zh-hans/
[url-release]: https://github.com/AntSwordProject/AntSword/releases/tag/2.0.0 [url-release]: https://github.com/AntSwordProject/AntSword/releases/
[url-electron]: http://electron.atom.io/ [url-electron]: http://electron.atom.io/
[url-es6]: http://es6.ruanyifeng.com/ [url-es6]: http://es6.ruanyifeng.com/
[url-dhtmlx]: http://dhtmlx.com/ [url-dhtmlx]: http://dhtmlx.com/
...@@ -50,4 +61,8 @@ ...@@ -50,4 +61,8 @@
[url-release]: https://github.com/AntSwordProject/AntSword/releases [url-release]: https://github.com/AntSwordProject/AntSword/releases
[url-quickstart]: https://doc.u0u.us/zh-hans/getting_started/index.html [url-quickstart]: https://doc.u0u.us/zh-hans/getting_started/index.html
[url-contribute]: https://doc.u0u.us/zh-hans/contribute_docs.html [url-contribute]: https://doc.u0u.us/zh-hans/contribute_docs.html
[url-mainui]: http://7xtigg.com1.z0.glb.clouddn.com/doc/getting_started/get_antsword_2.jpg [url-mainui]: http://as.xuanbo.cc/doc/getting_started/get_antsword_2.jpg
\ No newline at end of file [url-filemanager]: http://as.xuanbo.cc/doc/file_manager/main_page_1.png
[url-terminal]: http://as.xuanbo.cc/doc/terminal/main_page_1.png
[url-database]: http://as.xuanbo.cc/doc/database/main_page_1.png
[url-pluginstore]: http://as.xuanbo.cc/doc/plugin_store/main_page_2.jpg
...@@ -12,6 +12,7 @@ const fs = require('fs'), ...@@ -12,6 +12,7 @@ const fs = require('fs'),
CONF = require('./config'), CONF = require('./config'),
superagent = require('superagent'), superagent = require('superagent'),
superagentProxy = require('superagent-proxy'); superagentProxy = require('superagent-proxy');
const { Readable } = require("stream");
let logger; let logger;
// 请求UA // 请求UA
...@@ -109,6 +110,51 @@ class Request { ...@@ -109,6 +110,51 @@ class Request {
} }
// 自定义body // 自定义body
const _postData = Object.assign({}, opts.body, opts.data); const _postData = Object.assign({}, opts.body, opts.data);
if (opts['useChunk'] == 1){
logger.debug("request with Chunked");
let _postarr = [];
for(var key in _postData){
if(_postData.hasOwnProperty(key)){
_postarr.push(`${key}=${encodeURIComponent(_postData[key])}`);
}
}
let antstream = new AntRead(_postarr.join("&"), {'step': parseInt(opts['chunkStepMin']), 'stepmax': parseInt(opts['chunkStepMax'])});
let _datasuccess = false; // 表示是否是 404 类shell
_request
.proxy(APROXY_CONF['uri'])
.type('form')
// .set('Content-Type', 'application/x-www-form-urlencoded')
.timeout(opts.timeout || REQ_TIMEOUT)
.ignoreHTTPS(opts['ignoreHTTPS'])
.parse((res, callback) => {
this.parse(opts['tag_s'], opts['tag_e'], (chunk) => {
event.sender.send('request-chunk-' + opts['hash'], chunk);
}, res, (err, ret)=>{
let buff = ret ? ret : new Buffer();
// 自动猜测编码
let encoding = detectEncoding(buff, {defaultEncoding: "unknown"});
logger.debug("detect encoding:", encoding);
encoding = encoding != "unknown" ? encoding : opts['encode'];
let text = iconv.decode(buff, encoding);
if (err && text == "") {
return event.sender.send('request-error-' + opts['hash'], err);
};
// 回调数据
event.sender.send('request-' + opts['hash'], {
text: text,
buff: buff,
encoding: encoding
});
_datasuccess = true;
callback(null, ret);
});
}).on('error', (err) => {
if(_datasuccess == false) {
return event.sender.send('request-error-' + opts['hash'], err);
}
});
antstream.pipe(_request);
}else{
// 通过替换函数方式来实现发包方式切换, 后续可改成别的 // 通过替换函数方式来实现发包方式切换, 后续可改成别的
const old_send = _request.send; const old_send = _request.send;
if(opts['useMultipart'] == 1) { if(opts['useMultipart'] == 1) {
...@@ -153,6 +199,7 @@ class Request { ...@@ -153,6 +199,7 @@ class Request {
}); });
}); });
} }
}
/** /**
* 监听下载请求 * 监听下载请求
...@@ -181,6 +228,49 @@ class Request { ...@@ -181,6 +228,49 @@ class Request {
} }
// 自定义body // 自定义body
const _postData = Object.assign({}, opts.body, opts.data); const _postData = Object.assign({}, opts.body, opts.data);
if (opts['useChunk'] == 1){
logger.debug("request with Chunked");
let _postarr = [];
for(var key in _postData){
if(_postData.hasOwnProperty(key)){
_postarr.push(`${key}=${_postData[key]}`);
}
}
let antstream = new AntRead(_postarr.join("&"), {'step': parseInt(opts['chunkStepMin']), 'stepmax': parseInt(opts['chunkStepMax'])});
let _datasuccess = false; // 表示是否是 404 类shell
_request
.proxy(APROXY_CONF['uri'])
.type('form')
.ignoreHTTPS(opts['ignoreHTTPS'])
.pipe(through(
(chunk) => {
// 判断数据流中是否包含后截断符?长度++
let temp = chunk.indexOf(opts['tag_e']);
if (temp !== -1) {
indexEnd = Buffer.concat(tempData).length + temp;
};
tempData.push(chunk);
event.sender.send('download-progress-' + opts['hash'], chunk.length);
},
() => {
let tempDataBuffer = Buffer.concat(tempData);
indexStart = tempDataBuffer.indexOf(opts['tag_s']) || 0;
// 截取最后的数据
let finalData = new Buffer(tempDataBuffer.slice(
indexStart + opts['tag_s'].length,
indexEnd
), 'binary');
// 写入文件流&&关闭
rs.write(finalData);
rs.close();
event.sender.send('download-' + opts['hash'], finalData.length);
// 删除内存数据
finalData = tempDataBuffer = tempData = null;
}
));
antstream.pipe(_request);
}else{
// 通过替换函数方式来实现发包方式切换, 后续可改成别的 // 通过替换函数方式来实现发包方式切换, 后续可改成别的
const old_send = _request.send; const old_send = _request.send;
if(opts['useMultipart'] == 1) { if(opts['useMultipart'] == 1) {
...@@ -224,6 +314,7 @@ class Request { ...@@ -224,6 +314,7 @@ class Request {
} }
)); ));
} }
}
/** /**
* 二进制数据流解析 * 二进制数据流解析
...@@ -326,4 +417,59 @@ function detectEncoding(buffer, options) { ...@@ -326,4 +417,59 @@ function detectEncoding(buffer, options) {
} }
}; };
/**
* 控步长的可读流
* @param data [string|buffer] 输入源
* @param options {} 配置
* step 步长
* stepmax 最大步长,默认与步长相等,如果大于步长,则每次读取时后随机返回 [step, stepmax] 长度的数据
*/
class AntRead extends Readable {
constructor(data, options={}) {
super();
this.index = 0;
let o = {};
o.step = options.hasOwnProperty('step') ? parseInt(options['step']) : 2;
o.step = o.step < 1 ? 2 : o.step;
o.stepmax = options.hasOwnProperty('stepmax') ? options['stepmax'] : o.step ;
if (o.stepmax < o.step) {
o.stepmax = o.step;
}
let chunk;
if('string' === typeof data) {
chunk = data;
}else if('object' === typeof data && Buffer.isBuffer(data)) { // buffer
chunk = new Buffer(data).toString();
}else{
throw Error("data must be string, buffer.");
}
this.chunk = chunk;
this.o = o;
}
// 重写自定义的可读流的 _read 方法
_read() {
let step = this.randomNum(this.o.step, this.o.stepmax);
if (this.index >= this.chunk.length) {
this.push(null);
}else{
this.push(this.chunk.substring(this.index, this.index + step) + "");
}
this.index += step;
}
// random [n, m]
randomNum(minNum, maxNum){
switch(arguments.length){
case 1:
return parseInt(Math.random()*minNum+1,10);
case 2:
return parseInt(Math.random()*(maxNum-minNum+1)+minNum,10);
default:
return 0;
}
}
}
module.exports = Request; module.exports = Request;
{ {
"name": "antsword", "name": "antsword",
"version": "2.0.4", "version": "2.0.5",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
......
{ {
"name": "antsword", "name": "antsword",
"version": "2.0.4", "version": "2.0.5",
"description": "中国蚁剑是一款跨平台的开源网站管理工具", "description": "中国蚁剑是一款跨平台的开源网站管理工具",
"main": "app.js", "main": "app.js",
"dependencies": { "dependencies": {
......
...@@ -189,7 +189,7 @@ antSword['aproxyauth'] = ( ...@@ -189,7 +189,7 @@ antSword['aproxyauth'] = (
!aproxy['username'] || !aproxy['password'] !aproxy['username'] || !aproxy['password']
) ? '' : `${aproxy['username']}:${aproxy['password']}`; ) ? '' : `${aproxy['username']}:${aproxy['password']}`;
antSword['aproxyuri'] = `${aproxy['protocol']}:\/\/${antSword['aproxyauth']}@${aproxy['server']}:${aproxy['port']}`; antSword['aproxyuri'] = `${aproxy['protocol']}:\/\/${antSword['aproxyauth']}${antSword['aproxyauth']===""?"":"@"}${aproxy['server']}:${aproxy['port']}`;
// 通知后端设置代理 // 通知后端设置代理
ipcRenderer.send('aproxy', { ipcRenderer.send('aproxy', {
......
...@@ -245,6 +245,9 @@ class Base { ...@@ -245,6 +245,9 @@ class Base {
tag_e: opt['tag_e'], tag_e: opt['tag_e'],
encode: this.__opts__['encode'], encode: this.__opts__['encode'],
ignoreHTTPS: (this.__opts__['otherConf'] || {})['ignore-https'] === 1, ignoreHTTPS: (this.__opts__['otherConf'] || {})['ignore-https'] === 1,
useChunk: (this.__opts__['otherConf'] || {})['use-chunk'] === 1,
chunkStepMin: (this.__opts__['otherConf'] || {})['chunk-step-byte-min'] || 2,
chunkStepMax: (this.__opts__['otherConf'] || {})['chunk-step-byte-max'] || 3,
useMultipart: (this.__opts__['otherConf'] || {})['use-multipart'] === 1, useMultipart: (this.__opts__['otherConf'] || {})['use-multipart'] === 1,
timeout: parseInt((this.__opts__['otherConf'] || {})['request-timeout']), timeout: parseInt((this.__opts__['otherConf'] || {})['request-timeout']),
headers: (this.__opts__['httpConf'] || {})['headers'] || {}, headers: (this.__opts__['httpConf'] || {})['headers'] || {},
......
...@@ -106,6 +106,7 @@ module.exports = { ...@@ -106,6 +106,7 @@ module.exports = {
add: { add: {
title: 'Add shell', title: 'Add shell',
toolbar: { toolbar: {
test: 'Test Connection',
add: 'Add', add: 'Add',
clear: 'Clear' clear: 'Clear'
}, },
...@@ -117,6 +118,8 @@ module.exports = { ...@@ -117,6 +118,8 @@ module.exports = {
type: 'Shell type', type: 'Shell type',
encoder: 'Encoder' encoder: 'Encoder'
}, },
test_success: 'Connection Successful!',
test_warning: 'Response is null!',
warning: 'Please enter the full!', warning: 'Please enter the full!',
success: 'Add shell success!', success: 'Add shell success!',
error: (err) => antSword.noxss(`Add shell failed!\n${err}`) error: (err) => antSword.noxss(`Add shell failed!\n${err}`)
...@@ -169,6 +172,13 @@ module.exports = { ...@@ -169,6 +172,13 @@ module.exports = {
otherConf: { otherConf: {
nohttps: 'Ignore HTTPS certificate', nohttps: 'Ignore HTTPS certificate',
usemultipart: 'Use Multipart send payload', usemultipart: 'Use Multipart send payload',
chunk: {
title: 'Chunked Transfer (Experimentally)',
usechunk: 'Use Chunked send payload.',
min: 'Min Block',
max: 'Max Block',
exphint: 'This feature is currently experimental and cannot be used with Multipart. Some types of servers may not support Chunked transfers. In addition, it is recommended to set the timeout period to 30s or more to avoid data transmission when the network speed is not good.',
},
terminalCache: "Use the terminal's cache", terminalCache: "Use the terminal's cache",
filemanagerCache: "Use the filemanager's cache", filemanagerCache: "Use the filemanager's cache",
uploadFragment: "Upload File Fragmentation Size", uploadFragment: "Upload File Fragmentation Size",
...@@ -700,6 +710,7 @@ module.exports = { ...@@ -700,6 +710,7 @@ module.exports = {
}, },
viewsite: { viewsite: {
toolbar: { toolbar: {
useproxy: (s) => `Proxy: ${s?'ON':'OFF'}`,
save: 'Save', save: 'Save',
view: 'View' view: 'View'
}, },
......
...@@ -107,6 +107,7 @@ module.exports = { ...@@ -107,6 +107,7 @@ module.exports = {
add: { add: {
title: '添加数据', title: '添加数据',
toolbar: { toolbar: {
test: '测试连接',
add: '添加', add: '添加',
clear: '清空' clear: '清空'
}, },
...@@ -118,6 +119,8 @@ module.exports = { ...@@ -118,6 +119,8 @@ module.exports = {
type: '连接类型', type: '连接类型',
encoder: '编码器' encoder: '编码器'
}, },
test_success: '连接成功!',
test_warning: '返回数据为空',
warning: '请输入完整!', warning: '请输入完整!',
success: '添加数据成功!', success: '添加数据成功!',
error: (err) => antSword.noxss(`添加数据失败!\n${err}`) error: (err) => antSword.noxss(`添加数据失败!\n${err}`)
...@@ -170,6 +173,13 @@ module.exports = { ...@@ -170,6 +173,13 @@ module.exports = {
otherConf: { otherConf: {
nohttps: '忽略HTTPS证书', nohttps: '忽略HTTPS证书',
usemultipart: '使用 Multipart 发包', usemultipart: '使用 Multipart 发包',
chunk: {
title: '分块传输(实验性功能)',
usechunk: '开启分块传输发包',
min: '最小分块',
max: '最大分块',
exphint: '该功能目前为实验性功能, 无法与 Multipart 同时使用,部分类型的服务端可能不支持Chunked传输。此外,建议超时时长设置30s以上,避免网速不好的情况下影响数据传输。',
},
terminalCache: '虚拟终端使用缓存', terminalCache: '虚拟终端使用缓存',
filemanagerCache: '文件管理使用缓存', filemanagerCache: '文件管理使用缓存',
uploadFragment: '上传文件分片大小', uploadFragment: '上传文件分片大小',
...@@ -700,6 +710,7 @@ module.exports = { ...@@ -700,6 +710,7 @@ module.exports = {
}, },
viewsite: { viewsite: {
toolbar: { toolbar: {
useproxy: (s) => `代理: ${s?'开':'关'}`,
save: '保存', save: '保存',
view: '浏览' view: '浏览'
}, },
......
...@@ -1503,7 +1503,6 @@ class PHP { ...@@ -1503,7 +1503,6 @@ class PHP {
dumpResult() { dumpResult() {
const grid = this.manager.result.layout.getAttachedObject(); const grid = this.manager.result.layout.getAttachedObject();
let filename = `${this.core.__opts__.ip}_${new Date().format("yyyyMMddhhmmss")}.csv`; let filename = `${this.core.__opts__.ip}_${new Date().format("yyyyMMddhhmmss")}.csv`;
antSword['test'] = this;
dialog.showSaveDialog({ dialog.showSaveDialog({
title: LANG['result']['dump']['title'], title: LANG['result']['dump']['title'],
defaultPath: filename defaultPath: filename
......
...@@ -809,6 +809,7 @@ class FileManager { ...@@ -809,6 +809,7 @@ class FileManager {
let editor = null; let editor = null;
let codes = ''; let codes = '';
let win; let win;
let hinttext = '';
if (openfileintab == false){ if (openfileintab == false){
win = this.createWin({ win = this.createWin({
title: LANG['editor']['title'](path), title: LANG['editor']['title'](path),
...@@ -823,6 +824,7 @@ class FileManager { ...@@ -823,6 +824,7 @@ class FileManager {
null, null, true, true null, null, true, true
); );
win = antSword['tabbar'].cells(`tab_file_${_id}`); win = antSword['tabbar'].cells(`tab_file_${_id}`);
hinttext = `IP:${this.opts['ip']} File:${path}`;
} }
win.progressOn(); win.progressOn();
...@@ -854,9 +856,11 @@ class FileManager { ...@@ -854,9 +856,11 @@ class FileManager {
_options.push(_opt); _options.push(_opt);
} }
toolbar.loadStruct([ toolbar.loadStruct([
{ id: 'save', type: 'button', icon: 'save', text: LANG['editor']['toolbar']['save'] }, { id: 'hinttext', type: 'text', text: hinttext},
{ type: 'separator' }, { type: 'separator' },
{ type: 'spacer' }, { type: 'spacer' },
{ id: 'save', type: 'button', icon: 'save', text: LANG['editor']['toolbar']['save'] },
{ type: 'separator' },
{ {
id: 'encode', type: 'buttonSelect', icon: 'language', openAll: true, id: 'encode', type: 'buttonSelect', icon: 'language', openAll: true,
text: LANG['editor']['toolbar']['encode'], text: LANG['editor']['toolbar']['encode'],
......
...@@ -39,10 +39,17 @@ class Plugin { ...@@ -39,10 +39,17 @@ class Plugin {
win.on('close', () => { win.on('close', () => {
this.win = win = null; this.win = win = null;
}); });
let ses = win.webContents.session;
let proxyuri = "";
if(antSword.aproxymode != "noproxy") {
proxyuri = antSword.aproxyuri;
}
ses.setProxy({proxyRules: proxyuri}, ()=>{
win.loadURL(url); win.loadURL(url);
win.show(); win.show();
// win.openDevTools(); // win.openDevTools();
this.win = win; this.win = win;
});
} }
......
...@@ -27,9 +27,51 @@ class Form { ...@@ -27,9 +27,51 @@ class Form {
// toolbar点击事件 // toolbar点击事件
this.toolbar.attachEvent('onClick', (id) => { this.toolbar.attachEvent('onClick', (id) => {
if (id === 'clear') { switch(id){
return this.baseForm.clear(); case 'clear':
this.baseForm.clear();
break;
case 'test':
if (
!this.baseForm.validate() ||
!this.httpForm.validate() ||
!this.otherForm.validate()
) {
return toastr.warning(LANG['list']['add']['warning'], LANG_T['warning']);
};
let opts = this._parseFormData(
this.baseForm.getValues(),
this.httpForm.getValues(),
this.otherForm.getValues()
);
let opt = {
"url": opts.base['url'],
"pwd": opts.base['pwd'],
"type": opts.base['type'],
"encode": opts.base['encode'],
"encoder": opts.base['encoder'],
"httpConf": opts.http,
"otherConf": opts.other,
}
win.progressOn();
let core = new antSword["core"][opt['type']](opt);
core.request(
core.base.info()
)
.then((ret) => {
if(ret['text'].length > 0){
toastr.success(LANG['list']['add']['test_success'], LANG_T['success']);
}else{
toastr.warning(LANG['list']['add']['test_warning'], LANG_T['warning']);
} }
win.progressOff();
})
.catch((err)=>{
toastr.error(JSON.stringify(err), LANG_T['error']);
win.progressOff();
});
break;
case 'act':
// 检测表单数据 // 检测表单数据
if ( if (
!this.baseForm.validate() || !this.baseForm.validate() ||
...@@ -57,6 +99,10 @@ class Form { ...@@ -57,6 +99,10 @@ class Form {
}); });
}, 100); }, 100);
}; };
break;
default:
break;
}
}); });
} }
...@@ -109,7 +155,10 @@ class Form { ...@@ -109,7 +155,10 @@ class Form {
type: 'button', type: 'button',
icon: 'remove', icon: 'remove',
text: LANG['list']['add']['toolbar']['clear'] text: LANG['list']['add']['toolbar']['clear']
}]); },
{ type: 'separator' },
{ id: 'test', type: 'button', 'icon': 'spinner', text: LANG['list']['add']['toolbar']['test'] },
]);
return toolbar; return toolbar;
} }
...@@ -318,6 +367,9 @@ class Form { ...@@ -318,6 +367,9 @@ class Form {
const opt = Object.assign({}, { const opt = Object.assign({}, {
'ignore-https': 0, 'ignore-https': 0,
'use-multipart': 0, 'use-multipart': 0,
'use-chunk': 0,
'chunk-step-byte-min': 2,
'chunk-step-byte-max': 3,
'terminal-cache': 0, 'terminal-cache': 0,
'filemanager-cache': 1, 'filemanager-cache': 1,
'upload-fragment': '500', 'upload-fragment': '500',
...@@ -334,7 +386,60 @@ class Form { ...@@ -334,7 +386,60 @@ class Form {
}, { }, {
type: "checkbox", name: 'use-multipart', label: LANG['list']['otherConf']['usemultipart'], type: "checkbox", name: 'use-multipart', label: LANG['list']['otherConf']['usemultipart'],
checked: opt['use-multipart'] === 1 checked: opt['use-multipart'] === 1
}, { }, { type: 'fieldset', offsetLeft: 0, label: LANG['list']['otherConf']['chunk']['title'], list: [
{ type: 'block', offsetLeft: 0, list: [
{
type: "checkbox", name: 'use-chunk', label: LANG['list']['otherConf']['chunk']['usechunk'], checked: opt['use-chunk'] === 1
},
]},
{ type: 'block', offsetLeft: 0, list: [
{ type:'label', label: LANG['list']['otherConf']['chunk']['min']},
{ type:'newcolumn' },
{
type: 'combo', label: '/byte', validate: 'ValidNumeric', inputWidth: 50, name: "chunk-step-byte-min",
options: ((items) => {
let ret = [];
// 如果自定义的路径不在items里,则++
if (items.indexOf(opt['chunk-step-byte-min']) === -1) {
items.unshift(opt['chunk-step-byte-min']);
}
items.map((_) => {
ret.push({
text: _,
value: _,
selected: opt['chunk-step-byte-min'] === _
})
});
return ret;
})([
'2', '4', '10', '50', '100', '500'
])
},
{ type:'newcolumn',},
{ type:'label', label: LANG['list']['otherConf']['chunk']['max'], offsetLeft: 30,},
{ type:'newcolumn' },
{
type: 'combo', label: '/byte', validate: 'ValidNumeric', inputWidth: 50, name: "chunk-step-byte-max",
options: ((items) => {
let ret = [];
// 如果自定义的路径不在items里,则++
if (items.indexOf(opt['chunk-step-byte-max']) === -1) {
items.unshift(opt['chunk-step-byte-max']);
}
items.map((_) => {
ret.push({
text: _,
value: _,
selected: opt['chunk-step-byte-max'] === _
})
});
return ret;
})([
'2', '4', '10', '50', '100', '500'
])
},
]},
]}, {
type: "checkbox", name: 'terminal-cache', label: LANG['list']['otherConf']['terminalCache'], type: "checkbox", name: 'terminal-cache', label: LANG['list']['otherConf']['terminalCache'],
checked: opt['terminal-cache'] === 1 checked: opt['terminal-cache'] === 1
}, { }, {
...@@ -405,6 +510,28 @@ class Form { ...@@ -405,6 +510,28 @@ class Form {
]) ])
} }
]}], true); ]}], true);
form.attachEvent('onChange', (name, value, state)=>{
switch(name){
case 'use-multipart':
if(state == true && form.isItemChecked('use-chunk')) {
form.uncheckItem('use-chunk');
}
break;
case 'use-chunk':
if(state == true && form.isItemChecked('use-multipart')) {
form.uncheckItem('use-multipart');
}
if(state == true) {
layer.open({
title: LANG_T['info']
,content: LANG['list']['otherConf']['chunk']['exphint']
});
}
break;
default:
break;
}
});
return form; return form;
} }
......
...@@ -24,7 +24,7 @@ class ViewSite { ...@@ -24,7 +24,7 @@ class ViewSite {
this.opts = opts; this.opts = opts;
this.cell = tabbar.cells(`tab_viewsite_${hash}`); this.cell = tabbar.cells(`tab_viewsite_${hash}`);
this.useproxy = antSword.aproxymode !== "noproxy";
// 初始化工具栏 // 初始化工具栏
this.toolbar = this._initToolbar(); this.toolbar = this._initToolbar();
...@@ -52,10 +52,21 @@ class ViewSite { ...@@ -52,10 +52,21 @@ class ViewSite {
const toolbar = this.cell.attachToolbar(); const toolbar = this.cell.attachToolbar();
toolbar.loadStruct([ toolbar.loadStruct([
{ id: 'url', width: 400, type: 'buttonInput', value: this.opts.url || 'loading..' }, { id: 'url', width: 400, type: 'buttonInput', value: this.opts.url || 'loading..' },
{ type: 'separator' },
{ id: 'useproxy', type: 'buttonTwoState', icon: 'paper-plane', text: LANG['toolbar'].useproxy(this.useproxy), pressed: this.useproxy, disabled: antSword.aproxymode === "noproxy"},
{ type: 'separator' },
{ id: 'view', type: 'button', icon: 'chrome', text: LANG['toolbar'].view }, { id: 'view', type: 'button', icon: 'chrome', text: LANG['toolbar'].view },
{ type: 'separator' }, { type: 'separator' },
{ id: 'save', type: 'button', icon: 'save', text: LANG['toolbar'].save }, { id: 'save', type: 'button', icon: 'save', text: LANG['toolbar'].save },
]); ]);
toolbar.attachEvent('onStateChange', (id, state) => {
switch(id) {
case 'useproxy':
this.useproxy = state;
toolbar.setItemText('useproxy', `<i class="fa fa-paper-plane"></i> ${LANG['toolbar'].useproxy(this.useproxy)}`);
break;
}
});
toolbar.attachEvent('onClick', (id) => { toolbar.attachEvent('onClick', (id) => {
switch(id) { switch(id) {
case 'save': case 'save':
...@@ -171,9 +182,19 @@ class ViewSite { ...@@ -171,9 +182,19 @@ class ViewSite {
}, },
title: url title: url
}); });
win.on('close', () => {
win = null;
});
let ses = win.webContents.session;
let proxyuri = "";
if(this.useproxy && antSword.aproxymode != "noproxy") {
proxyuri = antSword.aproxyuri;
}
ses.setProxy({proxyRules: proxyuri}, ()=>{
win.loadURL(url); win.loadURL(url);
win.show(); win.show();
win.openDevTools(); win.openDevTools();
});
} }
} }
......
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment