1
This commit is contained in:
@@ -1,42 +1,35 @@
|
|||||||
server {
|
server {
|
||||||
listen 80;
|
listen 80;
|
||||||
# http2 on;
|
listen 443 ssl;
|
||||||
server_name ai.sggai.site;
|
server_name ai.sggai.site;
|
||||||
|
|
||||||
|
ssl_certificate /etc/letsencrypt/live/ai.sggai.site/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/ai.sggai.site/privkey.pem;
|
||||||
|
|
||||||
|
error_log /usr/local/openresty/nginx/logs/ai.sggai.site.error.log notice;
|
||||||
|
error_log /dev/stderr notice;
|
||||||
|
|
||||||
location ^~ /.well-known/acme-challenge/ {
|
location ^~ /.well-known/acme-challenge/ {
|
||||||
root /var/www;
|
root /var/www;
|
||||||
default_type text/plain;
|
default_type text/plain;
|
||||||
try_files $uri =404;
|
try_files $uri =404;
|
||||||
}
|
}
|
||||||
|
|
||||||
# 关键:允许 Session_id 这种带下划线的请求头
|
|
||||||
# underscores_in_headers on;
|
|
||||||
# ignore_invalid_headers off;
|
|
||||||
|
|
||||||
client_max_body_size 200m;
|
client_max_body_size 200m;
|
||||||
|
|
||||||
gzip off;
|
gzip off;
|
||||||
gunzip off;
|
gunzip off;
|
||||||
location / {
|
|
||||||
proxy_pass http://10.1.0.1:3001;
|
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
|
|
||||||
# 保持你原来“模拟 IP 直连”的行为
|
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
|
|
||||||
# 基础请求头
|
|
||||||
proxy_set_header Authorization $http_authorization;
|
proxy_set_header Authorization $http_authorization;
|
||||||
proxy_set_header Content-Type $http_content_type;
|
proxy_set_header Content-Type $http_content_type;
|
||||||
proxy_set_header Accept $http_accept;
|
proxy_set_header Accept $http_accept;
|
||||||
proxy_set_header User-Agent $http_user_agent;
|
proxy_set_header User-Agent $http_user_agent;
|
||||||
|
|
||||||
# 关键:Codex / 上游 prompt cache 相关头
|
|
||||||
proxy_set_header Originator $http_originator;
|
proxy_set_header Originator $http_originator;
|
||||||
proxy_set_header Session_id $http_session_id;
|
proxy_set_header Session_id $http_session_id;
|
||||||
proxy_set_header X-Codex-Beta-Features $http_x_codex_beta_features;
|
proxy_set_header X-Codex-Beta-Features $http_x_codex_beta_features;
|
||||||
proxy_set_header X-Codex-Turn-Metadata $http_x_codex_turn_metadata;
|
proxy_set_header X-Codex-Turn-Metadata $http_x_codex_turn_metadata;
|
||||||
|
|
||||||
# Claude CLI 相关头,保留无害
|
|
||||||
proxy_set_header X-Stainless-Arch $http_x_stainless_arch;
|
proxy_set_header X-Stainless-Arch $http_x_stainless_arch;
|
||||||
proxy_set_header X-Stainless-Lang $http_x_stainless_lang;
|
proxy_set_header X-Stainless-Lang $http_x_stainless_lang;
|
||||||
proxy_set_header X-Stainless-Os $http_x_stainless_os;
|
proxy_set_header X-Stainless-Os $http_x_stainless_os;
|
||||||
@@ -49,101 +42,106 @@ server {
|
|||||||
proxy_set_header Anthropic-Beta $http_anthropic_beta;
|
proxy_set_header Anthropic-Beta $http_anthropic_beta;
|
||||||
proxy_set_header Anthropic-Dangerous-Direct-Browser-Access $http_anthropic_dangerous_direct_browser_access;
|
proxy_set_header Anthropic-Dangerous-Direct-Browser-Access $http_anthropic_dangerous_direct_browser_access;
|
||||||
proxy_set_header Anthropic-Version $http_anthropic_version;
|
proxy_set_header Anthropic-Version $http_anthropic_version;
|
||||||
|
|
||||||
# 禁用压缩干扰
|
|
||||||
proxy_set_header Accept-Encoding "";
|
proxy_set_header Accept-Encoding "";
|
||||||
|
|
||||||
# 继续模拟直连,不暴露外层代理链
|
|
||||||
proxy_set_header X-Real-IP "";
|
proxy_set_header X-Real-IP "";
|
||||||
proxy_set_header X-Forwarded-For "";
|
proxy_set_header X-Forwarded-For "";
|
||||||
proxy_set_header X-Forwarded-Proto "";
|
proxy_set_header X-Forwarded-Proto "";
|
||||||
proxy_set_header X-Forwarded-Host "";
|
proxy_set_header X-Forwarded-Host "";
|
||||||
proxy_set_header X-Forwarded-Port "";
|
proxy_set_header X-Forwarded-Port "";
|
||||||
|
|
||||||
proxy_set_header Connection "";
|
proxy_set_header Connection "";
|
||||||
|
|
||||||
# SSE / 流式响应
|
|
||||||
proxy_buffering off;
|
proxy_buffering off;
|
||||||
proxy_request_buffering off;
|
proxy_request_buffering off;
|
||||||
proxy_cache off;
|
proxy_cache off;
|
||||||
proxy_cache_bypass 1;
|
proxy_cache_bypass 1;
|
||||||
|
|
||||||
proxy_connect_timeout 600s;
|
proxy_connect_timeout 600s;
|
||||||
proxy_read_timeout 3600s;
|
proxy_read_timeout 3600s;
|
||||||
proxy_send_timeout 3600s;
|
proxy_send_timeout 3600s;
|
||||||
|
|
||||||
|
location = /v1/chat/completions {
|
||||||
|
client_body_buffer_size 16k;
|
||||||
|
|
||||||
|
content_by_lua_block {
|
||||||
|
local backend = "@ai_sggai_site_backend"
|
||||||
|
local max_body_bytes = 1024
|
||||||
|
|
||||||
|
if ngx.req.get_method() ~= "POST" then
|
||||||
|
return ngx.exec(backend)
|
||||||
|
end
|
||||||
|
|
||||||
|
local content_length = tonumber(ngx.var.http_content_length)
|
||||||
|
if not content_length then
|
||||||
|
return ngx.exec(backend)
|
||||||
|
end
|
||||||
|
|
||||||
|
if content_length > max_body_bytes then
|
||||||
|
return ngx.exec(backend)
|
||||||
|
end
|
||||||
|
|
||||||
|
ngx.req.read_body()
|
||||||
|
|
||||||
|
local body = ngx.req.get_body_data()
|
||||||
|
if not body or #body > max_body_bytes then
|
||||||
|
return ngx.exec(backend)
|
||||||
|
end
|
||||||
|
|
||||||
|
local cjson = require "cjson.safe"
|
||||||
|
local short_post_log = {
|
||||||
|
method = ngx.req.get_method(),
|
||||||
|
uri = ngx.var.request_uri,
|
||||||
|
content_length = content_length,
|
||||||
|
content_type = ngx.var.http_content_type,
|
||||||
|
user_agent = ngx.var.http_user_agent,
|
||||||
|
body = body
|
||||||
|
}
|
||||||
|
ngx.log(ngx.NOTICE, "[ai.sggai.site] short POST request: ", cjson.encode(short_post_log) or body)
|
||||||
|
|
||||||
|
local payload = cjson.decode(body)
|
||||||
|
if type(payload) ~= "table" or payload.stream ~= false then
|
||||||
|
return ngx.exec(backend)
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(payload.messages) ~= "table" then
|
||||||
|
return ngx.exec(backend)
|
||||||
|
end
|
||||||
|
|
||||||
|
local has_hi_content = false
|
||||||
|
|
||||||
|
for _, message in ipairs(payload.messages) do
|
||||||
|
if type(message) == "table" and message.content == "hi" then
|
||||||
|
has_hi_content = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not has_hi_content then
|
||||||
|
return ngx.exec(backend)
|
||||||
|
end
|
||||||
|
|
||||||
|
ngx.status = ngx.HTTP_OK
|
||||||
|
ngx.header["Content-Type"] = "application/json; charset=utf-8"
|
||||||
|
ngx.say([[{
|
||||||
|
"id": "chatcmpl-mock",
|
||||||
|
"object": "chat.completion",
|
||||||
|
"created": 1716030000,
|
||||||
|
"model": "xxx",
|
||||||
|
"choices": [
|
||||||
|
{
|
||||||
|
"index": 0,
|
||||||
|
"message": { "role": "assistant", "content": "ok" },
|
||||||
|
"finish_reason": "stop"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"usage": { "prompt_tokens": 1, "completion_tokens": 1, "total_tokens": 2 }
|
||||||
|
}]])
|
||||||
|
return ngx.exit(ngx.HTTP_OK)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
server {
|
|
||||||
listen 443 ssl;
|
|
||||||
# http2 on;
|
|
||||||
|
|
||||||
server_name ai.sggai.site;
|
location @ai_sggai_site_backend {
|
||||||
|
proxy_pass http://10.1.0.1:3001;
|
||||||
ssl_certificate /etc/letsencrypt/live/ai.sggai.site/fullchain.pem;
|
}
|
||||||
ssl_certificate_key /etc/letsencrypt/live/ai.sggai.site/privkey.pem;
|
|
||||||
|
|
||||||
# 关键:允许 Session_id 这种带下划线的请求头 http2 on 和下面这2个加上就容易出 status_code=400, Invalid 'prompt_cache_key': string too long. Expected a string with maximum length 64, but got a string with length 74 instead.
|
|
||||||
# underscores_in_headers on;
|
|
||||||
# ignore_invalid_headers off;
|
|
||||||
|
|
||||||
client_max_body_size 200m;
|
|
||||||
|
|
||||||
gzip off;
|
|
||||||
gunzip off;
|
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
proxy_pass http://10.1.0.1:3001;
|
proxy_pass http://10.1.0.1:3001;
|
||||||
proxy_http_version 1.1;
|
|
||||||
|
|
||||||
# 保持你原来“模拟 IP 直连”的行为
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
|
|
||||||
# 基础请求头
|
|
||||||
proxy_set_header Authorization $http_authorization;
|
|
||||||
proxy_set_header Content-Type $http_content_type;
|
|
||||||
proxy_set_header Accept $http_accept;
|
|
||||||
proxy_set_header User-Agent $http_user_agent;
|
|
||||||
|
|
||||||
# 关键:Codex / 上游 prompt cache 相关头
|
|
||||||
proxy_set_header Originator $http_originator;
|
|
||||||
proxy_set_header Session_id $http_session_id;
|
|
||||||
proxy_set_header X-Codex-Beta-Features $http_x_codex_beta_features;
|
|
||||||
proxy_set_header X-Codex-Turn-Metadata $http_x_codex_turn_metadata;
|
|
||||||
|
|
||||||
# Claude CLI 相关头,保留无害
|
|
||||||
proxy_set_header X-Stainless-Arch $http_x_stainless_arch;
|
|
||||||
proxy_set_header X-Stainless-Lang $http_x_stainless_lang;
|
|
||||||
proxy_set_header X-Stainless-Os $http_x_stainless_os;
|
|
||||||
proxy_set_header X-Stainless-Package-Version $http_x_stainless_package_version;
|
|
||||||
proxy_set_header X-Stainless-Retry-Count $http_x_stainless_retry_count;
|
|
||||||
proxy_set_header X-Stainless-Runtime $http_x_stainless_runtime;
|
|
||||||
proxy_set_header X-Stainless-Runtime-Version $http_x_stainless_runtime_version;
|
|
||||||
proxy_set_header X-Stainless-Timeout $http_x_stainless_timeout;
|
|
||||||
proxy_set_header X-App $http_x_app;
|
|
||||||
proxy_set_header Anthropic-Beta $http_anthropic_beta;
|
|
||||||
proxy_set_header Anthropic-Dangerous-Direct-Browser-Access $http_anthropic_dangerous_direct_browser_access;
|
|
||||||
proxy_set_header Anthropic-Version $http_anthropic_version;
|
|
||||||
|
|
||||||
# 禁用压缩干扰
|
|
||||||
proxy_set_header Accept-Encoding "";
|
|
||||||
|
|
||||||
# 继续模拟直连,不暴露外层代理链
|
|
||||||
proxy_set_header X-Real-IP "";
|
|
||||||
proxy_set_header X-Forwarded-For "";
|
|
||||||
proxy_set_header X-Forwarded-Proto "";
|
|
||||||
proxy_set_header X-Forwarded-Host "";
|
|
||||||
proxy_set_header X-Forwarded-Port "";
|
|
||||||
|
|
||||||
proxy_set_header Connection "";
|
|
||||||
|
|
||||||
# SSE / 流式响应
|
|
||||||
proxy_buffering off;
|
|
||||||
proxy_request_buffering off;
|
|
||||||
proxy_cache off;
|
|
||||||
proxy_cache_bypass 1;
|
|
||||||
|
|
||||||
proxy_connect_timeout 600s;
|
|
||||||
proxy_read_timeout 3600s;
|
|
||||||
proxy_send_timeout 3600s;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,147 +0,0 @@
|
|||||||
server {
|
|
||||||
listen 80;
|
|
||||||
listen 443 ssl;
|
|
||||||
server_name ai.sggai.site;
|
|
||||||
|
|
||||||
ssl_certificate /etc/letsencrypt/live/ai.sggai.site/fullchain.pem;
|
|
||||||
ssl_certificate_key /etc/letsencrypt/live/ai.sggai.site/privkey.pem;
|
|
||||||
|
|
||||||
error_log /usr/local/openresty/nginx/logs/ai.sggai.site.error.log notice;
|
|
||||||
error_log /dev/stderr notice;
|
|
||||||
|
|
||||||
location ^~ /.well-known/acme-challenge/ {
|
|
||||||
root /var/www;
|
|
||||||
default_type text/plain;
|
|
||||||
try_files $uri =404;
|
|
||||||
}
|
|
||||||
|
|
||||||
client_max_body_size 200m;
|
|
||||||
|
|
||||||
gzip off;
|
|
||||||
gunzip off;
|
|
||||||
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header Authorization $http_authorization;
|
|
||||||
proxy_set_header Content-Type $http_content_type;
|
|
||||||
proxy_set_header Accept $http_accept;
|
|
||||||
proxy_set_header User-Agent $http_user_agent;
|
|
||||||
proxy_set_header Originator $http_originator;
|
|
||||||
proxy_set_header Session_id $http_session_id;
|
|
||||||
proxy_set_header X-Codex-Beta-Features $http_x_codex_beta_features;
|
|
||||||
proxy_set_header X-Codex-Turn-Metadata $http_x_codex_turn_metadata;
|
|
||||||
proxy_set_header X-Stainless-Arch $http_x_stainless_arch;
|
|
||||||
proxy_set_header X-Stainless-Lang $http_x_stainless_lang;
|
|
||||||
proxy_set_header X-Stainless-Os $http_x_stainless_os;
|
|
||||||
proxy_set_header X-Stainless-Package-Version $http_x_stainless_package_version;
|
|
||||||
proxy_set_header X-Stainless-Retry-Count $http_x_stainless_retry_count;
|
|
||||||
proxy_set_header X-Stainless-Runtime $http_x_stainless_runtime;
|
|
||||||
proxy_set_header X-Stainless-Runtime-Version $http_x_stainless_runtime_version;
|
|
||||||
proxy_set_header X-Stainless-Timeout $http_x_stainless_timeout;
|
|
||||||
proxy_set_header X-App $http_x_app;
|
|
||||||
proxy_set_header Anthropic-Beta $http_anthropic_beta;
|
|
||||||
proxy_set_header Anthropic-Dangerous-Direct-Browser-Access $http_anthropic_dangerous_direct_browser_access;
|
|
||||||
proxy_set_header Anthropic-Version $http_anthropic_version;
|
|
||||||
proxy_set_header Accept-Encoding "";
|
|
||||||
proxy_set_header X-Real-IP "";
|
|
||||||
proxy_set_header X-Forwarded-For "";
|
|
||||||
proxy_set_header X-Forwarded-Proto "";
|
|
||||||
proxy_set_header X-Forwarded-Host "";
|
|
||||||
proxy_set_header X-Forwarded-Port "";
|
|
||||||
proxy_set_header Connection "";
|
|
||||||
proxy_buffering off;
|
|
||||||
proxy_request_buffering off;
|
|
||||||
proxy_cache off;
|
|
||||||
proxy_cache_bypass 1;
|
|
||||||
proxy_connect_timeout 600s;
|
|
||||||
proxy_read_timeout 3600s;
|
|
||||||
proxy_send_timeout 3600s;
|
|
||||||
|
|
||||||
location = /v1/chat/completions {
|
|
||||||
client_body_buffer_size 16k;
|
|
||||||
|
|
||||||
content_by_lua_block {
|
|
||||||
local backend = "@ai_sggai_site_backend"
|
|
||||||
local max_body_bytes = 1024
|
|
||||||
|
|
||||||
if ngx.req.get_method() ~= "POST" then
|
|
||||||
return ngx.exec(backend)
|
|
||||||
end
|
|
||||||
|
|
||||||
local content_length = tonumber(ngx.var.http_content_length)
|
|
||||||
if not content_length then
|
|
||||||
return ngx.exec(backend)
|
|
||||||
end
|
|
||||||
|
|
||||||
if content_length > max_body_bytes then
|
|
||||||
return ngx.exec(backend)
|
|
||||||
end
|
|
||||||
|
|
||||||
ngx.req.read_body()
|
|
||||||
|
|
||||||
local body = ngx.req.get_body_data()
|
|
||||||
if not body or #body > max_body_bytes then
|
|
||||||
return ngx.exec(backend)
|
|
||||||
end
|
|
||||||
|
|
||||||
local cjson = require "cjson.safe"
|
|
||||||
local short_post_log = {
|
|
||||||
method = ngx.req.get_method(),
|
|
||||||
uri = ngx.var.request_uri,
|
|
||||||
content_length = content_length,
|
|
||||||
content_type = ngx.var.http_content_type,
|
|
||||||
user_agent = ngx.var.http_user_agent,
|
|
||||||
body = body
|
|
||||||
}
|
|
||||||
ngx.log(ngx.NOTICE, "[ai.sggai.site] short POST request: ", cjson.encode(short_post_log) or body)
|
|
||||||
|
|
||||||
local payload = cjson.decode(body)
|
|
||||||
if type(payload) ~= "table" or payload.stream ~= false then
|
|
||||||
return ngx.exec(backend)
|
|
||||||
end
|
|
||||||
|
|
||||||
if type(payload.messages) ~= "table" then
|
|
||||||
return ngx.exec(backend)
|
|
||||||
end
|
|
||||||
|
|
||||||
local has_hi_content = false
|
|
||||||
|
|
||||||
for _, message in ipairs(payload.messages) do
|
|
||||||
if type(message) == "table" and message.content == "hi" then
|
|
||||||
has_hi_content = true
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if not has_hi_content then
|
|
||||||
return ngx.exec(backend)
|
|
||||||
end
|
|
||||||
|
|
||||||
ngx.status = ngx.HTTP_OK
|
|
||||||
ngx.header["Content-Type"] = "application/json; charset=utf-8"
|
|
||||||
ngx.say([[{
|
|
||||||
"id": "chatcmpl-mock",
|
|
||||||
"object": "chat.completion",
|
|
||||||
"created": 1716030000,
|
|
||||||
"model": "xxx",
|
|
||||||
"choices": [
|
|
||||||
{
|
|
||||||
"index": 0,
|
|
||||||
"message": { "role": "assistant", "content": "ok" },
|
|
||||||
"finish_reason": "stop"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"usage": { "prompt_tokens": 1, "completion_tokens": 1, "total_tokens": 2 }
|
|
||||||
}]])
|
|
||||||
return ngx.exit(ngx.HTTP_OK)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
location @ai_sggai_site_backend {
|
|
||||||
proxy_pass http://10.1.0.1:3001;
|
|
||||||
}
|
|
||||||
|
|
||||||
location / {
|
|
||||||
proxy_pass http://10.1.0.1:3001;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
149
conf/conf.d/ai.sggai.site.conf.2back
Normal file
149
conf/conf.d/ai.sggai.site.conf.2back
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
# http2 on;
|
||||||
|
server_name ai.sggai.site;
|
||||||
|
|
||||||
|
location ^~ /.well-known/acme-challenge/ {
|
||||||
|
root /var/www;
|
||||||
|
default_type text/plain;
|
||||||
|
try_files $uri =404;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 关键:允许 Session_id 这种带下划线的请求头
|
||||||
|
# underscores_in_headers on;
|
||||||
|
# ignore_invalid_headers off;
|
||||||
|
|
||||||
|
client_max_body_size 200m;
|
||||||
|
|
||||||
|
gzip off;
|
||||||
|
gunzip off;
|
||||||
|
location / {
|
||||||
|
proxy_pass http://10.1.0.1:3001;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
|
||||||
|
# 保持你原来“模拟 IP 直连”的行为
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
|
||||||
|
# 基础请求头
|
||||||
|
proxy_set_header Authorization $http_authorization;
|
||||||
|
proxy_set_header Content-Type $http_content_type;
|
||||||
|
proxy_set_header Accept $http_accept;
|
||||||
|
proxy_set_header User-Agent $http_user_agent;
|
||||||
|
|
||||||
|
# 关键:Codex / 上游 prompt cache 相关头
|
||||||
|
proxy_set_header Originator $http_originator;
|
||||||
|
proxy_set_header Session_id $http_session_id;
|
||||||
|
proxy_set_header X-Codex-Beta-Features $http_x_codex_beta_features;
|
||||||
|
proxy_set_header X-Codex-Turn-Metadata $http_x_codex_turn_metadata;
|
||||||
|
|
||||||
|
# Claude CLI 相关头,保留无害
|
||||||
|
proxy_set_header X-Stainless-Arch $http_x_stainless_arch;
|
||||||
|
proxy_set_header X-Stainless-Lang $http_x_stainless_lang;
|
||||||
|
proxy_set_header X-Stainless-Os $http_x_stainless_os;
|
||||||
|
proxy_set_header X-Stainless-Package-Version $http_x_stainless_package_version;
|
||||||
|
proxy_set_header X-Stainless-Retry-Count $http_x_stainless_retry_count;
|
||||||
|
proxy_set_header X-Stainless-Runtime $http_x_stainless_runtime;
|
||||||
|
proxy_set_header X-Stainless-Runtime-Version $http_x_stainless_runtime_version;
|
||||||
|
proxy_set_header X-Stainless-Timeout $http_x_stainless_timeout;
|
||||||
|
proxy_set_header X-App $http_x_app;
|
||||||
|
proxy_set_header Anthropic-Beta $http_anthropic_beta;
|
||||||
|
proxy_set_header Anthropic-Dangerous-Direct-Browser-Access $http_anthropic_dangerous_direct_browser_access;
|
||||||
|
proxy_set_header Anthropic-Version $http_anthropic_version;
|
||||||
|
|
||||||
|
# 禁用压缩干扰
|
||||||
|
proxy_set_header Accept-Encoding "";
|
||||||
|
|
||||||
|
# 继续模拟直连,不暴露外层代理链
|
||||||
|
proxy_set_header X-Real-IP "";
|
||||||
|
proxy_set_header X-Forwarded-For "";
|
||||||
|
proxy_set_header X-Forwarded-Proto "";
|
||||||
|
proxy_set_header X-Forwarded-Host "";
|
||||||
|
proxy_set_header X-Forwarded-Port "";
|
||||||
|
|
||||||
|
proxy_set_header Connection "";
|
||||||
|
|
||||||
|
# SSE / 流式响应
|
||||||
|
proxy_buffering off;
|
||||||
|
proxy_request_buffering off;
|
||||||
|
proxy_cache off;
|
||||||
|
proxy_cache_bypass 1;
|
||||||
|
|
||||||
|
proxy_connect_timeout 600s;
|
||||||
|
proxy_read_timeout 3600s;
|
||||||
|
proxy_send_timeout 3600s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
# http2 on;
|
||||||
|
|
||||||
|
server_name ai.sggai.site;
|
||||||
|
|
||||||
|
ssl_certificate /etc/letsencrypt/live/ai.sggai.site/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/ai.sggai.site/privkey.pem;
|
||||||
|
|
||||||
|
# 关键:允许 Session_id 这种带下划线的请求头 http2 on 和下面这2个加上就容易出 status_code=400, Invalid 'prompt_cache_key': string too long. Expected a string with maximum length 64, but got a string with length 74 instead.
|
||||||
|
# underscores_in_headers on;
|
||||||
|
# ignore_invalid_headers off;
|
||||||
|
|
||||||
|
client_max_body_size 200m;
|
||||||
|
|
||||||
|
gzip off;
|
||||||
|
gunzip off;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://10.1.0.1:3001;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
|
||||||
|
# 保持你原来“模拟 IP 直连”的行为
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
|
||||||
|
# 基础请求头
|
||||||
|
proxy_set_header Authorization $http_authorization;
|
||||||
|
proxy_set_header Content-Type $http_content_type;
|
||||||
|
proxy_set_header Accept $http_accept;
|
||||||
|
proxy_set_header User-Agent $http_user_agent;
|
||||||
|
|
||||||
|
# 关键:Codex / 上游 prompt cache 相关头
|
||||||
|
proxy_set_header Originator $http_originator;
|
||||||
|
proxy_set_header Session_id $http_session_id;
|
||||||
|
proxy_set_header X-Codex-Beta-Features $http_x_codex_beta_features;
|
||||||
|
proxy_set_header X-Codex-Turn-Metadata $http_x_codex_turn_metadata;
|
||||||
|
|
||||||
|
# Claude CLI 相关头,保留无害
|
||||||
|
proxy_set_header X-Stainless-Arch $http_x_stainless_arch;
|
||||||
|
proxy_set_header X-Stainless-Lang $http_x_stainless_lang;
|
||||||
|
proxy_set_header X-Stainless-Os $http_x_stainless_os;
|
||||||
|
proxy_set_header X-Stainless-Package-Version $http_x_stainless_package_version;
|
||||||
|
proxy_set_header X-Stainless-Retry-Count $http_x_stainless_retry_count;
|
||||||
|
proxy_set_header X-Stainless-Runtime $http_x_stainless_runtime;
|
||||||
|
proxy_set_header X-Stainless-Runtime-Version $http_x_stainless_runtime_version;
|
||||||
|
proxy_set_header X-Stainless-Timeout $http_x_stainless_timeout;
|
||||||
|
proxy_set_header X-App $http_x_app;
|
||||||
|
proxy_set_header Anthropic-Beta $http_anthropic_beta;
|
||||||
|
proxy_set_header Anthropic-Dangerous-Direct-Browser-Access $http_anthropic_dangerous_direct_browser_access;
|
||||||
|
proxy_set_header Anthropic-Version $http_anthropic_version;
|
||||||
|
|
||||||
|
# 禁用压缩干扰
|
||||||
|
proxy_set_header Accept-Encoding "";
|
||||||
|
|
||||||
|
# 继续模拟直连,不暴露外层代理链
|
||||||
|
proxy_set_header X-Real-IP "";
|
||||||
|
proxy_set_header X-Forwarded-For "";
|
||||||
|
proxy_set_header X-Forwarded-Proto "";
|
||||||
|
proxy_set_header X-Forwarded-Host "";
|
||||||
|
proxy_set_header X-Forwarded-Port "";
|
||||||
|
|
||||||
|
proxy_set_header Connection "";
|
||||||
|
|
||||||
|
# SSE / 流式响应
|
||||||
|
proxy_buffering off;
|
||||||
|
proxy_request_buffering off;
|
||||||
|
proxy_cache off;
|
||||||
|
proxy_cache_bypass 1;
|
||||||
|
|
||||||
|
proxy_connect_timeout 600s;
|
||||||
|
proxy_read_timeout 3600s;
|
||||||
|
proxy_send_timeout 3600s;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user