Open
Description
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}"));
}