public void FinishedPart() { if (jsonBuffer != null) { ParseJsonBuffer(); } else { curAttachment.Finish(); String md5String = curAttachment.MD5DigestString(); attachmentsByMd5Digest.Put(md5String, curAttachment); curAttachment = null; } }
private void RegisterAttachments() { int numAttachmentsInDoc = 0; IDictionary <string, object> attachments = (IDictionary <string, object>)document.Get ("_attachments"); if (attachments == null) { return; } foreach (string attachmentName in attachments.Keys) { IDictionary <string, object> attachment = (IDictionary <string, object>)attachments .Get(attachmentName); int length = 0; if (attachment.ContainsKey("length")) { length = ((int)attachment.Get("length")); } if (attachment.ContainsKey("encoded_length")) { length = ((int)attachment.Get("encoded_length")); } if (attachment.ContainsKey("follows") && ((bool)attachment.Get("follows")) == true) { // Check that each attachment in the JSON corresponds to an attachment MIME body. // Look up the attachment by either its MIME Content-Disposition header or MD5 digest: string digest = (string)attachment.Get("digest"); BlobStoreWriter writer = attachmentsByName.Get(attachmentName); if (writer != null) { // Identified the MIME body by the filename in its Disposition header: string actualDigest = writer.MD5DigestString(); if (digest != null && !digest.Equals(actualDigest) && !digest.Equals(writer.SHA1DigestString ())) { string errMsg = string.Format("Attachment '%s' has incorrect MD5 digest (%s; should be %s)" , attachmentName, digest, actualDigest); throw new InvalidOperationException(errMsg); } attachment.Put("digest", actualDigest); } else { if (digest != null) { writer = attachmentsByMd5Digest.Get(digest); if (writer == null) { string errMsg = string.Format("Attachment '%s' does not appear in MIME body (%s; should be %s)" , attachmentName); throw new InvalidOperationException(errMsg); } } else { if (attachments.Count == 1 && attachmentsByMd5Digest.Count == 1) { // Else there's only one attachment, so just assume it matches & use it: writer = attachmentsByMd5Digest.Values.GetEnumerator().Next(); attachment.Put("digest", writer.MD5DigestString()); } else { // No digest metatata, no filename in MIME body; give up: string errMsg = string.Format("Attachment '%s' has no digest metadata; cannot identify MIME body" , attachmentName); throw new InvalidOperationException(errMsg); } } } // Check that the length matches: if (writer.GetLength() != length) { string errMsg = string.Format("Attachment '%s' has incorrect length field %d (should be %d)" , attachmentName, length, writer.GetLength()); throw new InvalidOperationException(errMsg); } ++numAttachmentsInDoc; } else { if (attachment.ContainsKey("data") && length > 1000) { string msg = string.Format("Attachment '%s' sent inline (len=%d). Large attachments " + "should be sent in MIME parts for reduced memory overhead.", attachmentName); Log.W(Database.Tag, msg); } } } if (numAttachmentsInDoc < attachmentsByMd5Digest.Count) { string msg = string.Format("More MIME bodies (%d) than attachments (%d) ", attachmentsByMd5Digest .Count, numAttachmentsInDoc); throw new InvalidOperationException(msg); } // hand over the (uninstalled) blobs to the database to remember: database.RememberAttachmentWritersForDigests(attachmentsByMd5Digest); }