上传和接收使用ASP.NET HTTP压缩的大文件时,会出现“mime多部分流意外结束”

ccgok5k5  于 2023-02-17  发布在  .NET
关注(0)|答案(3)|浏览(215)

我很坚韧尝试在ASP.NET中使用HTTP文件上传来发送大文件。
目标是传输大于2GB的内容,压缩以保存带宽。发送3GB的未压缩文件效果很好,所有文件都被接收并正确保存在磁盘上。然而,当我使用压缩(gzip或deflate)时,我从接收API得到以下错误:

Unexpected end of MIME multipart stream. MIME multipart message is not complete.

问题是只有当发送大的请求时(大约300MB是上限),我才会得到例外。上传200MB压缩的效果很好。
下面是上传代码:

using (var client = new HttpClient())
{
    using (var content = new MultipartFormDataContent())
    {
        client.BaseAddress = new Uri(fileServerUrl);
        client.DefaultRequestHeaders.TransferEncodingChunked = true;

        CompressedContent compressedContent = new CompressedContent(content, "gzip");

        var request = new HttpRequestMessage(HttpMethod.Post, "/api/fileupload/")
        {
            Content = compressedContent
        };

        var uploadResponse = client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead).Result;
    }
}

CompressedContent类是WebApiContrib帮助程序集中的类
这里是接收端

// CustomStreamProvider is an implementation to store the files uploaded on the disk
var streamProvider = new CustomStreamProvider(uploadPath);
var res = await Request.Content.ReadAsMultipartAsync(streamProvider);
streamProvider.FileData.Select(file => new FileInfo(file.LocalFileName)).Select(fi => fi.FullName)

你能给我提供一个线索是什么问题吗?为什么它是较大的内容(大于300MB)似乎是压缩不当,而较小的传输刚刚好?

1l5u6lss

1l5u6lss1#

你是不是在分块压缩文件?如果你可以发送未压缩的文件,那么很明显,问题出在你的压缩程序上。使用gzip或Deflate对文件大小有限制。因此你需要分块压缩。

**提示:**调试压缩例程。尝试压缩文件并将其保存到HDD,看看是否可读。

看一下这个article

brgchamk

brgchamk2#

检查content-length是什么,HTTP服务器端例程不希望您发送不同的content-length。您可能正在发送原始文件大小的content-length,在其他地方您正在发送压缩内容,MultiPart解析器希望数据等于content-length。
相反,您发送一个压缩文件,并在服务器端提取它,让压缩和解压缩在应用程序级别不同,而不是插入http协议。
你必须确保两边的压缩/解压缩顺序和内容长度是正确的。据我所知,在HTTP协议中,上传时的压缩并不常见。

pu82cl6c

pu82cl6c3#

尝试按如下所示将名称添加到输入中:

<input type="file" id="fileInput" name="fileInput"/>

或者使用自定义流附加API所需的换行符:

Stream reqStream = Request.Content.ReadAsStreamAsync().Result;
MemoryStream tempStream = new MemoryStream();
reqStream.CopyTo(tempStream);

tempStream.Seek(0, SeekOrigin.End);
StreamWriter writer = new StreamWriter(tempStream);
writer.WriteLine();
writer.Flush();
tempStream.Position = 0;

StreamContent streamContent = new StreamContent(tempStream);
foreach(var header in Request.Content.Headers)
{
    streamContent.Headers.Add(header.Key, header.Value);
}

// Read the form data and return an async task.
await streamContent.ReadAsMultipartAsync(provider);

相关问题