Upload File Helper Method Documentation

Overview

The handleMultipartFormData method is a private helper method that parses multipart/form-data encoded HTTP request bodies and extracts uploaded files along with associated metadata. It performs low-level byte array manipulation to parse the multipart structure, validate file types, and save allowed files to the appropriate user directory.


Purpose

This method handles the complex task of parsing multipart form data without relying on external libraries. It extracts file content and metadata (filename, path) from the raw byte array, validates file types against allowed extensions, and delegates file saving to the saveFile() method. It provides Japanese-language success/error messages for user feedback.


Method Signature

private static String handleMultipartFormData(
    byte[] body, 
    String contentType, 
    String user
) throws IOException

Parameters


Return Value

Returns a Japanese-language status message:

Note: The success message indicates file validation passed, but doesn't guarantee the file was saved successfully (that happens after the return).


Core Functionality

This method performs the following key operations:


1. Boundary Extraction


2. Multipart Part Iteration


3. Header and Content Separation

For each part:


4. Part Type Identification

Identifies two types of form parts:


5. File Extension Validation

When a file is found:


6. File Saving


Processing Flow

  1. Extract boundary marker from Content-Type header
  2. Initialize tracking variables (data, allowed, fileName, path, msg)
  3. Loop through body searching for boundaries:
    • Find next boundary marker
    • Check if it's the closing boundary (exit if so)
    • Extract part between current and next boundary
    • Trim trailing newlines from part
    • Log preview of first 200 bytes
    • Split part into headers and content
    • If headers contain filename: extract filename, store file data, validate extension
    • If headers contain name="path": extract path value
    • Move to next boundary
  4. After loop: if data exists and is allowed, call saveFile()
  5. Return success or error message

Allowed File Extensions

The method validates files against three extension sets:

Files with extensions not in any of these lists are rejected (allowed remains false).


Helper Methods

This method relies on several utility methods:


Error Handling


Logging

The method provides extensive console logging:


Security Features


Behavior Notes


Performance Considerations


Limitations


Potential Improvements

flowchart TD A(["Start handleMultipartFormData"]) --> B["Extract boundary from contentType
Split on boundary="] B --> C["Construct boundary bytes:
boundaryBytes = -- + boundary
closingBoundaryBytes = -- + boundary + --"] C --> D["Initialize variables:
msg = Upload error
pos = 0, data = null
allowed = false, fileName, path = empty"] D --> E["Start infinite loop"] E --> F["Find next boundary:
boundaryIndex = indexOf body boundaryBytes pos"] F --> G{"boundaryIndex
== -1?"} G -->|Yes| SAVE["AFTER LOOP"] G -->|No| H{"Is closing
boundary?"} H -->|Yes| SAVE H -->|No| I["Move pos after boundary + CRLF"] I --> J["Find next boundary:
nextBoundary = indexOf body boundaryBytes pos"] J --> K{"nextBoundary
== -1?"} K -->|Yes| SAVE K -->|No| L["Extract part:
part = body pos:nextBoundary"] L --> M["Trim trailing newlines from part"] M --> N["Log first 200 bytes preview"] N --> O["Find header/content separator:
headerEnd = indexOf part CRLF CRLF 0"] O --> P{"headerEnd
== -1?"} P -->|Yes| Q["Log error: Failed to find separator
Continue to next iteration"] P -->|No| R["Split part:
headers = part 0:headerEnd
fileContent = part headerEnd+4:end"] Q --> S["Set pos = nextBoundary"] S --> E R --> T{"Headers contain
filename=?"} T -->|Yes| U["Extract fileName using extractFileName
Log: File name: fileName"] T -->|No| V{"Headers contain
name=path?"} U --> W["Store file data:
data = fileContent"] W --> X["Set msg = Upload succeeded"] X --> Y["Convert fileName to lowercase"] Y --> Z["Initialize allowed = false"] Z --> AA["Create extension list:
TEXT IMAGE VIDEO extensions"] AA --> AB["Loop through extension sets"] AB --> AC["Loop through extensions in set"] AC --> AD{"fileName ends with
extension case-insensitive?"} AD -->|Yes| AE["Set allowed = true
Break inner loop"] AD -->|No| AF["Continue to next extension"] AE --> AG{"allowed
is true?"} AF --> AC AG -->|Yes| AH["Break outer loop"] AG -->|No| AB AH --> S V -->|Yes| AI["Extract path from fileContent:
path = new String fileContent trim
Log: Recived path: path"] V -->|No| S AI --> S SAVE{"data != null
AND allowed == true?"} SAVE -->|Yes| CALL["Call saveFile fileName data path user"] SAVE -->|No| RETURN CALL --> RETURN["Return msg"] RETURN --> ZZ(["End"])