internal static bool TrySplitMimePart(MimePartData<byte[]> part, Encoding encoding, out MultipartMimeData<MimePartData<byte[]>> multipart)
        {
            string boundary;
            if (!part.TryGetMimeBoundary(out boundary))
            {
                multipart = null;
                return false;
            }

            multipart = new MultipartMimeData<MimePartData<byte[]>>();
            multipart.Headers.AddRange(part.Headers);

            var body = part.Body;
            ExceptionUtilities.CheckObjectNotNull(body, "Body cannot be null");

            byte[] boundaryBytes = encoding.GetBytes(boundary);
            byte[] newlineBytes = encoding.GetBytes("\r\n");
            byte[] controlBytes = encoding.GetBytes("--");

            while (EndsWithPattern(body, newlineBytes))
            {
                body = body.Take(body.Length - newlineBytes.Length).ToArray();
            }

            byte[] firstBoundaryBytes = controlBytes.Concat(boundaryBytes).Concat(newlineBytes).ToArray();
            byte[] innerBoundaryBytes = newlineBytes.Concat(controlBytes).Concat(boundaryBytes).Concat(newlineBytes).ToArray();
            byte[] finalBoundaryBytesWithoutFirstNewLine = controlBytes.Concat(boundaryBytes).Concat(controlBytes).ToArray();
            byte[] finalBoundaryBytes = newlineBytes.Concat(finalBoundaryBytesWithoutFirstNewLine).ToArray();

            int firstBoundaryStart = IndexOfPattern(body, firstBoundaryBytes, 0);
            if (firstBoundaryStart == -1)
            {
                // Possibly an empty changeset - empty multipart can be represented as just the end boundary
                int finalBoundaryStart = IndexOfPattern(body, finalBoundaryBytesWithoutFirstNewLine, 0);
                ExceptionUtilities.Assert(finalBoundaryStart == 0, "Malformed");
                ExceptionUtilities.Assert(EndsWithPattern(body, finalBoundaryBytesWithoutFirstNewLine), "Malformed");

                return true;
            }

            ExceptionUtilities.Assert(firstBoundaryStart == 0, "Malformed");
            ExceptionUtilities.Assert(EndsWithPattern(body, finalBoundaryBytes), "Malformed");

            int currentBoundaryEnd = firstBoundaryStart + firstBoundaryBytes.Length;
            while (currentBoundaryEnd < body.Length)
            {
                int nextBoundaryStart = IndexOfPattern(body, innerBoundaryBytes, currentBoundaryEnd);
                int nextBoundaryEnd = nextBoundaryStart + innerBoundaryBytes.Length;
                if (nextBoundaryStart < 0)
                {
                    nextBoundaryStart = IndexOfPattern(body, finalBoundaryBytes, currentBoundaryEnd);
                    nextBoundaryEnd = nextBoundaryStart + finalBoundaryBytes.Length;
                    ExceptionUtilities.Assert(nextBoundaryStart != 0, "Malformed");
                    ExceptionUtilities.Assert(nextBoundaryStart + finalBoundaryBytes.Length == body.Length, "Malformed");
                }

                var fragment = body.Skip(currentBoundaryEnd).Take(nextBoundaryStart - currentBoundaryEnd).ToArray();
                var subPart = new MimePartData<byte[]>();
                if (fragment.Length > 0)
                {
                    PopulateHeadersAndBody(subPart, fragment, encoding);
                    multipart.Add(subPart);
                }

                currentBoundaryEnd = nextBoundaryEnd;
            }

            return true;
        }
Ejemplo n.º 2
0
        internal static bool TrySplitMimePart(MimePartData <byte[]> part, Encoding encoding, out MultipartMimeData <MimePartData <byte[]> > multipart)
        {
            string boundary;

            if (!part.TryGetMimeBoundary(out boundary))
            {
                multipart = null;
                return(false);
            }

            multipart = new MultipartMimeData <MimePartData <byte[]> >();
            multipart.Headers.AddRange(part.Headers);

            var body = part.Body;

            ExceptionUtilities.CheckObjectNotNull(body, "Body cannot be null");

            byte[] boundaryBytes = encoding.GetBytes(boundary);
            byte[] newlineBytes  = encoding.GetBytes("\r\n");
            byte[] controlBytes  = encoding.GetBytes("--");

            while (EndsWithPattern(body, newlineBytes))
            {
                body = body.Take(body.Length - newlineBytes.Length).ToArray();
            }

            byte[] firstBoundaryBytes = controlBytes.Concat(boundaryBytes).Concat(newlineBytes).ToArray();
            byte[] innerBoundaryBytes = newlineBytes.Concat(controlBytes).Concat(boundaryBytes).Concat(newlineBytes).ToArray();
            byte[] finalBoundaryBytesWithoutFirstNewLine = controlBytes.Concat(boundaryBytes).Concat(controlBytes).ToArray();
            byte[] finalBoundaryBytes = newlineBytes.Concat(finalBoundaryBytesWithoutFirstNewLine).ToArray();

            int firstBoundaryStart = IndexOfPattern(body, firstBoundaryBytes, 0);

            if (firstBoundaryStart == -1)
            {
                // Possibly an empty changeset - empty multipart can be represented as just the end boundary
                int finalBoundaryStart = IndexOfPattern(body, finalBoundaryBytesWithoutFirstNewLine, 0);
                ExceptionUtilities.Assert(finalBoundaryStart == 0, "Malformed");
                ExceptionUtilities.Assert(EndsWithPattern(body, finalBoundaryBytesWithoutFirstNewLine), "Malformed");

                return(true);
            }

            ExceptionUtilities.Assert(firstBoundaryStart == 0, "Malformed");
            ExceptionUtilities.Assert(EndsWithPattern(body, finalBoundaryBytes), "Malformed");

            int currentBoundaryEnd = firstBoundaryStart + firstBoundaryBytes.Length;

            while (currentBoundaryEnd < body.Length)
            {
                int nextBoundaryStart = IndexOfPattern(body, innerBoundaryBytes, currentBoundaryEnd);
                int nextBoundaryEnd   = nextBoundaryStart + innerBoundaryBytes.Length;
                if (nextBoundaryStart < 0)
                {
                    nextBoundaryStart = IndexOfPattern(body, finalBoundaryBytes, currentBoundaryEnd);
                    nextBoundaryEnd   = nextBoundaryStart + finalBoundaryBytes.Length;
                    ExceptionUtilities.Assert(nextBoundaryStart != 0, "Malformed");
                    ExceptionUtilities.Assert(nextBoundaryStart + finalBoundaryBytes.Length == body.Length, "Malformed");
                }

                var fragment = body.Skip(currentBoundaryEnd).Take(nextBoundaryStart - currentBoundaryEnd).ToArray();
                var subPart  = new MimePartData <byte[]>();
                if (fragment.Length > 0)
                {
                    PopulateHeadersAndBody(subPart, fragment, encoding);
                    multipart.Add(subPart);
                }

                currentBoundaryEnd = nextBoundaryEnd;
            }

            return(true);
        }