简体   繁体   中英

WebApi can't read chunked request

I am writing a web service that will be used to consume some data. The 3rd party that is sending it is using a multipart request and when I look at the request in WireShark, it is chunked.

When I attempt to run the exact same request through fiddler as a standard (unchunked) request, it works fine, however, I can't seem to read the chunked request.

I've tried 2 different approaches. First:

public HttpResponseMessage ImportEstimate(HttpRequestMessage request)
{
    var data = request.Content.ReadAsMultipartAsync().Result;
    IEnumerable<HttpContent> parts = data.Contents;

    return request.CreateResponse(HttpStatusCode.OK, parts.Count());
}

This doesn't return anything. It just sits until the request times out.

The second approach is to do:

public HttpResponseMessage ImportEstimate(HttpRequestMessage request)
{
    IEnumerable<HttpContent> parts = null;
    Task.Factory
        .StartNew(() => parts = Request.Content.ReadAsMultipartAsync().Result.Contents,
            CancellationToken.None,
            TaskCreationOptions.LongRunning, // guarantees separate thread
            TaskScheduler.Default)
        .Wait();

    return request.CreateResponse(HttpStatusCode.OK, parts.Count());
}

Which returns an error:

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

What am I missing here?

Edited: Here is the request from WireShark

POST /myservice/importestimate HTTP/1.1
Host: devapi.mydomain.com
Content-Type: multipart/related; type="application/xop+xml"; start="<start.xml>"; start-info="text/xml"; boundary="--MIME_boundary"
Transfer-Encoding: chunked
SOAPAction: "importestimate"
X-Forwarded-For: xxx.xx.xxx.xxx
Connection: close

94

----MIME_boundary
Content-Type: application/xop+xml; type="text/xml; charset=UTF-8"
Content-Transfer-Encoding: 8bit
Content-Id: <start.xml>


170
<?xml version='1.0' encoding='UTF-8' ?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xop="http://www.w3.org/2004/08/xop/include" ><soap:Body><XDOC><XNET_INFO transactionId="001P92V" ><ATTACHMENTS><ATTACHMENT><xop:Include href="cid:3203@xactware.com" /></ATTACHMENT></ATTACHMENTS></XNET_INFO></XDOC></soap:Body></soap:Envelope>
B3

----MIME_boundary
Content-Type: application/zip
Content-Transfer-Encoding: binary
Content-Disposition: attachment; filename="XDOC.ZIP"
Content-Id: <3203@x.com>


5BC
... lots of data here removed for brevity...
15

----MIME_boundary--
0

After much research, I've figured out the problem!

Apparently my request did not end with a CRLF, which .Net must require to signal the end of the request.

I ended up reading the entire request, adding on a CRLF, and creating my own ReadAsMultipartAsync from MemoryStream. This seems to work.

Edited to add code:

private byte[] ProcessInput(HttpRequestMessage request)
{
    List<HttpContent> parts = new List<HttpContent>();
    byte[] result;
    result = request.Content.ReadAsByteArrayAsync().Result;

    // Stupid chunked requests remove the final CRLF, which makes .Net puke on the request.
    // So add our own CRLF.
    List<byte> crlfTemp = result.ToList();
    crlfTemp.Add(0x0D);
    crlfTemp.Add(0x0A);
    result = crlfTemp.ToArray();

    // Convert stream to MIME
    using (var stream = new MemoryStream(result))
    {
        // note: StreamContent has no Content-Type set by default
        // set a suitable Content-Type for ReadAsMultipartAsync()
        var content = new StreamContent(stream);
        content.Headers.ContentType =
            System.Net.Http.Headers.MediaTypeHeaderValue.Parse(
                "multipart/related; boundary=--MIME_boundary");
        content.Headers.ContentLength = result.Length;
        bool isMPC = content.IsMimeMultipartContent();
        Task.Factory
            .StartNew(() => parts = content.ReadAsMultipartAsync().Result.Contents.ToList(),
                CancellationToken.None,
                TaskCreationOptions.LongRunning, // guarantees separate thread
                TaskScheduler.Default)
            .Wait();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM