Skip to content

Commit

Permalink
Keep track of whether or not the original multipart had an end boundary
Browse files Browse the repository at this point in the history
Fixes issue #218
  • Loading branch information
jstedfast committed Jan 11, 2016
1 parent bac790a commit ea58a8c
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 6 deletions.
13 changes: 13 additions & 0 deletions MimeKit/ContentObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -210,5 +210,18 @@ public Stream Open ()
}

#endregion

/// <summary>
/// Determines if the specified content is null or empty.
/// </summary>
/// <remarks>
/// Determines if the specified content is null or empty.
/// </remarks>
/// <returns><c>true</c> if the content is null or empty; otherwise, <c>false</c>.</returns>
/// <param name="content">The content.</param>
internal static bool IsNullOrEmpty (IContentObject content)
{
return content == null || content.Stream.Length == 0;
}
}
}
2 changes: 1 addition & 1 deletion MimeKit/MimeParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1224,7 +1224,6 @@ unsafe BoundaryType MultipartScanEpilogue (Multipart multipart, byte* inbuf)
{
using (var memory = new MemoryStream ()) {
var found = ScanContent (inbuf, memory, true);

multipart.RawEpilogue = memory.ToArray ();
return found;
}
Expand Down Expand Up @@ -1297,6 +1296,7 @@ unsafe BoundaryType ConstructMultipart (Multipart multipart, byte* inbuf)

if (found == BoundaryType.ImmediateEndBoundary) {
// consume the end boundary and read the epilogue (if there is one)
multipart.WriteEndBoundary = true;
SkipLine (inbuf, false);
PopBoundary ();

Expand Down
39 changes: 34 additions & 5 deletions MimeKit/Multipart.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ public Multipart (string subtype) : base ("multipart", subtype)
{
ContentType.Parameters["boundary"] = GenerateBoundary ();
children = new List<MimeEntity> ();
WriteEndBoundary = true;
}

/// <summary>
Expand Down Expand Up @@ -256,6 +257,7 @@ public string Epilogue {
if (value != null) {
var folded = FoldPreambleOrEpilogue (FormatOptions.Default, value, true);
RawEpilogue = Encoding.UTF8.GetBytes (folded);
WriteEndBoundary = true;
epilogue = null;
} else {
RawEpilogue = null;
Expand All @@ -264,6 +266,17 @@ public string Epilogue {
}
}

/// <summary>
/// Gets or sets whether the end boundary should be written.
/// </summary>
/// <remarks>
/// Gets or sets whether the end boundary should be written.
/// </remarks>
/// <value><c>true</c> if the end boundary should be written; otherwise, <c>false</c>.</value>
internal bool WriteEndBoundary {
get; set;
}

/// <summary>
/// Dispatches to the specific visit method for this MIME entity.
/// </summary>
Expand Down Expand Up @@ -423,38 +436,54 @@ public override void Prepare (EncodingConstraint constraint, int maxLineLength =

if (cancellable != null) {
for (int i = 0; i < children.Count; i++) {
var multi = children[i] as Multipart;
var part = children[i] as MimePart;

cancellable.Write (boundary, 0, boundary.Length - 2, cancellationToken);
cancellable.Write (options.NewLineBytes, 0, options.NewLineBytes.Length, cancellationToken);
children[i].WriteTo (options, stream, false, cancellationToken);

if (part == null || (part.ContentObject != null && part.ContentObject.Stream.Length != 0))
cancellable.Write (options.NewLineBytes, 0, options.NewLineBytes.Length, cancellationToken);
if ((part != null && ContentObject.IsNullOrEmpty (part.ContentObject)) ||
(multi != null && !multi.WriteEndBoundary))
continue;

cancellable.Write (options.NewLineBytes, 0, options.NewLineBytes.Length, cancellationToken);
}

if (!WriteEndBoundary)
return;

cancellable.Write (boundary, 0, boundary.Length, cancellationToken);

if (RawEpilogue == null)
cancellable.Write (options.NewLineBytes, 0, options.NewLineBytes.Length, cancellationToken);
} else {
for (int i = 0; i < children.Count; i++) {
var multi = children[i] as Multipart;
var part = children[i] as MimePart;

cancellationToken.ThrowIfCancellationRequested ();
stream.Write (boundary, 0, boundary.Length - 2);
stream.Write (options.NewLineBytes, 0, options.NewLineBytes.Length);
children[i].WriteTo (options, stream, false, cancellationToken);

if (part == null || (part.ContentObject != null && part.ContentObject.Stream.Length != 0))
stream.Write (options.NewLineBytes, 0, options.NewLineBytes.Length);
if ((part != null && ContentObject.IsNullOrEmpty (part.ContentObject)) ||
(multi != null && !multi.WriteEndBoundary))
continue;

stream.Write (options.NewLineBytes, 0, options.NewLineBytes.Length);
}

if (!WriteEndBoundary)
return;

cancellationToken.ThrowIfCancellationRequested ();
stream.Write (boundary, 0, boundary.Length);

if (RawEpilogue == null)
if (RawEpilogue == null) {
cancellationToken.ThrowIfCancellationRequested ();
stream.Write (options.NewLineBytes, 0, options.NewLineBytes.Length);
}
}

if (RawEpilogue != null && RawEpilogue.Length > 0)
Expand Down

0 comments on commit ea58a8c

Please sign in to comment.