chatgpt-demo
chatgpt-demo copied to clipboard
Add support for reverse proxy servers
Clear and concise description of the problem
我使用hk博客搭建了一个api反代,可以免魔法访问api(不用设置https_proxy)
然后可以在代码中增加对反代的支持吗?
Suggested solution
我改动了两处,简单实现了一下,可以放到您的代码库中吗? .env文件:
# Your API Key for OpenAI
OPENAI_API_KEY=keykeykey
# Provide proxy for OpenAI API. e.g. http://127.0.0.1:7890
#HTTPS_PROXY=no set
Reverse_Proxy_Server=https://xxx.com/openai/
#this is my honkong blog
# Inject analytics or other scripts before </head> of the page
HEAD_SCRIPTS=
在generate.ts:
import type { APIRoute } from 'astro'
import { generatePayload, parseOpenAIStream } from '@/utils/openAI'
// #vercel-disable-blocks
import { fetch, ProxyAgent } from 'undici'
// #vercel-end
const apiKey = import.meta.env.OPENAI_API_KEY
const https_proxy = import.meta.env.HTTPS_PROXY
const Reverse_Proxy_Server = import.meta.env.Reverse_Proxy_Server //我增加的
export const post: APIRoute = async (context) => {
const body = await context.request.json()
const messages = body.messages
if (!messages) {
return new Response('No input text')
}
const initOptions = generatePayload(apiKey, messages)
// #vercel-disable-blocks
if (https_proxy) {
initOptions['dispatcher'] = new ProxyAgent(https_proxy)
}
// #vercel-end
// @ts-ignore
const response = await fetch(Reverse_Proxy_Server?Reverse_Proxy_Server.trim():'https://api.openai.com/v1/chat/completions', initOptions) as Response //我改动的
return new Response(parseOpenAIStream(response))
}
另外,我用nodejs实现stream反代,可以给第三方参考:
const http = require("http");
const https = require("https");
const url = require("url");
/***************************************
*
* 请留意,这仅仅是链接到openai的一个接口,纯文本,
* 并不消耗大量服务器流量,望理解
*
* ***********************************/
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;
process.NODE_NO_WARNINGS = 1;
process.removeAllListeners('warning');
var server = http.createServer( function(request,response) {
response.writeHead(200,{'Content-Type':'application/json;charset=UTF8','Access-Control-Allow-Origin':'*',"Access-Control-Allow-Headers":"Authorization,Content-Type"});
var body = ''
request.on('data', function (chunk) {
body += chunk;
});
request.on('end', async function () {
try{
headers = request.headers
var authorization = ""
for(let i in headers){
if(i.trim().toLocaleLowerCase()==="authorization"){
authorization = headers[i].trim()
break;
}
}
var json1 = await fetchData(authorization, body,response);
// response.write(json1);
}catch(e){
response.write('{"error":"'+e+'"}');
}
response.end();
});
});
server.listen(3001);
function fetchData(authorization, body,response) {
const https = require('https');
const options = {
hostname: 'api.openai.com',
path: '/v1/chat/completions',
method: 'POST',
headers: {
'authorization': authorization,
'content-type': 'application/json'
}
};
return new Promise((resolve, reject) => {
const req = https.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
response.write(chunk)
});
res.on('end', () => {
const result = data.trim();
resolve(result);
});
});
req.on('error', (error) => {
reject(error);
});
req.write(body);
req.end();
});
}
Alternative
No response
Additional context
No response
Validations
- [X] Follow our Code of Conduct
- [X] Read the Contributing Guide.
- [X] Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
PR Welcome. 另外,反代服务器建议仅填入 host 前缀部分,如 "https://api.proxy-openai.com/",环境变量起名可以用 OPENAI_API_BASE_URL