fix: improve SSE scan errors and validate bare Fabric address inputs

## CHANGES
- Send detailed SSE stream scan errors in responses
- Detect token-too-long and return clear buffer-limit message
- Unify streaming and JSON error messaging for scan failures
- Validate bare Fabric address using URL parsing
- Reject bare addresses missing host or hostname
- Disallow path components in bare Fabric addresses
- Trim trailing slash from validated Fabric chat URL
- Add tests covering invalid bare addresses with paths
This commit is contained in:
Kayvan Sylvan 2026-01-17 03:32:07 -08:00
parent 97b6b76dd2
commit e2b63ddc2f
2 changed files with 35 additions and 3 deletions

View file

@ -280,11 +280,16 @@ func (f APIConvert) ollamaChat(c *gin.Context) {
}
if err := scanner.Err(); err != nil {
log.Printf("Error scanning body: %v", err)
errorMsg := fmt.Sprintf("failed to scan SSE response stream: %v", err)
// Check for buffer size exceeded error
if strings.Contains(err.Error(), "token too long") {
errorMsg = "SSE line exceeds 1MB buffer limit - data line too large"
}
if prompt.Stream {
// In streaming mode, send the error in the same streaming format
_ = writeOllamaResponse(c, prompt.Model, "Error: failed to scan response stream", true)
_ = writeOllamaResponse(c, prompt.Model, fmt.Sprintf("Error: %s", errorMsg), true)
} else {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to scan SSE response stream from Fabric server"})
c.JSON(http.StatusInternalServerError, gin.H{"error": errorMsg})
}
return
}
@ -353,7 +358,22 @@ func buildFabricChatURL(addr string) (string, error) {
if strings.HasPrefix(addr, ":") {
return fmt.Sprintf("http://127.0.0.1%s", addr), nil
}
return fmt.Sprintf("http://%s", addr), nil
// Validate bare addresses (without http/https prefix)
parsed, err := url.Parse("http://" + addr)
if err != nil {
return "", fmt.Errorf("invalid address: %w", err)
}
if parsed.Host == "" {
return "", fmt.Errorf("invalid address: missing host")
}
if strings.HasPrefix(parsed.Host, ":") {
return "", fmt.Errorf("invalid address: missing hostname")
}
// Bare addresses should be host[:port] only - reject path components
if parsed.Path != "" && parsed.Path != "/" {
return "", fmt.Errorf("invalid address: path component not allowed in bare address")
}
return strings.TrimRight(parsed.String(), "/"), nil
}
func writeOllamaResponse(c *gin.Context, model string, content string, done bool) error {

View file

@ -71,6 +71,18 @@ func TestBuildFabricChatURL(t *testing.T) {
want: "http://192.168.1.1:3000",
wantErr: false,
},
{
name: "bare address with path - invalid",
addr: "localhost:8080/some/path",
want: "",
wantErr: true,
},
{
name: "bare hostname with path - invalid",
addr: "localhost/api",
want: "",
wantErr: true,
},
}
for _, tt := range tests {