From 0331af549de419b2e4bfdce9b4bf8ddbf3b8d6ed Mon Sep 17 00:00:00 2001 From: HITSword Date: Thu, 9 Jan 2020 17:21:19 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: HITSword --- .gitignore | 1 + AMHScript | 2 +- conf/no_cache_template.conf.txt | 18 + conf/proxy_cache_template.conf.txt | 26 ++ hyproxy-cli.php | 578 ++++++++++++++++------------- 5 files changed, 357 insertions(+), 268 deletions(-) create mode 100644 .gitignore create mode 100644 conf/no_cache_template.conf.txt create mode 100644 conf/proxy_cache_template.conf.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..485dee6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea diff --git a/AMHScript b/AMHScript index e0b2639..62dd3d2 100644 --- a/AMHScript +++ b/AMHScript @@ -247,7 +247,7 @@ function amh_module_admin() elif [ "$action" == 'del' ]; then php ${module_dir}hyproxy-cli.php --action='del' --server_name=${domain} - rm -f "$domain_conf" && echo "[OK] successfully delete $domain HYProxy."; + echo "[OK] successfully delete $domain HYProxy."; amh nginx reload; elif [ "$action" == 'start' ]; then php ${module_dir}hyproxy-cli.php --action='edit' --server_name=${domain} --field_name='status' --value='start'; diff --git a/conf/no_cache_template.conf.txt b/conf/no_cache_template.conf.txt new file mode 100644 index 0000000..efe8c66 --- /dev/null +++ b/conf/no_cache_template.conf.txt @@ -0,0 +1,18 @@ +#禁用反向代理缓存模板 +server { + listen 80; + listen [::]:80; + server_name {$server_name}; + index {$index}; + + location / { + default_type text/html; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host {$header_host}; + proxy_pass {$proxy_pass}; + } + + access_log {$logs_path}.access.log combined; #access_log end + error_log {$logs_path}.error.log crit; #error_log end +} \ No newline at end of file diff --git a/conf/proxy_cache_template.conf.txt b/conf/proxy_cache_template.conf.txt new file mode 100644 index 0000000..2a8016e --- /dev/null +++ b/conf/proxy_cache_template.conf.txt @@ -0,0 +1,26 @@ +#启用反向代理缓存模板 +server { + listen 80; + listen [::]:80; + server_name {$server_name}; + index {$index}; + + location / { + default_type text/html; + proxy_cache hyproxy; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host {$header_host}; + proxy_pass {$proxy_pass}; + if ($http_Cache_Control = "no-cache") { + rewrite ^(.*)$ /purge$1 last; + } + } + + location ~ /purge(/.*){ + proxy_cache_purge hyproxy $scheme://$host$1$is_args$args; + } + + access_log {$logs_path}.access.log combined; #access_log end + error_log {$logs_path}.error.log crit; #error_log end +} \ No newline at end of file diff --git a/hyproxy-cli.php b/hyproxy-cli.php index 56304fa..6cfddb2 100644 --- a/hyproxy-cli.php +++ b/hyproxy-cli.php @@ -1,278 +1,322 @@ 'mysql', - 'database_name' => $Config['DBname'], - 'server' => 'localhost', - 'username' => $Config['User'], - 'password' => $Config['Password'], - 'charset' => 'utf8' - ); - $medoo = new medoo($HYConfig); - -$opt = array( - 'action:', - 'proxy_status::',//状态 - 'server_name::',//域名 - 'proxy_pass::',//后端 - 'field_name::',//字段名 - 'value::',//字段内容 -); -$param = getopt('', $opt); -//print_r($param); -switch ($param['action']) { - case 'list': - echo hyproxy_list($param['proxy_status']); - break; - case 'make': - echo hyproxy_make($param['server_name']); - break; - case 'add': - echo hyproxy_add($param['server_name'],$param['proxy_pass']); - break; - case 'edit': - echo hyproxy_edit($param['server_name'],$param['field_name'],$param['value']); - break; - case 'del': - echo hyproxy_del($param['server_name']); - break; - default: - echo 'error action'; -} - -function hyproxy_list($proxy_status){//done 列出站点列表ID,域名,状态 - global $medoo; - empty($proxy_status) && $proxy_status = 'start'; - - $table = 'module_hyproxy'; - $columns = array('hyproxy_id','server_name','status'); - $where = array('status'=>$proxy_status); - $data = $medoo->select($table,$columns,$where); - $res = ''; - foreach ($data as &$value) { - $res.=sprintf("%d,%s,%s\n",$value['hyproxy_id'],$value['server_name'],$value['status']); - } - return $res; -} - -function hyproxy_make($server_name){//done - global $medoo; - $table = 'module_hyproxy'; - $columns = '*'; - $where = ''; - if (!empty($server_name)) {//指定域名 - $where = array('server_name'=>trim($server_name)); - } - $data = $medoo->select($table,$columns,$where); - $res = ''; - if (empty($data)) { - $res = "[ERROR] The server_name does not exist.\n"; - } else { - if (empty($server_name)) { - hy_deldir(_HYCONF);//删除所有 + /** + * HYPorxy CLI 文件 + * 依赖PDO 、InnoDB + * 需要安装PDO_MYSQL-1.0.2插件 + * 需要打开InnoDB支持 + */ + if (PHP_SAPI !== "cli") { + header('HTTP/1.1 404 Not Found'); + header("status: 404 Not Found"); + die(); } - foreach ($data as &$value) { - if (!empty($value['proxy_cache'])) { - $nginx = sprintf('server { - listen 80; - listen [::]:80; - server_name %s; - index %s; + define('DS', DIRECTORY_SEPARATOR); // 目录分隔符 + define('AMH_ROOT', '/home/wwwroot/index/web' . DS); // AHM根目录 + define('AMH_AMYSQL', AMH_ROOT . 'Amysql' . DS); // 系统目录 + define('_HYPROXY', dirname(__FILE__) . DS); // HYProxy插件根目录 + define('_HYCONF', '/usr/local/nginx/conf/hyproxy' . DS); // HYProxy Nginx conf目录 + define('_HYLOGS', '/usr/local/nginx/logs' . DS); // HYProxy Nginx logs目录 - location / { - default_type text/html; - proxy_cache hyproxy; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header Host %s; - proxy_pass %s; - if ($http_Cache_Control = "no-cache") { - rewrite ^(.*)$ /purge$1 last; - } - } - - location ~ /purge(/.*){ - proxy_cache_purge hyproxy $scheme://$host$1$is_args$args; - } - access_log /usr/local/nginx/logs/%s.access.log combined; #access_log end - error_log /usr/local/nginx/logs/%s.error.log crit; #error_log end -}',$value['server_name'],$value['index'],$value['header_host'],$value['proxy_pass'],$value['server_name'],$value['server_name']); - } else { - $nginx = sprintf('server { - listen 80; - listen [::]:80; - server_name %s; - index %s; + require_once(AMH_AMYSQL . 'Config.php'); //加载配置参数 + require_once(_HYPROXY . 'Class/medoo.php'); //加载medoo数据库类库 - location / { - default_type text/html; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header Host %s; - proxy_pass %s; - } - access_log /usr/local/nginx/logs/%s.access.log combined; #access_log end - error_log /usr/local/nginx/logs/%s.error.log crit; #error_log end -}',$value['server_name'],$value['index'],$value['header_host'],$value['proxy_pass'],$value['server_name'],$value['server_name']); - } - if ($value['status']=='start') { - $filebytes = file_put_contents(_HYCONF.$value['server_name'].'.conf', $nginx); //写入内容 - } else { - $filebytes = unlink(_HYCONF.$value['server_name'].'.conf');//删除 - } - - if($filebytes){ - $res.=sprintf("[OK] %s conf make is done.\n",$value['server_name']); - }else{ - $res.=sprintf("[ERROR] %s conf make is error.\n",$value['server_name']); - } - } - } - return $res; -} - -function hyproxy_add($server_name,$proxy_pass=''){//done - if (empty($server_name)) { - return "[ERROR] The server_name is empty.\n";//不能为空 - } - - $res = ''; - global $medoo; - $table = 'module_hyproxy'; - $columns = '*'; - $where = array('server_name'=>trim($server_name)); - $proxy = $medoo->get($table, $columns, $where); - - if ($proxy) { - return "[ERROR] The server_name is exist.\n";//已存在 - } else { - empty($proxy_pass) && $proxy_pass = 'http://'.$server_name; - if(!preg_match('/^http(s)?:\\/\\/.+/',$proxy_pass)){ - $proxy_pass = 'http://'.$proxy_pass; - } - $data = array( - 'server_name' => $server_name, - '`index`' => 'index.php index.html index.htm',//index是保留字段 - 'header_host' => '$host', - 'proxy_pass' => $proxy_pass, - 'proxy_cache' => 1, - 'status' => 'start', - 'time' => time() + $HYConfig = array( + 'database_type' => 'mysql', + 'database_name' => $Config['DBname'], + 'server' => 'localhost', + 'username' => $Config['User'], + 'password' => $Config['Password'], + 'charset' => 'utf8' ); - $mysqlres = $medoo->insert($table, $data); - if ($mysqlres) { - $res = "[OK] Proxy add success.\n"; - $res.= hyproxy_make($server_name); - }else { - $res = "[ERROR] Proxy add error.\n"; - } - } - return $res; -} - -function hyproxy_edit($server_name,$field_name='',$value=''){//done - if (empty($server_name)) { - return "[ERROR] The server_name is empty.\n";//不能为空 - } - if (empty($field_name)) { - return "[ERROR] The field_name is empty.\n";//不能为空 - } - $value = trim($value); - $res = ''; - global $medoo; - $table = 'module_hyproxy'; - $columns = '*'; - $where = array('server_name'=>trim($server_name)); - $proxy = $medoo->get($table, $columns, $where); - - if (empty($proxy)) { - return "[ERROR] The server_name is not exist.\n";//不存在 - } else { - if ($field_name=='proxy_pass') { - empty($value) && $value = 'http://'.$server_name; - if(!preg_match('/^http(s)?:\\/\\/.+/',$value)){ - $value = 'http://'.$value; - } - } - if ($field_name=='header_host') { - empty($value) && $value = '$host'; - } - $data = array( - $field_name => $value, - 'time' => time() - ); - $mysqlres = $medoo->update($table, $data,array('hyproxy_id'=>$proxy['hyproxy_id'])); - if ($mysqlres) { - $res = "[OK] Proxy edit success.\n"; - $res.= hyproxy_make($server_name); - }else { - $res = "[ERROR] Proxy edit error.\n"; - } - } - return $res; -} - -function hyproxy_del($server_name){ - if (empty($server_name)) { - return "[ERROR] The server_name is empty.\n";//不能为空 - } + $medoo = new medoo($HYConfig); - $res = ''; - global $medoo; - $table = 'module_hyproxy'; - $columns = '*'; - $where = array('server_name'=>trim($server_name)); - $proxy = $medoo->get($table, $columns, $where); - if (empty($proxy)) { - return "[ERROR] The server_name is not exist.\n";//不存在 - } else { - $mysqlres = $medoo->delete($table, $where); - if ($mysqlres) { - $res = "[OK] Proxy del success.\n"; - }else { - $res = "[ERROR] Proxy del error.\n"; + $opt = array( + 'action:', + 'proxy_status::',//状态 + 'server_name::',//域名 + 'proxy_pass::',//后端 + 'field_name::',//字段名 + 'value::',//字段内容 + ); + $param = getopt('', $opt); + //print_r($param); + switch ($param['action']) { + case 'list': + echo hyproxy_list($param['proxy_status']); + break; + case 'make': + echo hyproxy_make($param['server_name']); + break; + case 'add': + echo hyproxy_add($param['server_name'], $param['proxy_pass']); + break; + case 'edit': + echo hyproxy_edit($param['server_name'], $param['field_name'], $param['value']); + break; + case 'del': + echo hyproxy_del($param['server_name']); + break; + default: + echo 'error action'; } - } - return $res; -} -function hy_deldir($path) { - //如果是目录则继续 - if (is_dir($path)) { - //扫描一个文件夹内的所有文件夹和文件并返回数组 - $p = scandir($path); - foreach ($p as $val) { - //排除目录中的.和.. - if ($val != "." && $val != "..") { - //如果是目录则递归子目录,继续操作 - if (is_dir($path . $val)) { - //子目录中操作删除文件夹和文件 - deldir($path . $val . '/'); - //目录清空后删除空文件夹 - @rmdir($path . $val . '/'); + /** + * 列出站点列表ID,域名,状态 + * @param $proxy_status + * @return string + */ + function hyproxy_list($proxy_status) + { + global $medoo; + empty($proxy_status) && $proxy_status = 'start'; + + $table = 'module_hyproxy'; + $columns = array('hyproxy_id','server_name','status'); + $where = array('status'=>$proxy_status); + $list = $medoo->select($table, $columns, $where); + $res = ''; + foreach ($list as $row) { + $res.=sprintf("%d,%s,%s\n", $row['hyproxy_id'], $row['server_name'], $row['status']); + } + return $res; + } + + /** + * 生成nginx配置文件 + * @param $server_name + * @return string + */ + function hyproxy_make($server_name) + { + global $medoo; + $table = 'module_hyproxy'; + $columns = '*'; + $where = ''; + if (!empty($server_name)) {//指定域名 + $where = array('server_name'=>trim($server_name)); + } + $list = $medoo->select($table, $columns, $where); + $res = ''; + if (empty($list)) { + $res = "[ERROR] The server_name does not exist.\n"; } else { - //如果是文件直接删除 - unlink($path . $val); + if (empty($server_name)) { + hy_deldir(_HYCONF);//删除所有 + } + foreach ($list as $row) { + $filebytes = false; + $conf = hy_build_nginx_conf($row); + if (!$row['status']=='start') { + $filebytes = unlink(_HYCONF.$row['server_name'].'.conf');//删除 + } elseif (!empty($conf)) { + $filebytes = file_put_contents(_HYCONF.$row['server_name'].'.conf', $conf); //写入内容 + } + + if ($filebytes) { + $res.=sprintf("[OK] %s conf make is done.\n", $row['server_name']); + } else { + $res.=sprintf("[ERROR] %s conf make is error.\n", $row['server_name']); + } + } } - } + return $res; + } + + /** + * 新建反向代理 + * @param $server_name + * @param string $proxy_pass + * @return string + */ + function hyproxy_add($server_name, $proxy_pass = '') + { + if (empty($server_name)) { + return "[ERROR] The server_name is empty.\n";//不能为空 + } + + $res = ''; + global $medoo; + $table = 'module_hyproxy'; + $columns = '*'; + $where = array('server_name'=>trim($server_name)); + $proxy = $medoo->get($table, $columns, $where); + + if ($proxy) { + return "[ERROR] The server_name is exist.\n";//已存在 + } else { + empty($proxy_pass) && $proxy_pass = 'http://'.$server_name; + if (!preg_match('/^http(s)?:\\/\\/.+/', $proxy_pass)) { + $proxy_pass = 'http://'.$proxy_pass; + } + $data = array( + 'server_name' => $server_name, + '`index`' => 'index.php index.html index.htm',//index是保留字段 + 'header_host' => '$host', + 'proxy_pass' => $proxy_pass, + 'proxy_cache' => 1, + 'status' => 'start', + 'time' => time() + ); + $mysqlres = $medoo->insert($table, $data); + if ($mysqlres) { + $res = "[OK] Proxy add success.\n"; + $res.= hyproxy_make($server_name); + } else { + $res = "[ERROR] Proxy add error.\n"; + } + } + return $res; + } + + /** + * 修改反向代理参数 + * @param $server_name + * @param string $field_name + * @param string $value + * @return string + */ + function hyproxy_edit($server_name, $field_name = '', $value = '') + { + if (empty($server_name)) { + return "[ERROR] The server_name is empty.\n";//不能为空 + } + if (empty($field_name)) { + return "[ERROR] The field_name is empty.\n";//不能为空 + } + $value = trim($value); + $res = ''; + global $medoo; + $table = 'module_hyproxy'; + $columns = '*'; + $where = array('server_name'=>trim($server_name)); + $proxy = $medoo->get($table, $columns, $where); + + if (empty($proxy)) { + return "[ERROR] The server_name is not exist.\n";//不存在 + } else { + if ($field_name=='proxy_pass') { + empty($value) && $value = 'http://'.$server_name; + if (!preg_match('/^http(s)?:\\/\\/.+/', $value)) { + $value = 'http://'.$value; + } + } + if ($field_name=='header_host') { + empty($value) && $value = '$host'; + } + $data = array( + $field_name => $value, + 'time' => time() + ); + $mysqlres = $medoo->update($table, $data, array('hyproxy_id'=>$proxy['hyproxy_id'])); + if ($mysqlres) { + $res = "[OK] Proxy edit success.\n"; + $res.= hyproxy_make($server_name); + } else { + $res = "[ERROR] Proxy edit error.\n"; + } + } + return $res; + } + + /** + * 删除反向代理 + * @param $server_name + * @return string + */ + function hyproxy_del($server_name) + { + if (empty($server_name)) { + return "[ERROR] The server_name is empty.\n";//不能为空 + } + + $res = ''; + global $medoo; + $table = 'module_hyproxy'; + $columns = '*'; + $where = array('server_name'=>trim($server_name)); + $proxy = $medoo->get($table, $columns, $where); + if (empty($proxy)) { + return "[ERROR] The server_name is not exist.\n";//不存在 + } else { + $mysqlres = $medoo->delete($table, $where); + if ($mysqlres) { + $res = "[OK] Proxy del success.\n"; + } else { + $res = "[ERROR] Proxy del error.\n"; + } + } + unlink(_HYCONF . $server_name . '.conf');//删除配置文件 + unlink(_HYLOGS . $server_name . '.access.log');//删除日志文件 + unlink(_HYLOGS . $server_name . '.error.log');//删除日志文件 + return $res; + } + + /** + * 删除目录和子目录 + * @param $path + */ + function hy_deldir($path) + { + //如果是目录则继续 + if (is_dir($path)) { + //扫描一个文件夹内的所有文件夹和文件并返回数组 + $p = scandir($path); + foreach ($p as $val) { + //排除目录中的.和.. + if ($val != "." && $val != "..") { + //如果是目录则递归子目录,继续操作 + if (is_dir($path . $val)) { + //子目录中操作删除文件夹和文件 + deldir($path . $val . '/'); + //目录清空后删除空文件夹 + @rmdir($path . $val . '/'); + } else { + //如果是文件直接删除 + unlink($path . $val); + } + } + } + } + } + + /** + * 根据传入数据构建nginx配置内容 + * @param $row + */ + function hy_build_nginx_conf($row) + { + //开启反向代理缓存模板 + $proxy_cache_template_path = _HYPROXY . 'conf' . DS . 'proxy_cache_template.conf'; + $proxy_cache_template = ''; + if (file_exists($proxy_cache_template_path)) { + $proxy_cache_template = file_get_contents($proxy_cache_template_path); + } + //禁用反向代理缓存模板 + $no_cache_template_path = _HYPROXY . 'conf' . DS . 'no_cache_template.conf'; + $no_cache_template = ''; + if (file_exists($no_cache_template_path)) { + $no_cache_template = file_get_contents($no_cache_template_path); + } + + $conf = false; + if (!empty($row)) { + $row['logs_path'] = _HYLOGS . $row['server_name']; + + //判断使用哪个模板 + $template = false; + if (!empty($row['proxy_cache']) && !empty($proxy_cache_template)) { + $template = $proxy_cache_template; + } elseif (!empty($no_cache_template)) { + $template = $no_cache_template; + } + + //模板有效的话,进行遍历数组替换模板变量 + if ($template) { + foreach ($row as $k => $v) { + $template=str_replace('{$'.$k.'}', $v, $template); + } + $conf = $template; + } + } + return $conf; } - } -} \ No newline at end of file