Skip to content

fix: solve proxy shared state pollution for concurrent GenAI style and non-GenAI style requests. #202

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 2, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 33 additions & 21 deletions Demos/Gemma-on-Cloudrun/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@ func main() {
re := regexp.MustCompile(geminiAPIPathRegexPattern)
matches := re.FindStringSubmatch(r.URL.Path)

var (
isCurrentRequestGeminiStyle bool = false
actionForResponse string // Stores action for response modification
)

if len(matches) == 4 {
apiVersion := matches[1]
modelVersion := matches[2]
Expand All @@ -119,6 +124,9 @@ func main() {
log.Printf("Model Version: %s\n", modelVersion)
log.Printf("Real Path: %s\n", action)

isCurrentRequestGeminiStyle = true
actionForResponse = action

convertedAPIVersion, convertedAPIVersionOk := geminiToOpenAiAPIVersionhMapping[apiVersion]
convertedAction, convertedActionOk := geminiToOpenAiActionMapping[action]

Expand Down Expand Up @@ -173,29 +181,9 @@ func main() {
log.Printf(">>> Director: Outgoing Content-Type: %s", req.Header.Get("Content-Type"))
}

// --- Modify Response ---
proxy.ModifyResponse = func(resp *http.Response) error {

// Handle non-200 responses - pass them through without modification
if resp.StatusCode != http.StatusOK {
log.Printf("<<< ModifyResponse: Target returned non-200 status (%d). Forwarding original body.", resp.StatusCode)
return nil
}

switch action {
case "generateContent", "generateAnswer":
modifyNonStreamResponse(resp, action)
case "streamGenerateContent":
modifyStreamResponse(resp)
default:
return fmt.Errorf("unexpected action %s", action)
}

return nil
}

} else {
log.Printf("URL path does not match the expected format. No conversion applied.")
isCurrentRequestGeminiStyle = false

apiKey := r.Header.Get("Authorization")
expectedPrefix := "Bearer "
Expand All @@ -217,7 +205,31 @@ func main() {
log.Printf(">>> Director: Proxying request to: %s %s", req.Method, req.URL.String())
log.Printf(">>> Director: Outgoing Host header: %s", req.Host)
}
}

// --- Modify Response ---
proxy.ModifyResponse = func(resp *http.Response) error {
// Handle non-GenAI style requests - pass them through without modification
if !isCurrentRequestGeminiStyle {
return nil
}

// Handle non-200 responses - pass them through without modification
if resp.StatusCode != http.StatusOK {
log.Printf("<<< ModifyResponse: Target returned non-200 status (%d). Forwarding original body.", resp.StatusCode)
return nil
}

switch actionForResponse {
case "generateContent", "generateAnswer":
modifyNonStreamResponse(resp, actionForResponse)
case "streamGenerateContent":
modifyStreamResponse(resp)
default:
return fmt.Errorf("unexpected action %s", actionForResponse)
}

return nil
}

// --- Error Handling for the Proxy ---
Expand Down