154 lines
5.3 KiB
JavaScript
154 lines
5.3 KiB
JavaScript
/**
|
||
* 修复广州Nginx:把/images/移到正确的server块
|
||
*/
|
||
|
||
const GZ = { ip: '43.139.217.141', port: 3910, key: 'zy_gtw_4a155446b7acc09fe46a2a29972c0ca5d9954da19c35dc23' }
|
||
|
||
async function callGK(srv, method, path, body = null) {
|
||
const url = `http://${srv.ip}:${srv.port}${path}`
|
||
const opts = { method, headers: { 'Authorization': `Bearer ${srv.key}`, 'Content-Type': 'application/json' } }
|
||
if (body) opts.body = JSON.stringify(body)
|
||
const res = await fetch(url, opts)
|
||
const text = await res.text()
|
||
try { return { status: res.status, data: JSON.parse(text) } }
|
||
catch { return { status: res.status, data: { raw: text } } }
|
||
}
|
||
|
||
async function exec(srv, cmd) {
|
||
const r = await callGK(srv, 'POST', '/exec', { cmd })
|
||
return r.data
|
||
}
|
||
|
||
async function readFile(srv, path) {
|
||
const r = await callGK(srv, 'POST', '/file/read', { path })
|
||
if (r.status === 200) return r.data.content
|
||
return null
|
||
}
|
||
|
||
async function writeFile(srv, path, content) {
|
||
return (await callGK(srv, 'POST', '/file/write', { path, content })).status === 200
|
||
}
|
||
|
||
async function main() {
|
||
console.log('═'.repeat(50))
|
||
console.log('🔧 修复广州Nginx: /images/ 位置修正')
|
||
console.log('═'.repeat(50))
|
||
|
||
// 读取配置
|
||
const config = await readFile(GZ, '/etc/nginx/sites-enabled/guanghulab')
|
||
if (!config) {
|
||
console.log('❌ 无法读取配置')
|
||
return
|
||
}
|
||
|
||
console.log('当前配置长度:', config.length, '字符')
|
||
|
||
// 找两个server块的结构
|
||
// 第一个server: listen 443 ssl (HTTPS)
|
||
// 第二个server: listen 80 (HTTP redirect)
|
||
|
||
// 找到 "server {" 的两次出现
|
||
const firstServer = config.indexOf('server {')
|
||
const secondServer = config.indexOf('server {', firstServer + 10)
|
||
const firstServerEnd = config.indexOf('}', firstServer)
|
||
const secondServerEnd = config.indexOf('}', secondServer)
|
||
|
||
console.log('\n结构分析:')
|
||
console.log(' 第一个server { 位置:', firstServer)
|
||
console.log(' 第一个server } 位置:', firstServerEnd)
|
||
console.log(' 第二个server { 位置:', secondServer)
|
||
console.log(' 第二个server } 位置:', secondServerEnd)
|
||
|
||
// 用Python来精确处理
|
||
const result = await exec(GZ, `
|
||
python3 << 'PYEOF'
|
||
with open('/etc/nginx/sites-enabled/guanghulab', 'r') as f:
|
||
content = f.read()
|
||
|
||
# 找到/images/配置块(在第二个server块中)
|
||
images_start = content.find(' # 铸渊图片工作室')
|
||
images_end = content.find('}', images_start) + 1 # 包括最后一个}
|
||
|
||
if images_start == -1:
|
||
print('ERROR: 找不到/images/配置块')
|
||
exit(1)
|
||
|
||
images_block = content[images_start:images_end]
|
||
print('找到/images/块:', images_block[:60] + '...')
|
||
|
||
# 从原文件中删除/images/块
|
||
content_without = content[:images_start] + content[images_end:]
|
||
print('删除/images/后长度:', len(content_without))
|
||
|
||
# 找到第一个server块(HTTPS)的结束位置
|
||
# 第一个server块以"listen 443 ssl"开头,找到对应的}
|
||
first_server_start = content_without.index('server {')
|
||
# 找到listen 443 ssl的server块
|
||
depth = 0
|
||
pos = first_server_start
|
||
while pos < len(content_without):
|
||
if content_without[pos] == '{':
|
||
depth += 1
|
||
elif content_without[pos] == '}':
|
||
depth -= 1
|
||
if depth == 0:
|
||
# 在第一个server块的}前插入/images/块
|
||
new_content = content_without[:pos] + '\\n' + images_block + content_without[pos:]
|
||
with open('/etc/nginx/sites-enabled/guanghulab', 'w') as f:
|
||
f.write(new_content)
|
||
print(f'OK: 在第一个server块内(位置{pos})插入')
|
||
break
|
||
pos += 1
|
||
else:
|
||
print('ERROR: 找不到第一个server块结尾')
|
||
|
||
# 验证
|
||
with open('/etc/nginx/sites-enabled/guanghulab', 'r') as f:
|
||
final = f.read()
|
||
|
||
# 检查images块是否在正确的server块中
|
||
ssl_pos = final.find('listen 443 ssl')
|
||
second_server_pos = final.find('listen 80;\\n server_name guanghulab.com')
|
||
images_in_final = final.find('location /images/')
|
||
|
||
print(f'SSL server start: {ssl_pos}')
|
||
print(f'HTTP redirect start: {second_server_pos}')
|
||
print(f'/images/ location: {images_in_final}')
|
||
if ssl_pos < images_in_final < second_server_pos:
|
||
print('✅ /images/ 在正确的SSL server块中!')
|
||
else:
|
||
print('❌ /images/ 位置不正确!')
|
||
PYEOF
|
||
`)
|
||
console.log('\nPython:', result.stdout || result.stderr)
|
||
|
||
// 测试Nginx
|
||
const r1 = await exec(GZ, 'nginx -t 2>&1')
|
||
console.log('Nginx测试:', r1.stdout || r1.stderr)
|
||
|
||
if ((r1.stdout || '').includes('test failed') || (r1.stderr || '').includes('test failed')) {
|
||
console.log('⚠️ 配置错误,回滚')
|
||
// 重新部署 - 从备份读取
|
||
} else {
|
||
await exec(GZ, 'nginx -s reload 2>&1')
|
||
console.log('Nginx重载成功')
|
||
|
||
// 测试
|
||
const r2 = await exec(GZ, `curl -s -k --connect-timeout 5 -w "\\nHTTP:%{http_code}" https://localhost/images/ 2>&1 | tail -5`)
|
||
console.log('\n测试 https://localhost/images/:')
|
||
console.log((r2.stdout || '').slice(0, 200))
|
||
|
||
// 从外网测试
|
||
const SG_IP = '43.156.237.110'
|
||
const r3 = await exec(GZ, `curl -s --connect-timeout 5 -w "\\nHTTP:%{http_code}" "http://${SG_IP}/images/" -H "Host: guanghulab.com" 2>&1 | tail -3`)
|
||
console.log('\n测试 http://SG_IP/images/ (Host: guanghulab.com):')
|
||
console.log(r3.stdout || r3.stderr)
|
||
}
|
||
|
||
console.log('\n' + '═'.repeat(50))
|
||
console.log('✅ 修复完成')
|
||
console.log('═'.repeat(50))
|
||
}
|
||
|
||
main().catch(err => console.error('❌', err))
|