mirror of
https://github.com/praveentcom/openproxy.git
synced 2026-07-31 16:17:36 +02:00
feat: add UPSTREAM_URL validation and error handling in proxy request
This commit is contained in:
@@ -7,11 +7,11 @@ A lightweight, production-ready OpenAI-compatible proxy server that seamlessly f
|
|||||||
| Environment Variable | Description | Default Value |
|
| Environment Variable | Description | Default Value |
|
||||||
|----------------------|-------------|-----------------|
|
|----------------------|-------------|-----------------|
|
||||||
| `PORT` | Server port | `3007` |
|
| `PORT` | Server port | `3007` |
|
||||||
| `UPSTREAM_URL` | Your LLM endpoint URL | `""` |
|
| `UPSTREAM_URL` | Your LLM endpoint URL | **Required** |
|
||||||
| `DATABASE_URL` | PostgreSQL connection string for logging | `""` |
|
| `DATABASE_URL` | PostgreSQL connection string for logging | **Required** |
|
||||||
| `DATABASE_TABLE` | Name of the table to store the logs | `"llm_proxy"` |
|
| `DATABASE_TABLE` | Name of the table to store the logs | `"llm_proxy"` |
|
||||||
|
|
||||||
### Cost Calculation
|
## 💰 Cost Calculation
|
||||||
|
|
||||||
The cost is calculated based on the model and token usage with configurable pricing per model.
|
The cost is calculated based on the model and token usage with configurable pricing per model.
|
||||||
|
|
||||||
@@ -27,7 +27,9 @@ export const MODEL_COSTS: Record<string, CostConfig> = {
|
|||||||
|
|
||||||
You can add more models to the `MODEL_COSTS` object to support your specific LLM providers.
|
You can add more models to the `MODEL_COSTS` object to support your specific LLM providers.
|
||||||
|
|
||||||
## 📊 PostgreSQL Table Schema
|
## 📊 Database Table Schema
|
||||||
|
|
||||||
|
Before running the proxy, you need to create the table in the database.
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
CREATE TABLE IF NOT EXISTS <DATABASE_TABLE> (
|
CREATE TABLE IF NOT EXISTS <DATABASE_TABLE> (
|
||||||
|
|||||||
@@ -12,6 +12,12 @@ import { calculateCost } from "./cost";
|
|||||||
const PORT = Number(process.env.PORT || 3007);
|
const PORT = Number(process.env.PORT || 3007);
|
||||||
const UPSTREAM_URL = (process.env.UPSTREAM_URL || "").replace(/\/+$/, "");
|
const UPSTREAM_URL = (process.env.UPSTREAM_URL || "").replace(/\/+$/, "");
|
||||||
|
|
||||||
|
// Validate UPSTREAM_URL is configured
|
||||||
|
if (!UPSTREAM_URL) {
|
||||||
|
console.error("❌ UPSTREAM_URL environment variable is required");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
// --- PostgreSQL connection ---
|
// --- PostgreSQL connection ---
|
||||||
const pool = new Pool({
|
const pool = new Pool({
|
||||||
connectionString: process.env.DATABASE_URL,
|
connectionString: process.env.DATABASE_URL,
|
||||||
@@ -80,16 +86,26 @@ const server = http.createServer(async (req, res) => {
|
|||||||
const bodyBuf = method === "POST" ? await readBody(req) : Buffer.from("");
|
const bodyBuf = method === "POST" ? await readBody(req) : Buffer.from("");
|
||||||
const requestJson = bodyBuf.length ? JSON.parse(bodyBuf.toString()) : null;
|
const requestJson = bodyBuf.length ? JSON.parse(bodyBuf.toString()) : null;
|
||||||
|
|
||||||
const upstreamRes = await fetch(UPSTREAM_URL + path + url.search, {
|
const targetUrl = UPSTREAM_URL + path + url.search;
|
||||||
method,
|
|
||||||
headers: {
|
let upstreamRes;
|
||||||
"Content-Type": (req.headers["content-type"] as string) || "application/json",
|
try {
|
||||||
Authorization: auth.toString(),
|
upstreamRes = await fetch(targetUrl, {
|
||||||
},
|
method,
|
||||||
// @ts-ignore
|
headers: {
|
||||||
duplex: "half",
|
"Content-Type": (req.headers["content-type"] as string) || "application/json",
|
||||||
body: method === "POST" ? bodyBuf.toString() : undefined,
|
Authorization: auth.toString(),
|
||||||
});
|
},
|
||||||
|
// @ts-ignore
|
||||||
|
duplex: "half",
|
||||||
|
body: method === "POST" ? bodyBuf.toString() : undefined,
|
||||||
|
});
|
||||||
|
} catch (fetchError: any) {
|
||||||
|
console.error("Fetch error:", fetchError.message, "URL:", targetUrl);
|
||||||
|
res.statusCode = 502;
|
||||||
|
res.end(JSON.stringify({ error: "Failed to connect to upstream", message: fetchError.message }));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const contentType = upstreamRes.headers.get("content-type") || "application/json";
|
const contentType = upstreamRes.headers.get("content-type") || "application/json";
|
||||||
res.statusCode = upstreamRes.status;
|
res.statusCode = upstreamRes.status;
|
||||||
|
|||||||
Reference in New Issue
Block a user