解决codex无法使用fast mode的一种方式:改写http body

SakuraYukihana 2026-08-02 19:59 1

codex desktop使用API时无法启用fast mode,现有的修复方式都需要重新打包msix,更新后失效

同时sub2api的OpenAI Fast/Flex 策略有bug,pr和issue已经有人提交了一百次也没修

所以我研究搓了这种方式。


工作原理:nginx使用njs模块运行JavaScript脚本,先识别请求头中bearer api_key,然后改写/添加请求体中"service_tier": "fast"


首先,查看nginx是否安装了njs


nginx -V 2>&1
nginx -T 2>&1 | grep -E 'load_module|ngx_http_js_module'

输出load_module "/usr/lib/nginx/modules/ngx_http_js_module.so";就是已经安装


安装njs(虽然njs引擎已经弃用,但可以少装一个QuickJS)

如果你的nginx是新安装的,可以考虑切换到qjs

我使用的是arch,请按你的包管理器修改以下命令


pacman -Syu nginx-mod-njs

验证


nginx -T 2>&1 | grep ngx_http_js_module
nginx -t

写脚本:


mkdir /etc/nginx/njs
nano /etc/nginx/njs/request_body.js

/*
* 会触发 service_tier 修改的 API Key。
*
* Token 大小写敏感。
*/
const allowedKeys = {
"API_KEY_1": true,
"API_KEY_2": true,
"API_KEY_3": true,
};

async function rewriteBody(r) {
let originalBody;

/*
* proxy_set_body 始终使用 $upstream_body。
*
* 因此必须先保存原始 Body,再进行任何 return。
* 否则 Authorization 不匹配时,上游可能收到空 Body。
*/
try {
originalBody = await r.readRequestText();
} catch (e) {
r.error("Failed to read request body: " + e);
r.return(400, "Unable to read request body\n");
return;
}

r.variables.upstream_body = originalBody;

const authorization = r.headersIn.Authorization || "";

/*
* 接受:
* Authorization: Bearer TOKEN
*
* 允许 Bearer 大小写不同和末尾空白,
* 但 Token 中间不能含空格。
*/
const match = authorization.match(
/^Bearer[ \t]+([^ \t]+)[ \t]*$/i
);

if (match === null) {
return;
}

const token = match[1];

if (allowedKeys[token] !== true) {
return;
}

if (originalBody === "") {
r.return(400, "Request body is empty\n");
return;
}

let payload;

try {
payload = JSON.parse(originalBody);
} catch (e) {
r.return(400, "Request body must be valid JSON\n");
return;
}

if (
payload === null ||
Array.isArray(payload) ||
typeof payload !== "object"
) {
r.return(400, "Request body must be a JSON object\n");
return;
}

/*
* 已存在时覆盖,不存在时增加。
*/
payload.service_tier = "fast";

r.variables.upstream_body = JSON.stringify(payload);
}

export default {
rewriteBody,
};

然后修改nginx.conf中的http块


http{
...

js_path /etc/nginx/njs;
js_import request_body from request_body.js;
js_var $upstream_body;

...
}

注意,如果你有include来的http配置,include /etc/nginx/conf.d/*.conf;等包含sub2api/上游api的行必须在js_var后面


然后在负责api请求的location块中加入:


js_access request_body.rewriteBody;
proxy_set_body $upstream_body;

例如我的:


server {
listen 127.0.0.1:*** ssl proxy_protocol;
http2 on;

server_name ***;

ssl_certificate ***;
ssl_certificate_key ***;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

port_in_redirect off;

set_real_ip_from 127.0.0.1;
real_ip_header proxy_protocol;

location / {
client_max_body_size 64m;
client_body_buffer_size 64m;

js_access request_body.rewriteBody;
proxy_set_body $upstream_body;

proxy_pass http://127.0.0.1:***;
proxy_http_version 1.1;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Real-Port $remote_port;
proxy_set_header X-Forwarded-For $remote_addr;

proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $proxy_protocol_server_port;

proxy_set_header X-Original-URI $request_uri;
proxy_set_header X-Request-ID $request_id;

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;

proxy_buffering off;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
}
}


如果你用了stream模块转发流量,需要使用proxy_protocol的话,需要在http块中加入:


set_real_ip_from 127.0.0.1;
real_ip_header proxy_protocol;

然后:


nginx -t //验证配置

systemctl reload nginx //重启nginx
最新回复 (0)
    没有回复
* 帖子来源NodeSeek
返回