├── .gitignore ├── netlify └── fun.js ├── netlify.toml ├── vercel.json ├── uninstall.sh ├── package.json ├── install.sh ├── api └── proxy.js ├── app.js ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | /node_modules 3 | package-lock.json 4 | -------------------------------------------------------------------------------- /netlify/fun.js: -------------------------------------------------------------------------------- 1 | import serverless from 'serverless-http'; 2 | import app from '../api/proxy.js'; 3 | 4 | export const handler = serverless(app); -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | functions = "netlify" 3 | 4 | [[redirects]] 5 | from = "/*" 6 | to = "/.netlify/functions/fun/:splat" 7 | status = 200 8 | -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "routes": [ 4 | { 5 | "src": "/(.*)", 6 | "dest": "/api/proxy" 7 | } 8 | ] 9 | } -------------------------------------------------------------------------------- /uninstall.sh: -------------------------------------------------------------------------------- 1 | service_path="/etc/systemd/system/api-proxy.service" 2 | 3 | echo 正在卸载... 4 | 5 | systemctl stop api-proxy 6 | rm -f $service_path 7 | systemctl daemon-reload 8 | 9 | echo 卸载完成! 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "dependencies": { 4 | "express": "^4.18.2", 5 | "http-proxy-middleware": "^2.0.6", 6 | "serverless-http": "^3.2.0" 7 | }, 8 | "scripts": { 9 | "start": "node app.js" 10 | }, 11 | "engines": { 12 | "node": ">=14" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | install_path=$(pwd) 2 | service_path="/etc/systemd/system/api-proxy.service" 3 | 4 | echo 正在安装... 5 | 6 | npm install 7 | 8 | cat << EOF > $service_path 9 | [Unit] 10 | Description=API Proxy Service 11 | After=network.target 12 | 13 | [Service] 14 | Restart=always 15 | RestartSec=5 16 | ExecStart=npm start 17 | Environment=NODE_ENV=production 18 | WorkingDirectory=${install_path} 19 | 20 | [Install] 21 | WantedBy=multi-user.target 22 | EOF 23 | 24 | systemctl daemon-reload 25 | 26 | echo 安装完成! 27 | -------------------------------------------------------------------------------- /api/proxy.js: -------------------------------------------------------------------------------- 1 | import express from 'express'; 2 | import { createProxyMiddleware } from 'http-proxy-middleware'; 3 | 4 | const app = express(); 5 | 6 | // 代理地址 7 | const PROXY_TARGETS = [ 8 | { path: "/api/proxy/openai", target: "https://api.openai.com" }, 9 | { path: "/api/proxy/google", target: "https://generativelanguage.googleapis.com" }, 10 | { path: "/api/proxy/anthropic", target: "https://api.anthropic.com" }, 11 | ] 12 | 13 | PROXY_TARGETS.forEach(({ path, target }) => { 14 | app.use(path, createProxyMiddleware({ 15 | target: target, 16 | changeOrigin: true, 17 | pathRewrite: { 18 | [`^${path}`]: '', 19 | } 20 | })); 21 | }); 22 | 23 | export default app; -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | import http from 'http'; 2 | import https from "https"; 3 | import fs from "fs"; 4 | import app from './api/proxy.js'; 5 | 6 | const PORT = process.env.PORT || 443; 7 | 8 | // 证书路径 9 | const PRIVATE_KEY = "./certs/key.pem"; 10 | const CERT_CHAIN = "./certs/cert.pem"; 11 | 12 | // 证书 13 | let credentials = null; 14 | try { 15 | credentials = { 16 | key: fs.readFileSync(PRIVATE_KEY, 'utf8'), 17 | cert: fs.readFileSync(CERT_CHAIN, 'utf8') 18 | }; 19 | } catch (_) { 20 | console.log("No SSL certificate provided, using HTTP."); 21 | } 22 | 23 | const server = credentials ? https.createServer(credentials, app) : http.createServer(app); 24 | 25 | server.listen(PORT, () => { 26 | console.log(`Proxy server is running on port ${PORT}`); 27 | }); 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 TheRam_ 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # api-proxy 2 | 3 | 4 | 5 | 该项目为代理服务器,仅供学习和研究使用。 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | ## 快速开始 14 | 15 | - 安装 16 | 17 | ```bash 18 | git clone https://github.com/TheRamU/api-proxy.git 19 | cd api-proxy 20 | npm install 21 | ``` 22 | 23 | - 配置证书 24 | 25 | `app.js` 26 | 27 | ```js 28 | const PRIVATE_KEY = "./certs/key.pem"; 29 | const CERT_CHAIN = "./certs/cert.pem"; 30 | ``` 31 | 32 | - 运行 33 | 34 | ```bash 35 | npm start 36 | ``` 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | ## 以 Systemctl 方式运行 45 | 46 | 47 | 48 | - 安装 49 | 50 | ```bash 51 | git clone https://github.com/TheRamU/api-proxy.git 52 | cd api-proxy 53 | sh install.sh 54 | ``` 55 | 56 | - 配置证书 57 | 58 | `app.js` 59 | 60 | ```js 61 | const PRIVATE_KEY = "./certs/key.pem"; 62 | const CERT_CHAIN = "./certs/cert.pem"; 63 | ``` 64 | 65 | - 启动服务 & 配置自启动 66 | 67 | ```bash 68 | sudo systemctl start api-proxy 69 | sudo systemctl enable api-proxy 70 | ``` 71 | 72 | 启动失败 73 | 74 | ```bash 75 | vim /etc/sysconfig/selinux 76 | ``` 77 | 78 | ``` 79 | SELINUX=disabled 80 | ``` 81 | 82 | 83 | 84 | 85 | 86 | 87 | ## 部署服务 88 | 89 | [![](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/TheRamU/api-proxy) 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | ## 代理API 98 | 99 | - **OpenAI**:https://proxyhost/api/proxy/openai 100 | 101 | ```bash 102 | curl https://proxyhost/api/proxy/openai/v1/completions \ 103 | -H "Authorization: Bearer $OPENAI_API_KEY" \ 104 | -H "Content-Type: application/json" \ 105 | -d '{"prompt": YOUR_PROMPT, "model": MODEL}' 106 | ``` 107 | 108 | - **Google**:https://proxyhost/api/proxy/google 109 | 110 | ```bash 111 | curl \ 112 | -H 'Content-Type: application/json' \ 113 | -d '{"contents":[{"parts":[{"text":"Hello"}]}]}' \ 114 | -X POST https://proxyhost/api/proxy/google/v1beta/models/gemini-pro:generateContent?key=YOUR_API_KEY 115 | ``` 116 | 117 | - **Anthropic**:https://proxyhost/api/proxy/anthropic 118 | 119 | ```bash 120 | curl https://proxyhost/api/proxy/anthropic/v1/messages \ 121 | --header "x-api-key: $ANTHROPIC_API_KEY" \ 122 | --header "anthropic-version: 2023-06-01" \ 123 | --header "content-type: application/json" \ 124 | --data \ 125 | '{ 126 | "model": "claude-3-opus-20240229", 127 | "max_tokens": 1024, 128 | "messages": [ 129 | {"role": "user", "content": "Hello, world"} 130 | ] 131 | }' 132 | ``` --------------------------------------------------------------------------------