pull/115/head
soxft 3 years ago
parent 01362c76f9
commit a119b9847d
  1. 124
      class/core/site_api.py
  2. 4
      data/tpl/nginx.conf
  3. 163
      route/static/app/site.js

@ -6,15 +6,11 @@ import sys
import mw
import re
import json
import pwd
import shutil
import psutil
from flask import request
# request.urllib3.disable_warnings()
class site_api:
siteName = None # 网站名称
@ -27,6 +23,7 @@ class site_api:
logsPath = None
passPath = None
rewritePath = None
redirectPath = None
sslDir = None # ssl目录
def __init__(self):
@ -41,6 +38,10 @@ class site_api:
self.passPath = self.setupPath + '/nginx/pass'
# if not os.path.exists(pp):
# mw.execShell("mkdir -p " + rw + " && chmod -R 755 " + rw)
self.redirectPath = self.setupPath + '/nginx/redirect'
if not os.path.exists(self.redirectPath):
mw.execShell("mkdir -p " + self.redirectPath + " && chmod -R 755 " + self.redirectPath)
self.logsPath = mw.getRootDir() + '/wwwlogs'
# ssl conf
@ -1170,6 +1171,61 @@ class site_api:
webname = request.form.get('webname', '')
path = request.form.get('path', '0')
return self.delete(sid, webname, path)
## get_redirect_status
def getRedirectStatusApi(self):
_siteName = request.form.get("siteName",'')
# read data base
data_path = self.getRedirectDataPath(_siteName)
data_content = mw.readFile(data_path)
if data_content == False:
return mw.returnJson(True, "", {"result": [], "count": 0})
# get
# conf_path = "{}/{}/*.conf".format(self.redirectPath, siteName)
# conf_list = glob.glob(conf_path)
# if conf_list == []:
# return mw.returnJson(True, "", {"result": [], "count": 0})
try:
data = json.loads(data_content)
except:
mw.execShell("rm -rf {}/{}".format(self.redirectPath, _siteName))
return mw.returnJson(True, "", {"result": [], "count": 0})
# 处理301信息
return mw.returnJson(True, "ok", {"result": data, "count": len(data)})
# get redirect status
def setRedirectStatusApi(self):
_siteName = request.form.get("siteName",'')
_from = request.form.get("from",'') # from (example.com / /test/)
_to = request.form.get("to",'') # redirect to
_type = request.form.get("type",'') # path / domain
_rType = request.form.get("r_type",'') # redirect type
if _siteName == '' or _from == '' or _to == '' or _type == '' or _rType == '':
return mw.returnJson(False, "必填项不能为空!")
data_path = self.getRedirectDataPath(_siteName)
data_content = mw.readFile(data_path) if os.path.exists(data_path) else ""
data = json.loads(data_content) if data_content != "" else {}
if _rType == "301":
_rType = 0
else:
_rType = 1
if _type == "path":
_type = 0
else:
_type = 1
data.append({"from": _from, "type": _type, "r_type": _rType, "r_to": _to})
mw.writeFile(data_path, json.dumps(data))
return mw.returnJson(True, "ok")
def getProxyListApi(self):
siteName = request.form.get('siteName', '')
@ -1179,31 +1235,6 @@ class site_api:
url_rep = "proxy_pass (.*);|ProxyPass\s/\s(.*)|Host\s(.*);"
host_rep = "Host\s(.*);"
if re.search(rep, old_conf):
# 构造代理配置
if w == "nginx":
get.todomain = str(re.search(host_rep, old_conf).group(1))
get.proxysite = str(re.search(url_rep, old_conf).group(1))
else:
get.todomain = ""
get.proxysite = str(re.search(url_rep, old_conf).group(2))
get.proxyname = "旧代理"
get.type = 1
get.proxydir = "/"
get.advanced = 0
get.cachetime = 1
get.cache = 0
get.subfilter = "[{\"sub1\":\"\",\"sub2\":\"\"},{\"sub1\":\"\",\"sub2\":\"\"},{\"sub1\":\"\",\"sub2\":\"\"}]"
# proxyname_md5 = self.__calc_md5(get.proxyname)
# 备份并替换老虚拟主机配置文件
os.system("cp %s %s_bak" % (conf_path, conf_path))
conf = re.sub(rep, "", old_conf)
mw.writeFile(conf_path, conf)
# self.createProxy(get)
mw.restartWeb()
proxyUrl = self.__read_config(self.__proxyfile)
sitename = sitename
proxylist = []
@ -1363,6 +1394,9 @@ class site_api:
def getRewriteConf(self, siteName):
return self.rewritePath + '/' + siteName + '.conf'
def getRedirectDataPath(self, siteName):
return "{}/{}/data.json".format(self.redirectPath, siteName)
def getDirBindRewrite(self, siteName, dirname):
return self.rewritePath + '/' + siteName + '_' + dirname + '.conf'
@ -1526,13 +1560,9 @@ class site_api:
def getSecurity(self, sid, name):
filename = self.getHostConf(name)
conf = mw.readFile(filename)
if type(conf) == bool:
return mw.returnJson(False, '读取配置文件失败!')
data = {}
if conf.find('SECURITY-START') != -1:
rep = "#SECURITY-START(.|\n)*#SECURITY-END"
rep = "#SECURITY-START(\n|.){1,500}#SECURITY-END"
tmp = re.search(rep, conf).group()
data['fix'] = re.search(
"\(.+\)\$", tmp).group().replace('(', '').replace(')$', '').replace('|', ',')
@ -1557,22 +1587,22 @@ class site_api:
if os.path.exists(file):
conf = mw.readFile(file)
if conf.find('SECURITY-START') != -1:
rep = "\s{0,4}#SECURITY-START(\n|.)*#SECURITY-END\n?"
rep = "\s{0,4}#SECURITY-START(\n|.){1,500}#SECURITY-END\n?"
conf = re.sub(rep, '', conf)
mw.writeLog('网站管理', '站点[' + name + ']已关闭防盗链设置!')
else:
rconf = '''#SECURITY-START 防盗链配置
location ~ .*\.(%s)$
{
expires 30d;
access_log /dev/null;
valid_referers none blocked %s;
if ($invalid_referer){
return 404;
}
location ~ .*\.(%s)$
{
expires 30d;
access_log /dev/null;
valid_referers none blocked %s;
if ($invalid_referer){
return 404;
}
#SECURITY-END
include enable-php-''' % (fix.strip().replace(',', '|'), domains.strip().replace(',', ' '))
}
# SECURITY-END
include enable-php-''' % (fix.strip().replace(',', '|'), domains.strip().replace(',', ' '))
conf = re.sub("include\s+enable-php-", rconf, conf)
mw.writeLog('网站管理', '站点[' + name + ']已开启防盗链!')
mw.writeFile(file, conf)
@ -1623,8 +1653,6 @@ class site_api:
os.makedirs(path)
if not mw.isAppleSystem():
mw.execShell('chown -R www:www ' + path)
mw.writeFile(path + '/index.html', '已经开始工作!!!')
mw.execShell('chmod -R 755 ' + path)
def nginxAddDomain(self, webname, domain, port):
@ -1876,4 +1904,4 @@ location /{
def strfToTime(self, sdate):
import time
return time.strftime('%Y-%m-%d', time.strptime(sdate, '%b %d %H:%M:%S %Y %Z'))
# ssl相关方法 end
# ssl相关方法 end

@ -21,6 +21,10 @@ server
#REWRITE-START
include {$OR_REWRITE}/{$SERVER_NAME}.conf;
#REWRITE-END
#301-START
include /redirect/{$SERVER_NAME}/*.conf;
##301-END
#禁止访问的文件或目录
location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md)

@ -3,7 +3,7 @@
* @param {Number} page 当前页
* @param {String} search 搜索条件
*/
function getWeb(page, search, type_id) {
function getWeb(page, search, type_id) {
search = $("#SearchValue").prop("value");
page = page == undefined ? '1':page;
var order = getCookie('order');
@ -993,8 +993,8 @@ function webEdit(id,website,endTime,addtime){
+"<p onclick=\"configFile('"+website+"')\" title='配置文件'>配置文件</p>"
+"<p onclick=\"setSSL("+id+",'"+website+"')\" title='SSL'>SSL</p>"
+"<p onclick=\"phpVersion('"+website+"')\" title='PHP版本'>PHP版本</p>"
// +"<p onclick=\"to301('"+website+"')\" title='重定向'>重定向</p>"
// +"<p onclick=\"proxyList('"+website+"')\" title='反向代理'>反向代理</p>"
+"<p onclick=\"to301('"+website+"')\" title='重定向'>重定向</p>"
+"<p onclick=\"proxyList('"+website+"')\" title='反向代理'>反向代理</p>"
+"<p id='site_"+id+"' onclick=\"security('"+id+"','"+website+"')\" title='防盗链'>防盗链</p>"
+"<p id='site_"+id+"' onclick=\"getSiteLogs('"+website+"')\" title='查看站点请求日志'>响应日志</p>";
layer.open({
@ -1085,7 +1085,7 @@ function setSecurity(name,id){
$.post('/site/set_security',data,function(rdata){
layer.close(loadT);
layer.msg(rdata.msg,{icon:rdata.status?1:2});
if(rdata.status) setTimeout(function(){security(id,name);},1000);
if(rdata.status) setTimeout(function(){Security(id,name);},1000);
},'json');
}
@ -1421,47 +1421,125 @@ function openCache(siteName){
}
//301重定向
function to301(siteName,type){
if(type == 1){
type = $("input[name='status']").attr('checked')?'0':'1';
toUrl = encodeURIComponent($("input[name='toUrl']").val());
srcDomain = encodeURIComponent($("select[name='srcDomain']").val());
var data = 'siteName='+siteName+'&type='+type+'&toDomain='+toUrl+'&srcDomain='+srcDomain;
$.post('site?action=Set301Status',data,function(rdata){
To301(siteName);
layer.msg(rdata.msg,{icon:rdata.status?1:2});
function to301(siteName, type, obj){
// 设置 页面展示
// 设置 更新展示
if(type == 1 || type == 3){
obj = {
redirectname: (new Date()).valueOf(),
tourl: 'http://',
redirectdomain: [],
redirectpath: '',
redirecttype: '',
type: 1,
domainorpath: 'domain',
holdpath: 1
}
layer.open({
type: 1,
skin: 'demo-class',
area: '650px',
title: type == 1 ? '创建重定向' : '修改重定向[' + obj.redirectname + ']',
closeBtn: 2,
shift: 5,
shadeClose: false,
content: "<form id='form_redirect' class='divtable pd20' style='padding-bottom: 60px'>" +
"<div class='line' style='overflow:hidden;height: 40px;'>" +
"<div style='display: inline-block;'>" +
"<span class='tname' style='margin-left:10px;position: relative;top: -5px;'>保留URI参数</span>" +
"<input class='btswitch btswitch-ios' id='holdpath' type='checkbox' name='holdpath' " + (obj.holdpath == 1 ? 'checked="checked"' : '') + " /><label class='btswitch-btn phpmyadmin-btn' for='holdpath' style='float:left'></label>" +
"</div>" +
"</div>" +
"<div class='line' style='clear:both;display:none;'>" +
"<span class='tname'>重定向名称</span>" +
"<div class='info-r ml0'><input name='redirectname' class='bt-input-text mr5' " + (type == 1 ? '' : 'disabled="disabled"') + " type='text' style='width:300px' value='" + obj.redirectname + "'></div>" +
"</div>" +
"<div class='line' style='clear:both;'>" +
"<span class='tname'>重定向类型</span>" +
"<div class='info-r ml0'>" +
"<select class='bt-input-text mr5' name='type' style='width:100px'><option value='domain' " + (obj.domainorpath == 'domain' ? 'selected ="selected"' : "") + ">域名</option><option value='path' " + (obj.domainorpath == 'path' ? 'selected ="selected"' : "") + ">路径</option></select>" +
"<span class='mlr15'>重定向方式</span>" +
"<select class='bt-input-text ml10' name='redirecttype' style='width:100px'><option value='301' " + (obj.redirecttype == '301' ? 'selected ="selected"' : "") + " >301</option><option value='302' " + (obj.redirecttype == '302' ? 'selected ="selected"' : "") + ">302</option></select></div>" +
"</div>" +
"<div class='line redirectdomain'>" +
"<span class='tname'>重定向源</span>" +
"<div class='info-r ml0'>" +
"<input name='redirectpath' placeholder='域名或路径' class='bt-input-text mr5' type='text' style='width:200px;float: left;margin-right:0px' value='" + obj.redirectpath + "'>" +
"<span class='tname' style='width:90px'>目标URL</span>" +
"<input name='tourl' class='bt-input-text mr5' type='text' style='width:200px' value='" + obj.tourl + "'>" +
"</div>" +
"</div>" +
"</div>" +
"<div class='bt-form-submit-btn'><button type='button' class='btn btn-sm btn-danger btn-colse-prosy'>关闭</button><button type='button' class='btn btn-sm btn-success btn-submit-redirect'>" + (type == 1 ? " 提交" : "保存") + "</button></div>" +
"</form>"
});
return;
setTimeout(function() {
$('.btn-colse-prosy').click(function() {
form_redirect.close();
});
$('.btn-submit-redirect').click(function() {
var holdpath = $('[name="holdpath"]').prop('checked') ? 1 : 0;
var redirectname = $('[name="redirectname"]').val();
var redirecttype = $('[name="redirecttype"]').val();
var type = $('[name="type"]').val();
var redirectpath = $('[name="redirectpath"]').val();
var redirectdomain = JSON.stringify($('.selectpicker').val() || []);
var tourl = $(domainorpath == 'path' ? '[name="tourl1"]' : '[name="tourl"]').val();
console.log(type, holdpath, redirectname, redirecttype, domainorpath, redirectpath, redirectdomain, tourl);
});
}, 100);
}
// 设置 提交
// 设置 更新 提交
var body = '<div id="redirect_list" class="bt_table">\
<div style="padding-bottom: 10px">\
<button type="button" title="添加重定向" class="btn btn-success btn-sm mr5" onclick="to301(\''+siteName+'\',1)" ><span>添加重定向</span></button>\
</div>\
<div class="divtable" style="max-height:200px;">\
<table class="table table-hover" >\
<thead style="position: relative;z-index: 1;">\
<tr>\
<th><span data-index="1"><span>重定向类型</span></span></th>\
<th><span data-index="2"><span>重定向方式</span></span></th>\
<th><span data-index="3"><span>保留URL参数</span></span></th>\
<th><span data-index="4"><span>操作</span></span></th>\
</tr>\
</thead>\
<tbody id="md-301-body">\
</tbody>\
</table>\
</div>\
</div>';
$("#webedit-con").html(body);
var loadT = layer.msg(lan.site.the_msg,{icon:16,time:0,shade: [0.3, '#000']});
$.post('/site?action=Get301Status','siteName='+siteName,function(rdata){
$.post('/site/get_redirect_status','siteName='+siteName, function(response) {
layer.close(loadT);
var domain_tmp = rdata.domain.split(',');
var domains = '';
var selected = '';
for(var i=0;i<domain_tmp.length;i++){
selected = '';
if(domain_tmp[i] == rdata.src) selected = 'selected';
domains += "<option value='"+domain_tmp[i]+"' "+selected+">"+domain_tmp[i]+"</option>";
$("#md-301-loading").remove();
let res = JSON.parse(response);
if (res.status === true) {
let data = res.data.result;
data.forEach(function(item){
lan_r_type = item.r_type == 0 ? "永久重定向" : "临时重定向"
let tmp = '<tr>\
<td><span data-index="1"><span>'+item.from+'</span></span></td>\
<td><span data-index="2"><span>'+lan_r_type+'</span></span></td>\
<td><span data-index="2"><span>'+lan_r_type+'</span></span></td>\
<td><span data-index="4">编辑</span></td>\
</tr>';
$("#md-301-body").append(tmp);
})
} else {
layer.msg(res.msg, {icon:2});
}
if(rdata.url == null) rdata.url = '';
var status_selected = rdata.status?'checked':'';
var isRead = rdata.status?'readonly':'';
var body = "<div>"
+"<p style='margin-bottom:8px'><span style='display: inline-block; width: 90px;'>"+lan.site.access_domain+"</span><select class='bt-input-text' name='srcDomain' style='margin-left: 5px;width: 380px;height: 30px;margin-right:10px;"+(rdata.status?'background-color: #eee;':'')+"' "+(rdata.status?'disabled':'')+"><option value='all'>"+lan.site.all_site+"</option>"+domains+"</select></p>"
+"<p style='margin-bottom:8px'><span style='display: inline-block; width: 90px;'>"+lan.site.target_url+"</span><input class='bt-input-text' type='text' name='toUrl' value='"+rdata.url+"' style='margin-left: 5px;width: 380px;height: 30px;margin-right:10px;"+(rdata.status?'background-color: #eee;':'')+"' placeholder='"+lan.site.eg_url+"' "+isRead+" /></p>"
+'<div class="label-input-group ptb10"><label style="font-weight:normal"><input type="checkbox" name="status" '+status_selected+' onclick="To301(\''+siteName+'\',1)" />'+lan.site.enable_301+'</label></div>'
+'<ul class="help-info-text c7 ptb10">'
+'<li>'+lan.site.to301_help_1+'</li>'
+'<li>'+lan.site.to301_help_2+'</li>'
+'</ul>'
+"</div>";
$("#webedit-con").html(body);
});
}
//文件验证
// function file_check(){
// $(".check_message").html('<div style="margin-left:100px">\
@ -2268,13 +2346,4 @@ function tryRestartPHP(siteName){
layer.msg(data.msg,{icon:data.status?1:2,time:3000,shade: [0.3, '#000']});
},'json');
},'json');
}
}
Loading…
Cancel
Save