Skip to content

Fix JWT auth error logging consuming entire multipart bodies#5409

Draft
Copilot wants to merge 4 commits intomasterfrom
copilot/fix-jwt-middleware-performance
Draft

Fix JWT auth error logging consuming entire multipart bodies#5409
Copilot wants to merge 4 commits intomasterfrom
copilot/fix-jwt-middleware-performance

Conversation

Copy link
Contributor

Copilot AI commented Feb 7, 2026

JWT authentication failure logging calls httputil.DumpRequest(r, true), which reads and dumps the entire request body. For multipart/form-data file uploads, this causes 5-30 second delays and memory spikes equal to file size.

Changes

  • Modified detailAuthLog: Skip body dump for multipart/form-data requests
  • Added isMultipartFormData: Helper to detect multipart Content-Type
  • Tests: Verify multipart bodies are skipped while JSON bodies are still dumped
func detailAuthLog(r *http.Request, reason string) {
    // Skip dumping request body for multipart/form-data to avoid reading large files
    dumpBody := !isMultipartFormData(r)
    details, _ := httputil.DumpRequest(r, dumpBody)
    logc.Errorf(r.Context(), "authorize failed: %s\n=> %+v", reason, string(details))
}

func isMultipartFormData(r *http.Request) bool {
    contentType := r.Header.Get("Content-Type")
    return strings.Contains(contentType, "multipart/form-data")
}

Behavior: Headers-only logging for multipart, full dump for JSON/form-urlencoded (preserves debugging for non-file requests).

Original prompt

This section details on the original issue you should resolve

<issue_title>Bug Report: JWT Middleware reads entire multipart/form-data causing performance issues with file uploads</issue_title>
<issue_description>## Describe the bug
When using the built-in JWT authentication middleware (jwt: Auth) with file upload endpoints, the middleware attempts to read the entire multipart/form-data request body (including large file contents) to search for the JWT token. This causes severe performance issues: the entire file content is printed to console, validation takes 5-30 seconds, and memory usage spikes to the file size.

To Reproduce

Steps to reproduce the behavior:

  1. The code is

    // core.api
    syntax = "v1"
    
    @server (
        prefix: /api/file
        jwt: Auth  // Using built-in JWT middleware
    )
    service core-api {
        @handler UploadFileHandler
        post /upload (UploadFileRequest) returns (UploadFileResponse)
    }
    
    type UploadFileRequest {
        Hash string `json:"hash,optional"`
        Name string `json:"name,optional"`
        Ext  string `json:"ext,optional"`
        Size int64  `json:"size,optional"`
        Path string `json:"path,optional"`
    }
    
    type UploadFileResponse {
        Identity string `json:"identity"`
    }
    // Handler code
    func UploadFileHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
        return func(w http.ResponseWriter, r *http.Request) {
            file, fileHeader, err := r.FormFile("file")
            if err != nil {
                httpx.ErrorCtx(r.Context(), w, err)
                return
            }
            defer file.Close()
            
            // Process file upload...
        }
    }
    # Upload a large file (e.g., 100MB video) with JWT token in header
    curl -X POST http://localhost:8888/api/file/upload \
      -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
      -F "file=@large_video.mp4"
  2. The error/issue is

    # Console output (example):
    [Thousands of lines of binary file content printed to console]
    ����JFIF��������....[binary data continues]....
    
    # Response time: 15-30 seconds for a 100MB file
    # Memory usage: Spikes to 100MB+ (file size)
    # Expected: < 1 second response time, minimal memory usage
    

Expected behavior

  • JWT middleware should only check for token in HTTP headers (Authorization, X-Token) and query parameters (?token=xxx)
  • JWT middleware should NOT parse form data when Content-Type is multipart/form-data
  • File upload should complete quickly (within seconds, only limited by network speed)
  • Console should remain clean without printing file contents
  • Memory usage should be minimal (streaming file upload, not loading entire file to memory)

Screenshots

Before (with built-in JWT middleware):

Console output:
����JFIF��������C��....[thousands of lines]....
[Binary file content printed to console during JWT validation]

Response time: 15-30 seconds ❌
Memory usage: 100MB+ (file size) ❌

After (with custom middleware that skips form parsing):

Console output:
[Clean, no binary data]

Response time: < 1 second ✅
Memory usage: < 10MB ✅

Environments

  • OS: macOS Sonoma 14.x / Linux (Ubuntu 22.04)
  • go-zero version: v1.6.6 (verified issue exists)
  • goctl version: 1.9.2
  • Go version: go1.20+

More description

Root Cause Analysis

The JWT middleware in go-zero searches for tokens in multiple locations, including form parameters:

// Pseudocode of current implementation (rest/handler/authhandler.go)
func (h *AuthorizeHandler) Handle(next http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        // 1. Check Authorization header ✅
        token := r.Header.Get("Authorization")
        
        // 2. Check query parameter ✅
        if token == "" {
            token = r.URL.Query().Get("token")
        }
        
        // 3. Check form parameter ❌ THIS IS THE PROBLEM
        if token == "" {
            token = r.FormValue("token")  // <-- Reads entire multipart/form-data!
        }
        
        // Validate token...
    }
}

The Problem: r.FormValue("token") internally calls r.ParseMultipartForm(), which parses the entire multipart/form-data request body, including all file uploads (potentially hundreds of MBs), just to check if there's a token field in the form.

Impact

This bug makes it impractical to use go-zero's JWT middleware with file upload endpoints in production:

  • ❌ Large file uploads (videos, archives, datasets) become extremely slow
  • ❌ High memory usage causes OOM in containerized environments
  • ❌ Console pollution makes debugging impossible
  • ❌ Poor user experience (30+ second upload times)
  • ❌ Cannot handle concurrent file uploads

Suggested Solutions

Option 1: Skip Form Parsing for multipart/form-data (Recommended)
...


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 3 commits February 7, 2026 09:04
Co-authored-by: kevwan <1918356+kevwan@users.noreply.github.com>
Co-authored-by: kevwan <1918356+kevwan@users.noreply.github.com>
…quests

Co-authored-by: kevwan <1918356+kevwan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix performance issues in JWT middleware for file uploads Fix JWT auth error logging consuming entire multipart bodies Feb 7, 2026
Copilot AI requested a review from kevwan February 7, 2026 09:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug Report: JWT Middleware reads entire multipart/form-data causing performance issues with file uploads

2 participants