4

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:[email protected]" /></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: <[email protected]> 5BC ... lots of data here removed for brevity... 15 ----MIME_boundary-- 0 
2
  • could you share how the request looks like over the wire? probably from fiddler? Commented Aug 26, 2014 at 15:22
  • Added request from WireShark in the original post. Commented Aug 26, 2014 at 15:31

1 Answer 1

2

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(); } } 
Sign up to request clarification or add additional context in comments.

1 Comment

Can you show a code example please? I have the same problem

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.