From 9c8d8c7b839f31742c56fbed411d876c19ab6bd6 Mon Sep 17 00:00:00 2001 From: Haruko386 Date: Thu, 2 Jul 2026 16:05:49 +0800 Subject: [PATCH] fix: unable to load pic in chunk result (#16485) ### Summary As title: --- internal/handler/auth.go | 15 ++++++++++----- internal/handler/document.go | 26 ++++++++++++++++++++++---- internal/handler/user.go | 14 +++++++++++++- internal/router/router.go | 2 +- internal/service/document.go | 2 +- 5 files changed, 47 insertions(+), 12 deletions(-) diff --git a/internal/handler/auth.go b/internal/handler/auth.go index cdf5468ece..6ea1dd4156 100644 --- a/internal/handler/auth.go +++ b/internal/handler/auth.go @@ -56,9 +56,9 @@ func NewAuthHandler() *AuthHandler { // A beta token can also be a regular user JWT or API token. Order of // precedence: // -// 1. JWT (regular session) → existing UserService.GetUserByToken -// 2. API token → GetUserByAPIToken -// 3. Beta API token → GetUserByBetaAPIToken +// 1. Beta API token → GetUserByBetaAPIToken +// 2. JWT (regular session) → existing UserService.GetUserByToken +// 3. API token → GetUserByAPIToken // 4. Fall through → 401 // // IMPORTANT: the regular-user branch is NOT gated on a "Bearer " @@ -70,13 +70,18 @@ func NewAuthHandler() *AuthHandler { func (h *AuthHandler) BetaAuthMiddleware() gin.HandlerFunc { return func(c *gin.Context) { auth := c.GetHeader("Authorization") + if auth == "" { + if cookie, err := c.Cookie(oauthAuthCookie); err == nil { + auth = cookie + } + } + if auth == "" { jsonError(c, common.CodeUnauthorized, "Authorization required") c.Abort() return } - // Try regular user session first (handles JWT, Bearer, or - // raw access_token — same dispatch as AuthMiddleware()). + // AUTH_JWT if u, code, err := h.userService.GetUserByToken(auth); err == nil && code == common.CodeSuccess { c.Set("user", u) c.Next() diff --git a/internal/handler/document.go b/internal/handler/document.go index 0740a6b17c..b3401676b1 100644 --- a/internal/handler/document.go +++ b/internal/handler/document.go @@ -17,6 +17,7 @@ package handler import ( + "bytes" "encoding/json" "errors" "fmt" @@ -227,13 +228,30 @@ func (h *DocumentHandler) GetDocumentImage(c *gin.Context) { return } - contentType := mime.TypeByExtension(strings.ToLower(filepath.Ext(imageID))) - if contentType == "" { - contentType = "image/JPEG" - } + contentType := documentImageContentType(imageID, data) c.Data(http.StatusOK, contentType, data) } +func documentImageContentType(imageID string, data []byte) string { + if contentType := mime.TypeByExtension(strings.ToLower(filepath.Ext(imageID))); strings.HasPrefix(contentType, "image/") { + return contentType + } + switch { + case bytes.HasPrefix(data, []byte("\x89PNG\r\n\x1a\n")): + return "image/png" + case len(data) >= 3 && bytes.Equal(data[:3], []byte{0xff, 0xd8, 0xff}): + return "image/jpeg" + case bytes.HasPrefix(data, []byte("GIF87a")), bytes.HasPrefix(data, []byte("GIF89a")): + return "image/gif" + case len(data) >= 12 && bytes.Equal(data[:4], []byte("RIFF")) && bytes.Equal(data[8:12], []byte("WEBP")): + return "image/webp" + case bytes.HasPrefix(data, []byte("BM")): + return "image/bmp" + default: + return "application/octet-stream" + } +} + func (h *DocumentHandler) GetDocumentArtifact(c *gin.Context) { user, code, msg := GetUser(c) if code != common.CodeSuccess { diff --git a/internal/handler/user.go b/internal/handler/user.go index 06208d1502..86a4ffebab 100644 --- a/internal/handler/user.go +++ b/internal/handler/user.go @@ -98,6 +98,7 @@ func (h *UserHandler) Register(c *gin.Context) { } c.Header("Authorization", authToken) + setOAuthAuthCookie(c, authToken) c.Header("Access-Control-Allow-Origin", "*") c.Header("Access-Control-Allow-Methods", "*") c.Header("Access-Control-Allow-Headers", "*") @@ -163,6 +164,7 @@ func (h *UserHandler) Login(c *gin.Context) { // Set Authorization header with signed token c.Header("Authorization", authToken) + setOAuthAuthCookie(c, authToken) // Set CORS headers c.Header("Access-Control-Allow-Origin", "*") c.Header("Access-Control-Allow-Methods", "*") @@ -235,7 +237,7 @@ func (h *UserHandler) LoginByEmail(c *gin.Context) { }) return } - + setOAuthAuthCookie(c, authToken) c.Header("Authorization", authToken) c.Header("Access-Control-Allow-Origin", "*") c.Header("Access-Control-Allow-Methods", "*") @@ -341,6 +343,16 @@ func (h *UserHandler) ListUsers(c *gin.Context) { // @Success 200 {object} map[string]interface{} // @Router /v1/user/logout [post] func (h *UserHandler) Logout(c *gin.Context) { + http.SetCookie(c.Writer, &http.Cookie{ + Name: oauthAuthCookie, + Value: "", + Path: "/", + MaxAge: -1, + HttpOnly: false, + SameSite: http.SameSiteLaxMode, + Secure: c.Request.TLS != nil, + }) + // Same as AuthMiddleware@auth.go token := c.GetHeader("Authorization") if token == "" { diff --git a/internal/router/router.go b/internal/router/router.go index 88d043f06f..a6ede3fb8e 100644 --- a/internal/router/router.go +++ b/internal/router/router.go @@ -208,8 +208,8 @@ func (r *Router) Setup(engine *gin.Engine) { agentbotGroup := apiBetaAuth.Group("/agentbots") RegisterAgentbotRoutes(agentbotGroup, betaMW, r.botHandler) } - apiBetaAuth.GET("/documents/images/:image_id", r.documentHandler.GetDocumentImage) apiBetaAuth.GET("/documents/:id/preview", r.documentHandler.GetDocumentPreview) + apiBetaAuth.GET("/documents/images/:image_id", r.documentHandler.GetDocumentImage) apiBetaAuth.GET("/thumbnails", r.documentHandler.GetThumbnail) // MCP server endpoint — exposes RAGFlow capabilities as MCP tools. diff --git a/internal/service/document.go b/internal/service/document.go index adeb55f8e1..314016e1aa 100644 --- a/internal/service/document.go +++ b/internal/service/document.go @@ -235,7 +235,7 @@ var artifactUnsafeFilenameChars = regexp.MustCompile(`[^\pL\pN_.-]`) // GetDocumentImage retrieves an image object from storage. func (s *DocumentService) GetDocumentImage(imageID string) ([]byte, error) { - parts := strings.Split(imageID, "-") + parts := strings.SplitN(imageID, "-", 2) if len(parts) != 2 || parts[0] == "" || parts[1] == "" { return nil, fmt.Errorf("Image not found.") }