Spaces:
Configuration error
Configuration error
BOHE
commited on
Commit
·
0c2a71c
1
Parent(s):
9e2c5ce
测试
Browse files- api/main.go +105 -34
api/main.go
CHANGED
|
@@ -8,6 +8,7 @@ import (
|
|
| 8 |
"io"
|
| 9 |
"mime/multipart"
|
| 10 |
"net/http"
|
|
|
|
| 11 |
"os"
|
| 12 |
"path/filepath"
|
| 13 |
"strings"
|
|
@@ -277,9 +278,11 @@ func Handler(w http.ResponseWriter, r *http.Request) {
|
|
| 277 |
// 1. 获取 nonce
|
| 278 |
nonceResp, err := getNonce(dsToken)
|
| 279 |
if err != nil {
|
|
|
|
| 280 |
http.Error(w, "Failed to get nonce", http.StatusInternalServerError)
|
| 281 |
return
|
| 282 |
}
|
|
|
|
| 283 |
|
| 284 |
// 2. 创建临时文件,包含所有消息内容
|
| 285 |
var fileContent strings.Builder
|
|
@@ -292,6 +295,7 @@ func Handler(w http.ResponseWriter, r *http.Request) {
|
|
| 292 |
|
| 293 |
tempFile := fmt.Sprintf("temp_%s.txt", nonceResp.Uuid)
|
| 294 |
if err := os.WriteFile(tempFile, []byte(fileContent.String()), 0644); err != nil {
|
|
|
|
| 295 |
http.Error(w, "Failed to create temp file", http.StatusInternalServerError)
|
| 296 |
return
|
| 297 |
}
|
|
@@ -300,9 +304,11 @@ func Handler(w http.ResponseWriter, r *http.Request) {
|
|
| 300 |
// 3. 上传文件
|
| 301 |
uploadResp, err := uploadFile(dsToken, tempFile)
|
| 302 |
if err != nil {
|
|
|
|
| 303 |
http.Error(w, "Failed to upload file", http.StatusInternalServerError)
|
| 304 |
return
|
| 305 |
}
|
|
|
|
| 306 |
|
| 307 |
// 4. 修改消息列表,只保留文件引用
|
| 308 |
openAIReq.Messages = []Message{
|
|
@@ -321,11 +327,18 @@ func Handler(w http.ResponseWriter, r *http.Request) {
|
|
| 321 |
"size_bytes": len(fileContent.String()),
|
| 322 |
},
|
| 323 |
}
|
| 324 |
-
sourcesJSON,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 325 |
|
| 326 |
// 更新查询参数
|
| 327 |
q := youReq.URL.Query()
|
| 328 |
-
|
|
|
|
|
|
|
| 329 |
q.Add("chatId", chatId)
|
| 330 |
q.Add("queryTraceId", chatId)
|
| 331 |
q.Add("conversationTurnId", conversationTurnId)
|
|
@@ -345,6 +358,64 @@ func Handler(w http.ResponseWriter, r *http.Request) {
|
|
| 345 |
q.Add("use_nested_youchat_updates", "true")
|
| 346 |
q.Add("chat", string(chatHistoryJSON))
|
| 347 |
youReq.URL.RawQuery = q.Encode()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 348 |
} else {
|
| 349 |
// 构建常规查询参数
|
| 350 |
q := youReq.URL.Query()
|
|
@@ -367,42 +438,42 @@ func Handler(w http.ResponseWriter, r *http.Request) {
|
|
| 367 |
q.Add("use_nested_youchat_updates", "true")
|
| 368 |
q.Add("chat", string(chatHistoryJSON))
|
| 369 |
youReq.URL.RawQuery = q.Encode()
|
| 370 |
-
}
|
| 371 |
|
| 372 |
-
|
| 373 |
-
|
| 374 |
-
|
| 375 |
-
|
| 376 |
-
|
| 377 |
-
|
| 378 |
-
|
| 379 |
-
|
| 380 |
-
|
| 381 |
-
|
| 382 |
-
|
| 383 |
-
|
| 384 |
-
|
| 385 |
-
|
| 386 |
-
|
| 387 |
-
|
| 388 |
-
|
| 389 |
-
|
| 390 |
|
| 391 |
-
|
| 392 |
-
|
| 393 |
-
|
| 394 |
-
|
| 395 |
-
|
| 396 |
-
|
| 397 |
-
|
| 398 |
|
| 399 |
-
|
| 400 |
-
|
| 401 |
-
|
| 402 |
-
|
| 403 |
-
|
| 404 |
|
| 405 |
-
|
|
|
|
| 406 |
}
|
| 407 |
|
| 408 |
// getCookies 根据提供的 DS token 生成所需的 Cookie。
|
|
|
|
| 8 |
"io"
|
| 9 |
"mime/multipart"
|
| 10 |
"net/http"
|
| 11 |
+
"net/url"
|
| 12 |
"os"
|
| 13 |
"path/filepath"
|
| 14 |
"strings"
|
|
|
|
| 278 |
// 1. 获取 nonce
|
| 279 |
nonceResp, err := getNonce(dsToken)
|
| 280 |
if err != nil {
|
| 281 |
+
fmt.Printf("获取 nonce 失败: %v\n", err)
|
| 282 |
http.Error(w, "Failed to get nonce", http.StatusInternalServerError)
|
| 283 |
return
|
| 284 |
}
|
| 285 |
+
fmt.Printf("获取到 nonce: %s\n", nonceResp.Uuid)
|
| 286 |
|
| 287 |
// 2. 创建临时文件,包含所有消息内容
|
| 288 |
var fileContent strings.Builder
|
|
|
|
| 295 |
|
| 296 |
tempFile := fmt.Sprintf("temp_%s.txt", nonceResp.Uuid)
|
| 297 |
if err := os.WriteFile(tempFile, []byte(fileContent.String()), 0644); err != nil {
|
| 298 |
+
fmt.Printf("创建临时文件失败: %v\n", err)
|
| 299 |
http.Error(w, "Failed to create temp file", http.StatusInternalServerError)
|
| 300 |
return
|
| 301 |
}
|
|
|
|
| 304 |
// 3. 上传文件
|
| 305 |
uploadResp, err := uploadFile(dsToken, tempFile)
|
| 306 |
if err != nil {
|
| 307 |
+
fmt.Printf("上传文件失败: %v\n", err)
|
| 308 |
http.Error(w, "Failed to upload file", http.StatusInternalServerError)
|
| 309 |
return
|
| 310 |
}
|
| 311 |
+
fmt.Printf("文件上传成功: filename=%s, user_filename=%s\n", uploadResp.Filename, uploadResp.UserFilename)
|
| 312 |
|
| 313 |
// 4. 修改消息列表,只保留文件引用
|
| 314 |
openAIReq.Messages = []Message{
|
|
|
|
| 327 |
"size_bytes": len(fileContent.String()),
|
| 328 |
},
|
| 329 |
}
|
| 330 |
+
sourcesJSON, err := json.Marshal(sources)
|
| 331 |
+
if err != nil {
|
| 332 |
+
fmt.Printf("序列化 sources 失败: %v\n", err)
|
| 333 |
+
http.Error(w, "Failed to marshal sources", http.StatusInternalServerError)
|
| 334 |
+
return
|
| 335 |
+
}
|
| 336 |
|
| 337 |
// 更新查询参数
|
| 338 |
q := youReq.URL.Query()
|
| 339 |
+
// URL 编码 sources JSON
|
| 340 |
+
encodedSources := url.QueryEscape(string(sourcesJSON))
|
| 341 |
+
q.Add("sources", encodedSources)
|
| 342 |
q.Add("chatId", chatId)
|
| 343 |
q.Add("queryTraceId", chatId)
|
| 344 |
q.Add("conversationTurnId", conversationTurnId)
|
|
|
|
| 358 |
q.Add("use_nested_youchat_updates", "true")
|
| 359 |
q.Add("chat", string(chatHistoryJSON))
|
| 360 |
youReq.URL.RawQuery = q.Encode()
|
| 361 |
+
|
| 362 |
+
fmt.Printf("构建的请求 URL: %s\n", youReq.URL.String())
|
| 363 |
+
|
| 364 |
+
// 设置请求头
|
| 365 |
+
youReq.Header = http.Header{
|
| 366 |
+
"sec-ch-ua-platform": {"Windows"},
|
| 367 |
+
"Cache-Control": {"no-cache"},
|
| 368 |
+
"sec-ch-ua": {`"Not(A:Brand";v="99", "Microsoft Edge";v="133", "Chromium";v="133"`},
|
| 369 |
+
"sec-ch-ua-bitness": {"64"},
|
| 370 |
+
"sec-ch-ua-model": {""},
|
| 371 |
+
"sec-ch-ua-mobile": {"?0"},
|
| 372 |
+
"sec-ch-ua-arch": {"x86"},
|
| 373 |
+
"sec-ch-ua-full-version": {"133.0.3065.39"},
|
| 374 |
+
"Accept": {"text/event-stream"},
|
| 375 |
+
"User-Agent": {"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36 Edg/133.0.0.0"},
|
| 376 |
+
"sec-ch-ua-platform-version": {"19.0.0"},
|
| 377 |
+
"Sec-Fetch-Site": {"same-origin"},
|
| 378 |
+
"Sec-Fetch-Mode": {"cors"},
|
| 379 |
+
"Sec-Fetch-Dest": {"empty"},
|
| 380 |
+
"Host": {"you.com"},
|
| 381 |
+
}
|
| 382 |
+
|
| 383 |
+
// 设置 Cookie
|
| 384 |
+
cookies := getCookies(dsToken)
|
| 385 |
+
var cookieStrings []string
|
| 386 |
+
for name, value := range cookies {
|
| 387 |
+
cookieStrings = append(cookieStrings, fmt.Sprintf("%s=%s", name, value))
|
| 388 |
+
}
|
| 389 |
+
youReq.Header.Add("Cookie", strings.Join(cookieStrings, ";"))
|
| 390 |
+
|
| 391 |
+
// 发送请求并获取响应
|
| 392 |
+
client := &http.Client{}
|
| 393 |
+
resp, err := client.Do(youReq)
|
| 394 |
+
if err != nil {
|
| 395 |
+
fmt.Printf("发送请求失败: %v\n", err)
|
| 396 |
+
http.Error(w, err.Error(), http.StatusInternalServerError)
|
| 397 |
+
return
|
| 398 |
+
}
|
| 399 |
+
defer resp.Body.Close()
|
| 400 |
+
|
| 401 |
+
// 打印响应状态码
|
| 402 |
+
fmt.Printf("响应状态码: %d\n", resp.StatusCode)
|
| 403 |
+
|
| 404 |
+
// 如果状态码不是 200,打印响应内容
|
| 405 |
+
if resp.StatusCode != http.StatusOK {
|
| 406 |
+
body, _ := io.ReadAll(resp.Body)
|
| 407 |
+
fmt.Printf("错误响应内容: %s\n", string(body))
|
| 408 |
+
http.Error(w, fmt.Sprintf("API returned status %d", resp.StatusCode), resp.StatusCode)
|
| 409 |
+
return
|
| 410 |
+
}
|
| 411 |
+
|
| 412 |
+
// 根据 OpenAI 请求的 stream 参数选择处理函数
|
| 413 |
+
if !openAIReq.Stream {
|
| 414 |
+
handleNonStreamingResponse(w, youReq) // 处理非流式响应
|
| 415 |
+
return
|
| 416 |
+
}
|
| 417 |
+
|
| 418 |
+
handleStreamingResponse(w, youReq) // 处理流式响应
|
| 419 |
} else {
|
| 420 |
// 构建常规查询参数
|
| 421 |
q := youReq.URL.Query()
|
|
|
|
| 438 |
q.Add("use_nested_youchat_updates", "true")
|
| 439 |
q.Add("chat", string(chatHistoryJSON))
|
| 440 |
youReq.URL.RawQuery = q.Encode()
|
|
|
|
| 441 |
|
| 442 |
+
// 设置 You.com API 请求头
|
| 443 |
+
youReq.Header = http.Header{
|
| 444 |
+
"sec-ch-ua-platform": {"Windows"},
|
| 445 |
+
"Cache-Control": {"no-cache"},
|
| 446 |
+
"sec-ch-ua": {`"Not(A:Brand";v="99", "Microsoft Edge";v="133", "Chromium";v="133"`},
|
| 447 |
+
"sec-ch-ua-bitness": {"64"},
|
| 448 |
+
"sec-ch-ua-model": {""},
|
| 449 |
+
"sec-ch-ua-mobile": {"?0"},
|
| 450 |
+
"sec-ch-ua-arch": {"x86"},
|
| 451 |
+
"sec-ch-ua-full-version": {"133.0.3065.39"},
|
| 452 |
+
"Accept": {"text/event-stream"}, // 重要:接受 SSE 流
|
| 453 |
+
"User-Agent": {"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36 Edg/133.0.0.0"},
|
| 454 |
+
"sec-ch-ua-platform-version": {"19.0.0"},
|
| 455 |
+
"Sec-Fetch-Site": {"same-origin"},
|
| 456 |
+
"Sec-Fetch-Mode": {"cors"},
|
| 457 |
+
"Sec-Fetch-Dest": {"empty"},
|
| 458 |
+
"Host": {"you.com"},
|
| 459 |
+
}
|
| 460 |
|
| 461 |
+
// 设置 You.com API 请求的 Cookie
|
| 462 |
+
cookies := getCookies(dsToken)
|
| 463 |
+
var cookieStrings []string
|
| 464 |
+
for name, value := range cookies {
|
| 465 |
+
cookieStrings = append(cookieStrings, fmt.Sprintf("%s=%s", name, value))
|
| 466 |
+
}
|
| 467 |
+
youReq.Header.Add("Cookie", strings.Join(cookieStrings, ";"))
|
| 468 |
|
| 469 |
+
// 根据 OpenAI 请求的 stream 参数选择处理函数
|
| 470 |
+
if !openAIReq.Stream {
|
| 471 |
+
handleNonStreamingResponse(w, youReq) // 处理非流式响应
|
| 472 |
+
return
|
| 473 |
+
}
|
| 474 |
|
| 475 |
+
handleStreamingResponse(w, youReq) // 处理流式响应
|
| 476 |
+
}
|
| 477 |
}
|
| 478 |
|
| 479 |
// getCookies 根据提供的 DS token 生成所需的 Cookie。
|