Skip to content
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

Support filename header with UTF-8 encoded special characters #2276

Open
FerdinandStapenhorst opened this issue Dec 20, 2024 · 0 comments
Open

Comments

@FerdinandStapenhorst
Copy link

The current function GetMultipartFileHeader only works for file names with ASCII characters.

private static string GetMultipartFileHeader(HttpFile file)
{
    return string.Format(
        "--{0}{4}Content-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"{4}Content-Type: {3}{4}{4}",
        FORM_BOUNDARY, file.Name, file.FileName, file.ContentType ?? "application/octet-stream", LINE_BREAK);
}

Here an example version also supporting other encoded file names by using the filename* header format defined in RFC 5987 "Character Set and Language Encoding for HTTP Header Field Parameters."

private static string GetMultipartFileHeader(HttpFile file, Encoding encoding = null)
{
    // Default to UTF-8 encoding if none is specified
    encoding ??= Encoding.UTF8;

    // Encode the file name using the specified encoding
    string encodedFileName = EncodeFileName(file.FileName, encoding);

    // Generate an ASCII fallback for older servers
    string asciiFileName = Encoding.ASCII.GetString(Encoding.ASCII.GetBytes(file.FileName))
                             .Replace("?", ""); // Replace unrepresentable characters

    return string.Format(
        "--{0}{5}Content-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"; filename*={3}''{4}{5}Content-Type: {6}{5}{5}",
        FORM_BOUNDARY,                         // Boundary for the multipart form-data
        file.Name,                             // Form parameter name
        asciiFileName,                         // ASCII fallback file name
        encoding.WebName,                      // Character set for filename*
        encodedFileName,                       // Percent-encoded file name
        LINE_BREAK,                            // Line break (e.g., "\r\n")
        file.ContentType ?? "application/octet-stream" // Default Content-Type
    );
}


// Helper function to encode the file name for the specified encoding
private static string EncodeFileName(string fileName, Encoding encoding)
{
    byte[] encodedBytes = encoding.GetBytes(fileName);
    return string.Join("", encodedBytes.Select(b => $"%{b:X2}"));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant