mirror of
https://github.com/QuantumNous/new-api.git
synced 2026-04-18 04:57:26 +00:00
(jsrt) fix: fetch
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package jsrt
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
@@ -14,16 +15,15 @@ type JSFetchRequest struct {
|
||||
Method string `json:"method"`
|
||||
URL string `json:"url"`
|
||||
Headers map[string]string `json:"headers"`
|
||||
Body string `json:"body"`
|
||||
Body any `json:"body"`
|
||||
Timeout int `json:"timeout"`
|
||||
}
|
||||
|
||||
type JSFetchResponse struct {
|
||||
Status int `json:"status"`
|
||||
StatusText string `json:"statusText"`
|
||||
Headers map[string]string `json:"headers"`
|
||||
Body string `json:"body"`
|
||||
OK bool `json:"ok"`
|
||||
Status int `json:"status"`
|
||||
Headers map[string]string `json:"headers"`
|
||||
Body string `json:"body"`
|
||||
Error string `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
func (p *JSRuntimePool) fetch(url string, options ...any) *JSFetchResponse {
|
||||
@@ -54,17 +54,7 @@ func (p *JSRuntimePool) fetch(url string, options ...any) *JSFetchResponse {
|
||||
}
|
||||
|
||||
if body, exists := optMap["body"]; exists {
|
||||
switch v := body.(type) {
|
||||
case string:
|
||||
req.Body = v
|
||||
case map[string]any:
|
||||
if bodyBytes, err := json.Marshal(v); err == nil {
|
||||
req.Body = string(bodyBytes)
|
||||
req.Headers["Content-Type"] = "application/json"
|
||||
}
|
||||
default:
|
||||
req.Body = fmt.Sprintf("%v", body)
|
||||
}
|
||||
req.Body = body
|
||||
}
|
||||
|
||||
if timeout, exists := optMap["timeout"]; exists {
|
||||
@@ -77,18 +67,27 @@ func (p *JSRuntimePool) fetch(url string, options ...any) *JSFetchResponse {
|
||||
|
||||
// 创建HTTP请求
|
||||
var bodyReader io.Reader
|
||||
if req.Body != "" {
|
||||
bodyReader = strings.NewReader(req.Body)
|
||||
switch body := req.Body.(type) {
|
||||
case string:
|
||||
bodyReader = strings.NewReader(body)
|
||||
case []byte:
|
||||
bodyReader = bytes.NewReader(body)
|
||||
case nil:
|
||||
bodyReader = nil
|
||||
default:
|
||||
bodyBytes, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
return &JSFetchResponse{
|
||||
Error: fmt.Sprintf("Failed to marshal body: %v", err),
|
||||
}
|
||||
}
|
||||
bodyReader = bytes.NewReader(bodyBytes)
|
||||
}
|
||||
|
||||
httpReq, err := http.NewRequest(req.Method, req.URL, bodyReader)
|
||||
if err != nil {
|
||||
return &JSFetchResponse{
|
||||
Status: 0,
|
||||
StatusText: err.Error(),
|
||||
Headers: make(map[string]string),
|
||||
Body: "",
|
||||
OK: false,
|
||||
Error: err.Error(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,13 +109,7 @@ func (p *JSRuntimePool) fetch(url string, options ...any) *JSFetchResponse {
|
||||
// 执行请求
|
||||
resp, err := p.httpClient.Do(httpReq)
|
||||
if err != nil {
|
||||
return &JSFetchResponse{
|
||||
Status: 0,
|
||||
StatusText: err.Error(),
|
||||
Headers: make(map[string]string),
|
||||
Body: "",
|
||||
OK: false,
|
||||
}
|
||||
return &JSFetchResponse{}
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
@@ -124,11 +117,7 @@ func (p *JSRuntimePool) fetch(url string, options ...any) *JSFetchResponse {
|
||||
bodyBytes, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return &JSFetchResponse{
|
||||
Status: resp.StatusCode,
|
||||
StatusText: resp.Status,
|
||||
Headers: make(map[string]string),
|
||||
Body: "",
|
||||
OK: resp.StatusCode >= 200 && resp.StatusCode < 300,
|
||||
Status: resp.StatusCode,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,10 +130,8 @@ func (p *JSRuntimePool) fetch(url string, options ...any) *JSFetchResponse {
|
||||
}
|
||||
|
||||
return &JSFetchResponse{
|
||||
Status: resp.StatusCode,
|
||||
StatusText: resp.Status,
|
||||
Headers: headers,
|
||||
Body: string(bodyBytes),
|
||||
OK: resp.StatusCode >= 200 && resp.StatusCode < 300,
|
||||
Status: resp.StatusCode,
|
||||
Headers: headers,
|
||||
Body: string(bodyBytes),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,6 +146,7 @@ func (p *JSRuntimePool) setupGlobals(vm *goja.Runtime) {
|
||||
|
||||
// 数据库
|
||||
vm.Set("db", &JSDatabase{db: model.DB})
|
||||
vm.Set("logdb", &JSDatabase{db: model.LOG_DB})
|
||||
|
||||
// 定时器
|
||||
vm.Set("setTimeout", func(fn func(), delay int) {
|
||||
|
||||
@@ -30,34 +30,137 @@ function preProcessRequest(ctx) {
|
||||
// }
|
||||
|
||||
// 例子:修改请求
|
||||
if (ctx.URL.includes("/v1/chat/completions")) {
|
||||
try {
|
||||
var bodyObj = ctx.Body;
|
||||
// if (ctx.URL.includes("/v1/chat/completions")) {
|
||||
// try {
|
||||
// var bodyObj = ctx.Body;
|
||||
|
||||
let firstMsg = {
|
||||
role: "user",
|
||||
content: "今天天气怎么样"
|
||||
};
|
||||
bodyObj.messages[0] = firstMsg;
|
||||
console.log("Modified first message:", JSON.stringify(firstMsg));
|
||||
console.log("Modified body:", JSON.stringify(bodyObj));
|
||||
// let firstMsg = { // 需要新建一个对象,不能修改原有对象
|
||||
// role: "user",
|
||||
// content: "今天天气怎么样"
|
||||
// };
|
||||
// bodyObj.messages[0] = firstMsg;
|
||||
// console.log("Modified first message:", JSON.stringify(firstMsg));
|
||||
// console.log("Modified body:", JSON.stringify(bodyObj));
|
||||
|
||||
return {
|
||||
body: bodyObj,
|
||||
headers: {
|
||||
...ctx.Headers,
|
||||
"X-Modified-Body": "true"
|
||||
}
|
||||
};
|
||||
} catch (e) {
|
||||
console.error("Failed to modify request body:", {
|
||||
message: e.message,
|
||||
stack: e.stack,
|
||||
bodyType: typeof ctx.Body,
|
||||
url: ctx.URL
|
||||
});
|
||||
}
|
||||
}
|
||||
// return {
|
||||
// body: bodyObj,
|
||||
// headers: {
|
||||
// ...ctx.Headers,
|
||||
// "X-Modified-Body": "true"
|
||||
// }
|
||||
// };
|
||||
// } catch (e) {
|
||||
// console.error("Failed to modify request body:", {
|
||||
// message: e.message,
|
||||
// stack: e.stack,
|
||||
// bodyType: typeof ctx.Body,
|
||||
// url: ctx.URL
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
// // 例子:读取最近一条日志,新增 jsrt 日志,并输出日志总数
|
||||
// if (ctx.URL) {
|
||||
// try {
|
||||
// // 1. 读取最近一条日志
|
||||
// var recentLogs = logdb.Query(
|
||||
// "SELECT id, user_id, username, content, created_at FROM logs ORDER BY id DESC LIMIT 1"
|
||||
// );
|
||||
|
||||
// var recentLog = null;
|
||||
// if (recentLogs && recentLogs.length > 0) {
|
||||
// recentLog = recentLogs[0];
|
||||
// console.log("最近一条日志:", JSON.stringify(recentLog));
|
||||
// }
|
||||
|
||||
// // 2. 新增一条 jsrt 日志
|
||||
// var currentTimestamp = Math.floor(Date.now() / 1000);
|
||||
// var jsrtLogContent = "JSRT 预处理中间件执行 - " + ctx.URL + " - " + new Date().toISOString();
|
||||
|
||||
// var insertResult = logdb.Exec(
|
||||
// "INSERT INTO logs (user_id, username, created_at, type, content) VALUES (?, ?, ?, ?, ?)",
|
||||
// ctx.UserID || 0,
|
||||
// ctx.Username || "jsrt-system",
|
||||
// currentTimestamp,
|
||||
// 4, // LogTypeSystem
|
||||
// jsrtLogContent
|
||||
// );
|
||||
|
||||
// if (insertResult.error) {
|
||||
// console.error("插入 JSRT 日志失败:", insertResult.error);
|
||||
// } else {
|
||||
// console.log("成功插入 JSRT 日志,影响行数:", insertResult.rowsAffected);
|
||||
// }
|
||||
|
||||
// // 3. 输出日志总数
|
||||
// var totalLogsResult = logdb.Query("SELECT COUNT(*) as total FROM logs");
|
||||
// var totalLogs = 0;
|
||||
// if (totalLogsResult && totalLogsResult.length > 0) {
|
||||
// totalLogs = totalLogsResult[0].total;
|
||||
// }
|
||||
|
||||
// console.log("当前日志总数:", totalLogs);
|
||||
// console.log("JSRT 日志管理示例执行完成");
|
||||
|
||||
// } catch (e) {
|
||||
// console.error("JSRT 日志管理示例执行失败:", {
|
||||
// message: e.message,
|
||||
// stack: e.stack,
|
||||
// url: ctx.URL
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
// // 例子:使用 fetch 调用外部 API
|
||||
// if (ctx.URL.includes("/api/uptime/status")) {
|
||||
// try {
|
||||
// // 使用 httpbin.org/ip 测试 fetch 功能
|
||||
// var response = fetch("https://httpbin.org/ip", {
|
||||
// method: "GET",
|
||||
// timeout: 5, // 5秒超时
|
||||
// headers: {
|
||||
// "User-Agent": "OneAPI-JSRT/1.0"
|
||||
// }
|
||||
// });
|
||||
|
||||
// if (response.Error.length === 0) {
|
||||
// // 解析响应体
|
||||
// var ipData = JSON.parse(response.Body);
|
||||
|
||||
// // 可以根据获取到的 IP 信息进行后续处理
|
||||
// if (ipData.origin) {
|
||||
// console.log("外部 IP 地址:", ipData.origin);
|
||||
|
||||
// // 示例:记录 IP 信息到数据库
|
||||
// var currentTimestamp = Math.floor(Date.now() / 1000);
|
||||
// var logContent = "Fetch 示例 - 外部 IP: " + ipData.origin + " - " + new Date().toISOString();
|
||||
|
||||
// var insertResult = logdb.Exec(
|
||||
// "INSERT INTO logs (user_id, username, created_at, type, content) VALUES (?, ?, ?, ?, ?)",
|
||||
// ctx.UserID || 0,
|
||||
// ctx.Username || "jsrt-fetch",
|
||||
// currentTimestamp,
|
||||
// 4, // LogTypeSystem
|
||||
// logContent
|
||||
// );
|
||||
|
||||
// if (insertResult.error) {
|
||||
// console.error("记录 IP 信息失败:", insertResult.error);
|
||||
// } else {
|
||||
// console.log("成功记录 IP 信息到数据库");
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// console.error("Fetch 失败 ", response.Status, " ", response.Error);
|
||||
// }
|
||||
// } catch (e) {
|
||||
// console.error("Fetch 失败:", {
|
||||
// message: e.message,
|
||||
// stack: e.stack,
|
||||
// url: ctx.URL
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
return undefined; // 跳过处理,继续执行下一个中间件或路由
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user