From 231ceaf76d757de49c2160e4a298e32addc0ffcf Mon Sep 17 00:00:00 2001 From: "Gyarbij (Chono N)" <49493993+Gyarbij@users.noreply.github.com> Date: Sat, 13 Jul 2024 04:02:10 +0200 Subject: [PATCH 01/11] chore: Refactor HandleToken function to improve readability and handle API key retrieval per updated azure api --- .DS_Store | Bin 0 -> 6148 bytes pkg/azure/proxy.go | 18 +++++++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..ebcaf6fb1917c6d85a8e5945f52db7eb5bfffe42 GIT binary patch literal 6148 zcmeHK%TB{E5FDo!ZQ;@*7bJf{CH^2S$)OT(pg#b85FrwRK)vVAuORV#oM6_rq9$pt z2+*#y9zSO7cpPP80A{vbp95n6L%LuzVzI|$T)bmZ=ot`=n`46)+~WZ`HXXKh{6+=j z?2eJ3#0rl*wfg+#dAVBV<&xv_a!l!yFK4U)N5~j6LBVp};(l=aeGm5)TNF*MIU{#> z-T^K##|2VcV}Z2Ae(SIc-0^*T;*;=sTI|mjyN74)F>A7-ti>APhO1Ah$rVv{*xsLL zvAaJu)l>mhKo$5?3NUAj4Np93sS2n9sz9xPd><@bFb-IGbe|3u?g~Kcv)dW#^1CQ8 zHeejE^2iaI@u5T?YQh!6_;B{yz>5P`9(_1WxO|wfvI#d7<5uVV*3n^Nk6Nk%sz6hL zo^OsN|EGuV|IHw6sRF9Nzf!>TlSMM)mO^grY)*2mrQg!Ugjad2Ls)UCm|RK4r*voR Yw^AX-0V|K}q3Mr+lR*nr;71ks2J=j01ONa4 literal 0 HcmV?d00001 diff --git a/pkg/azure/proxy.go b/pkg/azure/proxy.go index 7ff9279..4c4160e 100644 --- a/pkg/azure/proxy.go +++ b/pkg/azure/proxy.go @@ -163,17 +163,25 @@ func handleToken(req *http.Request) { } func HandleToken(req *http.Request) { - token := "" - if AzureOpenAIToken != "" { - token = AzureOpenAIToken + var token string + // Check for API Key in the api-key header + if apiKey := req.Header.Get("api-key"); apiKey != "" { + token = apiKey } else if authHeader := req.Header.Get("Authorization"); authHeader != "" { + // If not found, check for Authorization header token = strings.TrimPrefix(authHeader, "Bearer ") - } else if apiKey := os.Getenv("AZURE_OPENAI_API_KEY"); apiKey != "" { - token = apiKey + } else if AzureOpenAIToken != "" { + // If neither is present, use the AzureOpenAIToken if set + token = AzureOpenAIToken + } else if envApiKey := os.Getenv("AZURE_OPENAI_API_KEY"); envApiKey != "" { + // As a last resort, check for API key in environment variable + token = envApiKey } if token != "" { + // Set the api-key header with the found token req.Header.Set("api-key", token) + // Remove the Authorization header to avoid conflicts req.Header.Del("Authorization") } } From 2047e41c16c8c7e7266a43ddafed6dc67a9b1247 Mon Sep 17 00:00:00 2001 From: "Gyarbij (Chono N)" <49493993+Gyarbij@users.noreply.github.com> Date: Sat, 13 Jul 2024 04:08:45 +0200 Subject: [PATCH 02/11] chore: Refactor HandleToken function to improve readability and handle API key retrieval per updated Azure API --- pkg/azure/proxy.go | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/pkg/azure/proxy.go b/pkg/azure/proxy.go index 4c4160e..9e9618b 100644 --- a/pkg/azure/proxy.go +++ b/pkg/azure/proxy.go @@ -152,18 +152,12 @@ func getModelFromRequest(req *http.Request) string { } func handleToken(req *http.Request) { - token := "" - if AzureOpenAIToken != "" { - token = AzureOpenAIToken - } else { - token = strings.ReplaceAll(req.Header.Get("Authorization"), "Bearer ", "") - } - req.Header.Set("api-key", token) - req.Header.Del("Authorization") + HandleToken(req) } func HandleToken(req *http.Request) { var token string + // Check for API Key in the api-key header if apiKey := req.Header.Get("api-key"); apiKey != "" { token = apiKey @@ -183,6 +177,8 @@ func HandleToken(req *http.Request) { req.Header.Set("api-key", token) // Remove the Authorization header to avoid conflicts req.Header.Del("Authorization") + } else { + log.Println("Warning: No authentication token found") } } From 54603c48796021882ce23c180542f30ffb99b854 Mon Sep 17 00:00:00 2001 From: "Gyarbij (Chono N)" <49493993+Gyarbij@users.noreply.github.com> Date: Sat, 13 Jul 2024 04:39:22 +0200 Subject: [PATCH 03/11] mod response func --- pkg/azure/proxy.go | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/pkg/azure/proxy.go b/pkg/azure/proxy.go index 9e9618b..861605c 100644 --- a/pkg/azure/proxy.go +++ b/pkg/azure/proxy.go @@ -182,10 +182,45 @@ func HandleToken(req *http.Request) { } } +func makeDirector(remote *url.URL) func(*http.Request) { + return func(req *http.Request) { + // Get model and map it to deployment + model := getModelFromRequest(req) + deployment := GetDeploymentByModel(model) + + // Handle token + HandleToken(req) + + // Set the Host, Scheme, Path, and RawPath of the request + originURL := req.URL.String() + req.Host = remote.Host + req.URL.Scheme = remote.Scheme + req.URL.Host = remote.Host + + // Handle different endpoints + switch { + case strings.HasPrefix(req.URL.Path, "/v1/chat/completions"): + req.URL.Path = path.Join("/openai/deployments", deployment, "chat/completions") + // ... (other cases remain the same) + } + + req.URL.RawPath = req.URL.EscapedPath() + + // Add the api-version query parameter + query := req.URL.Query() + query.Add("api-version", AzureOpenAIAPIVersion) + req.URL.RawQuery = query.Encode() + + log.Printf("Proxying request [%s] %s -> %s", model, originURL, req.URL.String()) + log.Printf("Request Headers: %v", req.Header) + } +} + func modifyResponse(res *http.Response) error { - // Handle rate limiting headers - if res.StatusCode == http.StatusTooManyRequests { - log.Printf("Rate limit exceeded: %s", res.Header.Get("Retry-After")) + if res.StatusCode >= 400 { + body, _ := ioutil.ReadAll(res.Body) + log.Printf("Azure API Error Response: Status: %d, Body: %s", res.StatusCode, string(body)) + res.Body = ioutil.NopCloser(bytes.NewBuffer(body)) } // Handle streaming responses From 3dd02416cde5069a4ab864e90aca3e73da358c55 Mon Sep 17 00:00:00 2001 From: "Gyarbij (Chono N)" <49493993+Gyarbij@users.noreply.github.com> Date: Sat, 13 Jul 2024 04:49:45 +0200 Subject: [PATCH 04/11] fix makeDirector dupe --- pkg/azure/proxy.go | 84 ++++++++++++++++++---------------------------- 1 file changed, 32 insertions(+), 52 deletions(-) diff --git a/pkg/azure/proxy.go b/pkg/azure/proxy.go index 861605c..0190176 100644 --- a/pkg/azure/proxy.go +++ b/pkg/azure/proxy.go @@ -2,7 +2,6 @@ package azure import ( "bytes" - "fmt" "io/ioutil" "log" "net/http" @@ -92,56 +91,6 @@ func NewOpenAIReverseProxy() *httputil.ReverseProxy { } } -func makeDirector(remote *url.URL) func(*http.Request) { - return func(req *http.Request) { - // Get model and map it to deployment - model := getModelFromRequest(req) - deployment := GetDeploymentByModel(model) - - // Handle token - handleToken(req) - - // Set the Host, Scheme, Path, and RawPath of the request - originURL := req.URL.String() - req.Host = remote.Host - req.URL.Scheme = remote.Scheme - req.URL.Host = remote.Host - - // Handle different endpoints - switch { - case strings.HasPrefix(req.URL.Path, "/v1/chat/completions"): - req.URL.Path = path.Join(fmt.Sprintf("/openai/deployments/%s", deployment), "chat/completions") - case strings.HasPrefix(req.URL.Path, "/v1/completions"): - req.URL.Path = path.Join(fmt.Sprintf("/openai/deployments/%s", deployment), "completions") - case strings.HasPrefix(req.URL.Path, "/v1/embeddings"): - req.URL.Path = path.Join(fmt.Sprintf("/openai/deployments/%s", deployment), "embeddings") - case strings.HasPrefix(req.URL.Path, "/v1/images/generations"): - req.URL.Path = path.Join(fmt.Sprintf("/openai/deployments/%s", deployment), "images/generations") - case strings.HasPrefix(req.URL.Path, "/v1/fine_tunes"): - req.URL.Path = path.Join(fmt.Sprintf("/openai/deployments/%s", deployment), "fine-tunes") - case strings.HasPrefix(req.URL.Path, "/v1/files"): - req.URL.Path = path.Join(fmt.Sprintf("/openai/deployments/%s", deployment), "files") - case strings.HasPrefix(req.URL.Path, "/v1/audio/speech"): - req.URL.Path = path.Join(fmt.Sprintf("/openai/deployments/%s", deployment), "audio/speech") - case strings.HasPrefix(req.URL.Path, "/v1/audio/transcriptions"): - req.URL.Path = path.Join(fmt.Sprintf("/openai/deployments/%s", deployment), "transcriptions") - case strings.HasPrefix(req.URL.Path, "/v1/audio/translations"): - req.URL.Path = path.Join(fmt.Sprintf("/openai/deployments/%s", deployment), "translations") - default: - req.URL.Path = path.Join(fmt.Sprintf("/openai/deployments/%s", deployment), strings.TrimPrefix(req.URL.Path, "/v1/")) - } - - req.URL.RawPath = req.URL.EscapedPath() - - // Add the api-version query parameter - query := req.URL.Query() - query.Add("api-version", AzureOpenAIAPIVersion) - req.URL.RawQuery = query.Encode() - - log.Printf("proxying request [%s] %s -> %s", model, originURL, req.URL.String()) - } -} - func getModelFromRequest(req *http.Request) string { if req.Body == nil { return "" @@ -201,7 +150,24 @@ func makeDirector(remote *url.URL) func(*http.Request) { switch { case strings.HasPrefix(req.URL.Path, "/v1/chat/completions"): req.URL.Path = path.Join("/openai/deployments", deployment, "chat/completions") - // ... (other cases remain the same) + case strings.HasPrefix(req.URL.Path, "/v1/completions"): + req.URL.Path = path.Join("/openai/deployments", deployment, "completions") + case strings.HasPrefix(req.URL.Path, "/v1/embeddings"): + req.URL.Path = path.Join("/openai/deployments", deployment, "embeddings") + case strings.HasPrefix(req.URL.Path, "/v1/images/generations"): + req.URL.Path = path.Join("/openai/deployments", deployment, "images/generations") + case strings.HasPrefix(req.URL.Path, "/v1/fine_tunes"): + req.URL.Path = path.Join("/openai/deployments", deployment, "fine-tunes") + case strings.HasPrefix(req.URL.Path, "/v1/files"): + req.URL.Path = path.Join("/openai/deployments", deployment, "files") + case strings.HasPrefix(req.URL.Path, "/v1/audio/speech"): + req.URL.Path = path.Join("/openai/deployments", deployment, "audio/speech") + case strings.HasPrefix(req.URL.Path, "/v1/audio/transcriptions"): + req.URL.Path = path.Join("/openai/deployments", deployment, "transcriptions") + case strings.HasPrefix(req.URL.Path, "/v1/audio/translations"): + req.URL.Path = path.Join("/openai/deployments", deployment, "translations") + default: + req.URL.Path = path.Join("/openai/deployments", deployment, strings.TrimPrefix(req.URL.Path, "/v1/")) } req.URL.RawPath = req.URL.EscapedPath() @@ -231,6 +197,20 @@ func modifyResponse(res *http.Response) error { return nil } +func modifyResponse(res *http.Response) error { + // Handle rate limiting headers + if res.StatusCode == http.StatusTooManyRequests { + log.Printf("Rate limit exceeded: %s", res.Header.Get("Retry-After")) + } + + // Handle streaming responses + if res.Header.Get("Content-Type") == "text/event-stream" { + res.Header.Set("X-Accel-Buffering", "no") + } + + return nil +} + func GetDeploymentByModel(model string) string { if v, ok := AzureOpenAIModelMapper[model]; ok { return v From 46bb3b1d2c189e2fbd46c808576c4a3e73b14b4c Mon Sep 17 00:00:00 2001 From: "Gyarbij (Chono N)" <49493993+Gyarbij@users.noreply.github.com> Date: Sat, 13 Jul 2024 04:56:31 +0200 Subject: [PATCH 05/11] remove modify response duplicate --- pkg/azure/proxy.go | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/pkg/azure/proxy.go b/pkg/azure/proxy.go index 0190176..b3dedbc 100644 --- a/pkg/azure/proxy.go +++ b/pkg/azure/proxy.go @@ -197,20 +197,6 @@ func modifyResponse(res *http.Response) error { return nil } -func modifyResponse(res *http.Response) error { - // Handle rate limiting headers - if res.StatusCode == http.StatusTooManyRequests { - log.Printf("Rate limit exceeded: %s", res.Header.Get("Retry-After")) - } - - // Handle streaming responses - if res.Header.Get("Content-Type") == "text/event-stream" { - res.Header.Set("X-Accel-Buffering", "no") - } - - return nil -} - func GetDeploymentByModel(model string) string { if v, ok := AzureOpenAIModelMapper[model]; ok { return v From bbc1859e30c9db9a9633561b15244a2988527f64 Mon Sep 17 00:00:00 2001 From: "Gyarbij (Chono N)" <49493993+Gyarbij@users.noreply.github.com> Date: Sat, 13 Jul 2024 05:05:37 +0200 Subject: [PATCH 06/11] chore: Update Azure OpenAI API version to "2024-06-01" --- pkg/azure/proxy.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/azure/proxy.go b/pkg/azure/proxy.go index b3dedbc..961cd0a 100644 --- a/pkg/azure/proxy.go +++ b/pkg/azure/proxy.go @@ -17,7 +17,7 @@ import ( var ( AzureOpenAIToken = "" - AzureOpenAIAPIVersion = "2024-05-01-preview" + AzureOpenAIAPIVersion = "2024-06-01" AzureOpenAIEndpoint = "" AzureOpenAIModelMapper = map[string]string{ "gpt-3.5-turbo": "gpt-35-turbo", From ed9167bbb9cfd23e840bc6207c986b59bbf8e06e Mon Sep 17 00:00:00 2001 From: "Gyarbij (Chono N)" <49493993+Gyarbij@users.noreply.github.com> Date: Sat, 13 Jul 2024 05:13:55 +0200 Subject: [PATCH 07/11] chore: Update makeDirector function to handle new endpoint structure and add logging for new parameters --- pkg/azure/proxy.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/pkg/azure/proxy.go b/pkg/azure/proxy.go index 961cd0a..e0cdbcc 100644 --- a/pkg/azure/proxy.go +++ b/pkg/azure/proxy.go @@ -2,6 +2,7 @@ package azure import ( "bytes" + "encoding/json" "io/ioutil" "log" "net/http" @@ -131,8 +132,10 @@ func HandleToken(req *http.Request) { } } +// Update the makeDirector function to handle the new endpoint structure func makeDirector(remote *url.URL) func(*http.Request) { return func(req *http.Request) { + // Get model and map it to deployment model := getModelFromRequest(req) deployment := GetDeploymentByModel(model) @@ -172,6 +175,23 @@ func makeDirector(remote *url.URL) func(*http.Request) { req.URL.RawPath = req.URL.EscapedPath() + // Add logging for new parameters + if req.Body != nil { + var requestBody map[string]interface{} + bodyBytes, _ := ioutil.ReadAll(req.Body) + json.Unmarshal(bodyBytes, &requestBody) + + newParams := []string{"completion_config", "presence_penalty", "frequency_penalty", "best_of"} + for _, param := range newParams { + if val, ok := requestBody[param]; ok { + log.Printf("Request includes %s parameter: %v", param, val) + } + } + + // Restore the body to the request + req.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes)) + } + // Add the api-version query parameter query := req.URL.Query() query.Add("api-version", AzureOpenAIAPIVersion) From 031e8c7593a397692c6c4845c5421fc5e5fe37a9 Mon Sep 17 00:00:00 2001 From: "Gyarbij (Chono N)" <49493993+Gyarbij@users.noreply.github.com> Date: Sat, 20 Jul 2024 18:36:09 +0200 Subject: [PATCH 08/11] chore: Update makeDirector function to handle new endpoint structure and add logging for new parameters and convert to 'io' from deprectated 'ioutil' --- .github/workflows/ghcr-docker-publish.yml | 4 +--- pkg/azure/proxy.go | 15 ++++++++------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ghcr-docker-publish.yml b/.github/workflows/ghcr-docker-publish.yml index 9b1e56a..caa7cf2 100644 --- a/.github/workflows/ghcr-docker-publish.yml +++ b/.github/workflows/ghcr-docker-publish.yml @@ -1,10 +1,8 @@ name: Docker on: - schedule: - - cron: '25 8 * * *' push: - branches: [ "main" ] + branches: [ "main", dev ] # Publish semver tags as releases. tags: [ 'v*.*.*', '*.*.*' ] pull_request: diff --git a/pkg/azure/proxy.go b/pkg/azure/proxy.go index e0cdbcc..cecefea 100644 --- a/pkg/azure/proxy.go +++ b/pkg/azure/proxy.go @@ -3,7 +3,7 @@ package azure import ( "bytes" "encoding/json" - "io/ioutil" + "io" "log" "net/http" "net/http/httputil" @@ -31,6 +31,7 @@ var ( "gpt-4-32k": "gpt-4-32k", "gpt-4-32k-0613": "gpt-4-32k-0613", "gpt-4o": "gpt-4o", + "gpt-4o-mini": "gpt-4o-mini", "gpt-4o-2024-05-13": "gpt-4o-2024-05-13", "gpt-4-turbo": "gpt-4-turbo", "gpt-4-vision-preview": "gpt-4-vision-preview", @@ -96,8 +97,8 @@ func getModelFromRequest(req *http.Request) string { if req.Body == nil { return "" } - body, _ := ioutil.ReadAll(req.Body) - req.Body = ioutil.NopCloser(bytes.NewBuffer(body)) + body, _ := io.ReadAll(req.Body) + req.Body = io.NopCloser(bytes.NewBuffer(body)) return gjson.GetBytes(body, "model").String() } @@ -178,7 +179,7 @@ func makeDirector(remote *url.URL) func(*http.Request) { // Add logging for new parameters if req.Body != nil { var requestBody map[string]interface{} - bodyBytes, _ := ioutil.ReadAll(req.Body) + bodyBytes, _ := io.ReadAll(req.Body) json.Unmarshal(bodyBytes, &requestBody) newParams := []string{"completion_config", "presence_penalty", "frequency_penalty", "best_of"} @@ -189,7 +190,7 @@ func makeDirector(remote *url.URL) func(*http.Request) { } // Restore the body to the request - req.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes)) + req.Body = io.NopCloser(bytes.NewBuffer(bodyBytes)) } // Add the api-version query parameter @@ -204,9 +205,9 @@ func makeDirector(remote *url.URL) func(*http.Request) { func modifyResponse(res *http.Response) error { if res.StatusCode >= 400 { - body, _ := ioutil.ReadAll(res.Body) + body, _ := io.ReadAll(res.Body) log.Printf("Azure API Error Response: Status: %d, Body: %s", res.StatusCode, string(body)) - res.Body = ioutil.NopCloser(bytes.NewBuffer(body)) + res.Body = io.NopCloser(bytes.NewBuffer(body)) } // Handle streaming responses From 5d4f404b1dee8d62d8bac0afb838c078d92114a2 Mon Sep 17 00:00:00 2001 From: "Gyarbij (Chono N)" <49493993+Gyarbij@users.noreply.github.com> Date: Sat, 20 Jul 2024 18:57:28 +0200 Subject: [PATCH 09/11] Created helper functions maskString, maskURL, and logSafeHeaders to handle sensitive data: maskString masks most of a string, showing only the first and last two characters. maskURL masks query parameters in URLs. logSafeHeaders masks sensitive header values like "Authorization" and "api-key". Updated the logging statements in makeDirector: Use maskString for the model name. Use maskURL for the request URL. Use logSafeHeaders for request headers. In HandleToken, replaced the token logging with a simple success message. --- pkg/azure/proxy.go | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/pkg/azure/proxy.go b/pkg/azure/proxy.go index cecefea..5f3d9c8 100644 --- a/pkg/azure/proxy.go +++ b/pkg/azure/proxy.go @@ -3,6 +3,7 @@ package azure import ( "bytes" "encoding/json" + "fmt" "io" "log" "net/http" @@ -102,10 +103,6 @@ func getModelFromRequest(req *http.Request) string { return gjson.GetBytes(body, "model").String() } -func handleToken(req *http.Request) { - HandleToken(req) -} - func HandleToken(req *http.Request) { var token string @@ -128,6 +125,7 @@ func HandleToken(req *http.Request) { req.Header.Set("api-key", token) // Remove the Authorization header to avoid conflicts req.Header.Del("Authorization") + log.Println("API key set successfully") } else { log.Println("Warning: No authentication token found") } @@ -198,9 +196,39 @@ func makeDirector(remote *url.URL) func(*http.Request) { query.Add("api-version", AzureOpenAIAPIVersion) req.URL.RawQuery = query.Encode() - log.Printf("Proxying request [%s] %s -> %s", model, originURL, req.URL.String()) - log.Printf("Request Headers: %v", req.Header) + log.Printf("Proxying request [%s] %s -> %s", maskString(model), originURL, maskURL(req.URL)) + logSafeHeaders(req.Header) + } +} + +// Helper function to mask sensitive parts of a string +func maskString(s string) string { + if len(s) <= 4 { + return strings.Repeat("*", len(s)) + } + return s[:2] + strings.Repeat("*", len(s)-4) + s[len(s)-2:] +} + +// Helper function to mask sensitive parts of a URL +func maskURL(u *url.URL) string { + maskedQuery := u.Query() + for key := range maskedQuery { + maskedQuery.Set(key, "****") + } + return fmt.Sprintf("%s://%s%s?%s", u.Scheme, u.Host, u.Path, maskedQuery.Encode()) +} + +// Helper function to log headers safely +func logSafeHeaders(headers http.Header) { + safeHeaders := make(http.Header) + for key, values := range headers { + if strings.ToLower(key) == "authorization" || strings.ToLower(key) == "api-key" { + safeHeaders[key] = []string{"****"} + } else { + safeHeaders[key] = values + } } + log.Printf("Request Headers: %v", safeHeaders) } func modifyResponse(res *http.Response) error { From a9a3a34fd1baaa84888bbe7c26764c136c74d78c Mon Sep 17 00:00:00 2001 From: "Gyarbij (Chono N)" <49493993+Gyarbij@users.noreply.github.com> Date: Sat, 20 Jul 2024 19:09:50 +0200 Subject: [PATCH 10/11] refactor: Update makeDirector function to handle new endpoint structure and add sanitized logging for new parameters --- pkg/azure/proxy.go | 49 ++++++++++++++-------------------------------- 1 file changed, 15 insertions(+), 34 deletions(-) diff --git a/pkg/azure/proxy.go b/pkg/azure/proxy.go index 5f3d9c8..74f5f06 100644 --- a/pkg/azure/proxy.go +++ b/pkg/azure/proxy.go @@ -3,7 +3,6 @@ package azure import ( "bytes" "encoding/json" - "fmt" "io" "log" "net/http" @@ -103,6 +102,19 @@ func getModelFromRequest(req *http.Request) string { return gjson.GetBytes(body, "model").String() } +// sanitizeHeaders returns a copy of the headers with sensitive information redacted +func sanitizeHeaders(headers http.Header) http.Header { + sanitized := make(http.Header) + for key, values := range headers { + if key == "Authorization" || key == "api-key" { + sanitized[key] = []string{"[REDACTED]"} + } else { + sanitized[key] = values + } + } + return sanitized +} + func HandleToken(req *http.Request) { var token string @@ -125,7 +137,6 @@ func HandleToken(req *http.Request) { req.Header.Set("api-key", token) // Remove the Authorization header to avoid conflicts req.Header.Del("Authorization") - log.Println("API key set successfully") } else { log.Println("Warning: No authentication token found") } @@ -196,39 +207,9 @@ func makeDirector(remote *url.URL) func(*http.Request) { query.Add("api-version", AzureOpenAIAPIVersion) req.URL.RawQuery = query.Encode() - log.Printf("Proxying request [%s] %s -> %s", maskString(model), originURL, maskURL(req.URL)) - logSafeHeaders(req.Header) - } -} - -// Helper function to mask sensitive parts of a string -func maskString(s string) string { - if len(s) <= 4 { - return strings.Repeat("*", len(s)) - } - return s[:2] + strings.Repeat("*", len(s)-4) + s[len(s)-2:] -} - -// Helper function to mask sensitive parts of a URL -func maskURL(u *url.URL) string { - maskedQuery := u.Query() - for key := range maskedQuery { - maskedQuery.Set(key, "****") - } - return fmt.Sprintf("%s://%s%s?%s", u.Scheme, u.Host, u.Path, maskedQuery.Encode()) -} - -// Helper function to log headers safely -func logSafeHeaders(headers http.Header) { - safeHeaders := make(http.Header) - for key, values := range headers { - if strings.ToLower(key) == "authorization" || strings.ToLower(key) == "api-key" { - safeHeaders[key] = []string{"****"} - } else { - safeHeaders[key] = values - } + log.Printf("Proxying request [%s] %s -> %s", model, originURL, req.URL.String()) + log.Printf("Sanitized Request Headers: %v", sanitizeHeaders(req.Header)) } - log.Printf("Request Headers: %v", safeHeaders) } func modifyResponse(res *http.Response) error { From 4178857f2206b0e63e0e37fae58fd9d3583b88d7 Mon Sep 17 00:00:00 2001 From: "Gyarbij (Chono N)" <49493993+Gyarbij@users.noreply.github.com> Date: Sat, 20 Jul 2024 19:15:34 +0200 Subject: [PATCH 11/11] disable header logs --- pkg/azure/proxy.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/azure/proxy.go b/pkg/azure/proxy.go index 74f5f06..7bcbbae 100644 --- a/pkg/azure/proxy.go +++ b/pkg/azure/proxy.go @@ -208,7 +208,7 @@ func makeDirector(remote *url.URL) func(*http.Request) { req.URL.RawQuery = query.Encode() log.Printf("Proxying request [%s] %s -> %s", model, originURL, req.URL.String()) - log.Printf("Sanitized Request Headers: %v", sanitizeHeaders(req.Header)) + // log.Printf("Sanitized Request Headers: %v", sanitizeHeaders(req.Header)) } }