private MultipartWriter GetMultipartWriter(RevisionInternal rev, string boundary) { // Find all the attachments with "follows" instead of a body, and put 'em in a multipart stream. // It's important to scan the _attachments entries in the same order in which they will appear // in the JSON, because CouchDB expects the MIME bodies to appear in that same order var bodyStream = default(MultipartWriter); var attachments = rev.GetAttachments(); foreach (var a in attachments) { var attachment = a.Value.AsDictionary <string, object>(); if (attachment != null && attachment.GetCast <bool>("follows")) { if (bodyStream == null) { // Create the HTTP multipart stream: bodyStream = new MultipartWriter("multipart/related", boundary); bodyStream.SetNextPartHeaders(new Dictionary <string, string> { { "Content-Type", "application/json" } }); // Use canonical JSON encoder so that _attachments keys will be written in the // same order that this for loop is processing the attachments. var json = Manager.GetObjectMapper().WriteValueAsBytes(rev.GetProperties(), true); if (CanSendCompressedRequests) { bodyStream.AddGZippedData(json); } else { bodyStream.AddData(json); } } // Add attachment as another MIME part: var disposition = String.Format("attachment; filename={0}", Misc.QuoteString(a.Key)); var contentType = attachment.GetCast <string>("type"); var contentEncoding = attachment.GetCast <string>("encoding"); bodyStream.SetNextPartHeaders(new NonNullDictionary <string, string> { { "Content-Disposition", disposition }, { "Content-Type", contentType }, { "Content-Encoding", contentEncoding } }); var attachmentObj = default(AttachmentInternal); try { attachmentObj = LocalDatabase.AttachmentForDict(attachment, a.Key); } catch (CouchbaseLiteException) { return(null); } bodyStream.AddStream(attachmentObj.ContentStream, attachmentObj.Length); } } return(bodyStream); }
public void TestMultipartWriterGzipped() { var mp = new MultipartWriter("foo/bar", "BOUNDARY"); var data1 = Enumerable.Repeat((byte)'*', 100); mp.SetNextPartHeaders(new Dictionary <string, string> { { "Content-Type", "star-bellies" } }); mp.AddGZippedData(data1); var output = mp.AllOutput(); // Compression flags & OS type will differ depending on which platform this test is run on // So we need to compare for "almost" equality. In this particular output the compression // flags are on byte 97 and the os type is in byte 98 var expectedOutput = GetType().GetResourceAsStream("MultipartStars.mime").ReadAllBytes(); Assert.AreEqual(expectedOutput.Take(96), output.Take(96)); Assert.AreEqual(expectedOutput.Skip(98), output.Skip(98)); }