openai_plugin_transport.go 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. package service
  2. import (
  3. "net/http"
  4. )
  5. func (s *OpenAIGatewayService) SetPluginManager(manager *PluginManager) {
  6. s.pluginManager = manager
  7. }
  8. // doOpenAIUpstream 只在 OpenAI OAuth 能力绑定已启用时把真实请求交给插件。
  9. // 插件返回标准 http.Response,响应解析、错误映射、SSE 和计费仍由现有核心链处理。
  10. func (s *OpenAIGatewayService) doOpenAIUpstream(request *http.Request, proxyURL string, account *Account) (*http.Response, error) {
  11. request = WithAccountTrafficRequest(request, account)
  12. return accountTrafficController(s.httpUpstream).DoHTTP(request, func(controlled *http.Request) (*http.Response, error) {
  13. return s.doOpenAIUpstreamWithoutTraffic(controlled, proxyURL, account)
  14. })
  15. }
  16. func (s *OpenAIGatewayService) doOpenAIUpstreamWithoutTraffic(request *http.Request, proxyURL string, account *Account) (*http.Response, error) {
  17. profile, err := resolveMode1TLSProfile(account)
  18. if err != nil {
  19. return nil, err
  20. }
  21. if profile != nil && (s.cfg == nil || s.cfg.Gateway.TLSFingerprint.Enabled) && (s.pluginManager == nil || !s.pluginManager.ShouldRouteOpenAIOAuth(account)) {
  22. return s.httpUpstream.DoWithTLS(WithAccountTrafficRequest(request, account), proxyURL, account.ID, account.Mode1EffectiveConcurrency(), profile)
  23. }
  24. if s.pluginManager != nil {
  25. response, handled, err := s.pluginManager.RoundTripOpenAIOAuth(request.Context(), request, proxyURL, account)
  26. if handled {
  27. return captureIntelligentResponse(request, response), err
  28. }
  29. }
  30. return s.httpUpstream.Do(WithAccountTrafficRequest(request, account), proxyURL, account.ID, account.Mode1EffectiveConcurrency())
  31. }
  32. // doOpenAIAccountTestUpstream 让 OpenAI OAuth 账号测试与真实转发使用同一插件路径。
  33. // API Key 和未命中插件的账号保持各自原有的 HTTPUpstream 行为。
  34. func (s *AccountTestService) doOpenAIAccountTestUpstream(
  35. request *http.Request,
  36. proxyURL string,
  37. account *Account,
  38. useTLSFallback bool,
  39. ) (*http.Response, error) {
  40. request = WithAccountTrafficRequest(request, account)
  41. return accountTrafficController(s.httpUpstream).DoHTTP(request, func(controlled *http.Request) (*http.Response, error) {
  42. return s.doOpenAIAccountTestUpstreamWithoutTraffic(controlled, proxyURL, account, useTLSFallback)
  43. })
  44. }
  45. func (s *AccountTestService) doOpenAIAccountTestUpstreamWithoutTraffic(request *http.Request, proxyURL string, account *Account, useTLSFallback bool) (*http.Response, error) {
  46. profile, err := resolveMode1TLSProfile(account)
  47. if err != nil {
  48. return nil, err
  49. }
  50. if profile != nil && (s.cfg == nil || s.cfg.Gateway.TLSFingerprint.Enabled) && (s.pluginManager == nil || !s.pluginManager.ShouldRouteOpenAIOAuth(account)) {
  51. return s.httpUpstream.DoWithTLS(WithAccountTrafficRequest(request, account), proxyURL, account.ID, account.Mode1EffectiveConcurrency(), profile)
  52. }
  53. if s.pluginManager != nil {
  54. response, handled, err := s.pluginManager.RoundTripOpenAIOAuth(request.Context(), request, proxyURL, account)
  55. if handled {
  56. return captureIntelligentResponse(request, response), err
  57. }
  58. }
  59. if useTLSFallback && !isMode1ProtectionEnabled(account) {
  60. return s.httpUpstream.DoWithTLS(
  61. WithAccountTrafficRequest(request, account),
  62. proxyURL,
  63. account.ID,
  64. account.Concurrency,
  65. s.tlsFPProfileService.ResolveTLSProfile(account),
  66. )
  67. }
  68. return s.httpUpstream.Do(WithAccountTrafficRequest(request, account), proxyURL, account.ID, account.Mode1EffectiveConcurrency())
  69. }