2024-08-07 00:29:23 +08:00
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
use Workerman\Worker;
|
|
|
|
|
use Workerman\Connection\TcpConnection;
|
|
|
|
|
use Workerman\Connection\AsyncTcpConnection;
|
|
|
|
|
use Workerman\Protocols\Http\Request;
|
2024-08-09 17:43:48 +08:00
|
|
|
|
use Workerman\Protocols\Http\Response as WebmanResponse;
|
|
|
|
|
use yzh52521\EasyHttp\Http;
|
|
|
|
|
use yzh52521\EasyHttp\Response;
|
|
|
|
|
use yzh52521\EasyHttp\RequestException;
|
2024-08-07 00:29:23 +08:00
|
|
|
|
|
|
|
|
|
|
2024-08-09 17:43:48 +08:00
|
|
|
|
require_once __DIR__ . '/vendor/autoload.php';
|
2024-08-07 00:29:23 +08:00
|
|
|
|
|
2024-08-09 17:43:48 +08:00
|
|
|
|
$worker = new Worker('tcp://0.0.0.0:8686');
|
|
|
|
|
|
|
|
|
|
function encryptAES($data, $key, $iv) {
|
|
|
|
|
$encrypted = openssl_encrypt($data, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
|
|
|
|
|
$encrypted = base64_encode($encrypted);
|
|
|
|
|
return $encrypted;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function decryptAES($encryptedData, $key, $iv) {
|
|
|
|
|
$encryptedData = base64_decode($encryptedData);
|
|
|
|
|
$decrypted = openssl_decrypt($encryptedData, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
|
|
|
|
|
return $decrypted;
|
|
|
|
|
}
|
2024-08-07 00:29:23 +08:00
|
|
|
|
function replaceHost($data,$host)
|
|
|
|
|
{
|
|
|
|
|
return preg_replace('/Host: (.*)/i','Host: '.$host,$data);
|
|
|
|
|
}
|
|
|
|
|
function HTMLview($filePath, $data) {
|
|
|
|
|
ob_start();
|
|
|
|
|
extract($data);
|
|
|
|
|
include $filePath;
|
|
|
|
|
$str = ob_get_contents();
|
|
|
|
|
ob_end_clean();
|
|
|
|
|
|
|
|
|
|
return $str;
|
|
|
|
|
}
|
2024-08-09 17:43:48 +08:00
|
|
|
|
$worker->onConnect = function(TcpConnection $connection, Request $data)
|
2024-08-07 00:29:23 +08:00
|
|
|
|
{
|
2024-08-09 17:43:48 +08:00
|
|
|
|
$config=json_decode(file_get_contents("./config.json"));
|
|
|
|
|
|
|
|
|
|
$matched=false;
|
|
|
|
|
foreach($config->website as $website){
|
|
|
|
|
if($website->query==$data->host(true)){
|
|
|
|
|
$config->website=$website;
|
|
|
|
|
$c_provider=$website->provider;
|
|
|
|
|
$config->provider=$config->provider->$c_provider;
|
|
|
|
|
$matched=true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2024-08-07 00:29:23 +08:00
|
|
|
|
}
|
2024-08-09 17:43:48 +08:00
|
|
|
|
if($matched==false){
|
|
|
|
|
$connection->send(HTMLview('./view/404.php', array()));
|
|
|
|
|
$connection->close();
|
|
|
|
|
}else{
|
|
|
|
|
|
|
|
|
|
$tWT = $data->cookie('WT', 'null');
|
|
|
|
|
if($tWT!='null'){
|
|
|
|
|
$key = 'laysensechina000';
|
|
|
|
|
$iv = '1234567890abcdef';
|
|
|
|
|
$wt=json_decode(decryptAES($tWT, $key, $iv));
|
|
|
|
|
if(time()-$wt->time<60){
|
|
|
|
|
$tWT=='null';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if($tWT=='null'){
|
|
|
|
|
if(strpos( $data->path(), "/login" ) === 0){
|
|
|
|
|
if( $data->path()=='/login/qywx/' ){
|
|
|
|
|
$code = $data->get('code','null');
|
|
|
|
|
if($code=='null'){
|
|
|
|
|
$connection->send(HTMLview('./view/login.php', array('public'=>$config->website->public,'website'=>$config->website,'provider'=>$config->provider,'special'=>'failed','uri'=>'/')));
|
|
|
|
|
$connection->close();
|
|
|
|
|
|
|
|
|
|
}else{
|
|
|
|
|
$http = new Workerman\Http\Client();
|
|
|
|
|
$tokenfile='./'.$config->website->api->qywx->appid.'.'.$config->website->api->qywx->agentid.'.token';
|
|
|
|
|
echo $tokenfile;
|
|
|
|
|
if(file_exists($tokenfile)){
|
|
|
|
|
$tokencontent=json_decode(file_get_contents($tokenfile));
|
|
|
|
|
$fulltoken=$tokencontent->token;
|
|
|
|
|
$ddl=$tokencontent->ddl;
|
|
|
|
|
if($ddl-time()<180){
|
|
|
|
|
$reapply=true;
|
|
|
|
|
}else{
|
|
|
|
|
$reapply=false;
|
|
|
|
|
}
|
|
|
|
|
}else{
|
|
|
|
|
$reapply=true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if($reapply==true){
|
|
|
|
|
$apply=$response = Http::get('https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid='.$config->website->api->qywx->appid.'&corpsecret='.$config->website->api->qywx->token)->json();
|
|
|
|
|
$fulltoken=$apply->access_token;
|
|
|
|
|
$ddl=time()+$apply->expires_in;
|
|
|
|
|
$file=fopen($tokenfile,"w");
|
|
|
|
|
fwrite($file, json_encode(array('token'=>$fulltoken,'ddl'=>$ddl)));
|
|
|
|
|
fclose($file);
|
|
|
|
|
}
|
|
|
|
|
$lookup= Http::get('https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo?access_token='.$fulltoken.'&code='.$code)->json();
|
|
|
|
|
if($lookup->errcode!=0){
|
|
|
|
|
$connection->send(HTMLview('./view/login.php', array('public'=>$config->website->public,'website'=>$config->website,'provider'=>$config->provider,'special'=>'failed','uri'=>'/')));
|
|
|
|
|
$connection->close();
|
|
|
|
|
}else{
|
|
|
|
|
$userid=$lookup->userid;
|
|
|
|
|
$userinfo=Http::get('https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token='.$fulltoken.'&userid='.$userid)->json();
|
|
|
|
|
$username=$userinfo->name;
|
|
|
|
|
$userposition=$userinfo->position;
|
|
|
|
|
$WT=json_encode(['id'=>$userid,'name'=>$username,'position'=>$userposition,'time'=>time()]);
|
|
|
|
|
$key = 'laysensechina000';
|
|
|
|
|
$iv = '1234567890abcdef';
|
|
|
|
|
$WT = encryptAES($WT, $key, $iv);
|
|
|
|
|
$dest=$data->get('jump','/');
|
|
|
|
|
$response = new WebmanResponse(200, [], HTMLview('./view/jump.php', array('website'=>$config->website,'provider'=>$config->provider,'userinfo'=>$userinfo,'dest'=>$dest)));
|
|
|
|
|
$response->cookie('WT', $WT,time()+9600,'/','.laysense.cn');
|
|
|
|
|
|
|
|
|
|
$connection->send($response);
|
|
|
|
|
$connection->close();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}else{
|
|
|
|
|
$connection->send(HTMLview('./view/login.php', array('public'=>$config->website->public,'website'=>$config->website,'provider'=>$config->provider,'special'=>null,'uri'=>$data->uri())));
|
|
|
|
|
$connection->close();
|
|
|
|
|
}
|
|
|
|
|
}else{
|
2024-08-07 00:29:23 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Parse http header.
|
|
|
|
|
list($method, $addr, $http_version) = explode(' ', $data);
|
|
|
|
|
$_headers=explode("\r\n",$data);
|
|
|
|
|
$headers=[];
|
|
|
|
|
foreach ($_headers as $_header){
|
|
|
|
|
$_point=strpos($_header,':');
|
|
|
|
|
if ($_point===false) continue;
|
|
|
|
|
$headers[substr($_header,0,$_point)]=trim(trim(substr($_header,$_point),':'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//源站IP地址
|
2024-08-09 17:43:48 +08:00
|
|
|
|
$source_ip=$config->website->ip;
|
|
|
|
|
$port=$config->website->port;
|
|
|
|
|
$source_host=$config->website->host;
|
|
|
|
|
$ssl=$config->website->ssl;
|
2024-08-07 00:29:23 +08:00
|
|
|
|
|
|
|
|
|
|
2024-08-09 17:43:48 +08:00
|
|
|
|
print_r('用户IP:'.$data->header('X-Real-IP','127.0.0.1').'| 访问路径:'.$data->host().$data->uri() .' | 源站:'.$source_ip.':'.$port.'| 回源域名'.$source_host.'|SSL:'.$ssl);
|
2024-08-07 00:29:23 +08:00
|
|
|
|
if($ssl==true){
|
|
|
|
|
$source_ip=$source_host;
|
|
|
|
|
}
|
|
|
|
|
// Async TCP connection.
|
|
|
|
|
$remote_connection = new AsyncTcpConnection('tcp://'.$source_ip.':'.$port);
|
|
|
|
|
// CONNECT.
|
|
|
|
|
if($ssl==true){
|
|
|
|
|
$remote_connection->transport = 'ssl';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($method !== 'CONNECT') {
|
|
|
|
|
//替换request 中的回源host
|
|
|
|
|
$remote_connection->send(replaceHost($data,$source_host));
|
|
|
|
|
// POST GET PUT DELETE etc.
|
|
|
|
|
} else {
|
|
|
|
|
$connection->send("HTTP/1.1 200 Connection Established\r\n\r\n");
|
|
|
|
|
}
|
2024-08-09 17:43:48 +08:00
|
|
|
|
|
2024-08-07 00:29:23 +08:00
|
|
|
|
$remote_connection->onMessage=function (TcpConnection $SourceConn, $SourceData)use ($connection){
|
|
|
|
|
$connection->send($SourceData);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
$remote_connection->onClose = function ($source) use ($connection) {
|
|
|
|
|
$connection->close();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
$remote_connection->onBufferFull = function ($SourceConn) use ($connection) {
|
|
|
|
|
$connection->pauseRecv();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
$remote_connection->onBufferDrain = function ($SourceConn) use ($connection) {
|
|
|
|
|
$connection->resumeRecv();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
$connection->onMessage=function (TcpConnection $ClientConn, $ClientData)use ($remote_connection,$source_host){
|
|
|
|
|
$remote_connection->send(replaceHost($ClientData,$source_host));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
$connection->onClose = function (TcpConnection $ClientConn) use ($remote_connection) {
|
|
|
|
|
$remote_connection->close();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
$connection->onBufferFull = function (TcpConnection $ClientConn) use ($remote_connection) {
|
|
|
|
|
$remote_connection->pauseRecv();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
$connection->onBufferDrain = function (TcpConnection $ClientConn) use ($remote_connection) {
|
|
|
|
|
$remote_connection->resumeRecv();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
$remote_connection->connect();
|
2024-08-09 17:43:48 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-08-07 00:29:23 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 运行worker
|
|
|
|
|
Worker::runAll();
|