Exemple #1
0
        /// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="contentType">Content type.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>contentType</b> is null reference.</exception>
        /// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception>
        public MIME_b(MIME_h_ContentType contentType)
        {
            if (contentType == null)
            {
                throw new ArgumentNullException("contentType");
            }

            m_pContentType = contentType;
        }
 /// <summary>
 /// Default constructor.
 /// </summary>
 /// <param name="contentType">Content type.</param>
 /// <exception cref="ArgumentNullException">Is raised when <b>contentType</b> is null reference.</exception>
 /// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception>
 public MIME_b_MultipartAlternative(MIME_h_ContentType contentType) : base(contentType)
 {
     if (
         !string.Equals(contentType.TypeWithSubype,
                        "multipart/alternative",
                        StringComparison.CurrentCultureIgnoreCase))
     {
         throw new ArgumentException(
             "Argument 'contentType.TypeWithSubype' value must be 'multipart/alternative'.");
     }
 }
 /// <summary>
 /// Default constructor.
 /// </summary>
 /// <param name="contentType">Content type.</param>
 /// <exception cref="ArgumentNullException">Is raised when <b>contentType</b> is null reference.</exception>
 /// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception>
 public MIME_b_MultipartRelated(MIME_h_ContentType contentType) : base(contentType)
 {
     if (
         !string.Equals(contentType.TypeWithSubype,
                        "multipart/related",
                        StringComparison.CurrentCultureIgnoreCase))
     {
         throw new ArgumentException(
                   "Argument 'contentType.TypeWithSubype' value must be 'multipart/related'.");
     }
 }
        /// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="contentType">Content type.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>contentType</b> is null reference.</exception>
        /// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception>
        public MIME_b_Multipart(MIME_h_ContentType contentType) : base(contentType)
        {
            if (contentType == null)
            {
                throw new ArgumentNullException("contentType");
            }
            if (string.IsNullOrEmpty(contentType.Param_Boundary))
            {
                throw new ArgumentException(
                          "Argument 'contentType' doesn't contain required boundary parameter.");
            }

            m_pBodyParts = new MIME_EntityCollection();
        }
        /// <summary>
        /// Parses MIME entiry from the specified stream.
        /// </summary>
        /// <param name="stream">Source stream.</param>
        /// <param name="defaultContentType">Default content type.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>stream</b> or <b>defaultContentType</b> is null reference.</exception>
        internal void Parse(SmartStream stream, MIME_h_ContentType defaultContentType)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }
            if (defaultContentType == null)
            {
                throw new ArgumentNullException("defaultContentType");
            }

            m_pHeader.Parse(stream);
            Body = m_pBodyProvider.Parse(this, stream, ContentType ?? defaultContentType);
        }
Exemple #6
0
        /// <summary>
        /// Parses header field from the specified value.
        /// </summary>
        /// <param name="value">Header field value. Header field name must be included. For example: 'Content-Type: text/plain'.</param>
        /// <returns>Returns parsed header field.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>value</b> is null reference.</exception>
        /// <exception cref="ParseException">Is raised when header field parsing errors.</exception>
        public static MIME_h_ContentType Parse(string value)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            MIME_h_ContentType retVal = new MIME_h_ContentType();

            string[] name_value = value.Split(new[] { ':' }, 2);
            if (name_value.Length != 2)
            {
                throw new ParseException("Invalid Content-Type: header field value '" + value + "'.");
            }

            MIME_Reader r    = new MIME_Reader(name_value[1]);
            string      type = r.Token();

            if (type == null)
            {
                throw new ParseException("Invalid Content-Type: header field value '" + value + "'.");
            }
            retVal.m_Type = type;

            if (r.Char(false) != '/')
            {
                throw new ParseException("Invalid Content-Type: header field value '" + value + "'.");
            }

            string subtype = r.Token();

            if (subtype == null)
            {
                //throw new ParseException("Invalid Content-Type: header field value '" + value + "'.");
                subtype = "";
            }
            retVal.m_SubType = subtype;

            retVal.m_pParameters.Parse(r);

            retVal.m_ParseValue = value;
            retVal.m_IsModified = false;

            return(retVal);
        }
Exemple #7
0
        /// <summary>
        /// Parses MIME entity body from specified stream.
        /// </summary>
        /// <param name="owner">Owner MIME entity.</param>
        /// <param name="stream">Stream from where to parse entity body.</param>
        /// <param name="defaultContentType">Default content type.</param>
        /// <returns>Returns parsed body.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>owner</b>, <b>strean</b> or <b>defaultContentType</b> is null reference.</exception>
        /// <exception cref="ParseException">Is raised when header field parsing errors.</exception>
        public MIME_b Parse(MIME_Entity owner, SmartStream stream, MIME_h_ContentType defaultContentType)
        {
            if (owner == null)
            {
                throw new ArgumentNullException("owner");
            }
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }
            if (defaultContentType == null)
            {
                throw new ArgumentNullException("defaultContentType");
            }

            string mediaType           = defaultContentType.TypeWithSubype;
            string mediaTypeWithParams = defaultContentType.ToString().Split(':')[1].TrimStart(' ');

            if (owner.ContentType != null)
            {
                mediaType           = owner.ContentType.TypeWithSubype;
                mediaTypeWithParams = owner.ContentType.ToString().Split(':')[1].TrimStart(' ');
            }

            Type bodyType = null;

            // We have exact body provider for specified mediaType.
            if (m_pBodyTypes.ContainsKey(mediaType))
            {
                bodyType = m_pBodyTypes[mediaType];
            }
            // Use default mediaType.
            else
            {
                // Registered list of mediaTypes are available: http://www.iana.org/assignments/media-types/.

                string mediaRootType = mediaType.Split('/')[0].ToLowerInvariant();
                if (mediaRootType == "application")
                {
                    bodyType = typeof(MIME_b_Application);
                }
                else if (mediaRootType == "audio")
                {
                    bodyType = typeof(MIME_b_Audio);
                }
                else if (mediaRootType == "image")
                {
                    bodyType = typeof(MIME_b_Image);
                }
                else if (mediaRootType == "message")
                {
                    bodyType = typeof(MIME_b_Message);
                }
                else if (mediaRootType == "multipart")
                {
                    bodyType = typeof(MIME_b_Multipart);
                }
                else if (mediaRootType == "text")
                {
                    bodyType = typeof(MIME_b_Text);
                }
                else if (mediaRootType == "video")
                {
                    bodyType = typeof(MIME_b_Video);
                }
                else
                {
                    throw new ParseException("Invalid media-type '" + mediaType + "'.");
                }
            }

            return
                ((MIME_b)
                 bodyType.GetMethod("Parse",
                                    BindingFlags.Static | BindingFlags.NonPublic |
                                    BindingFlags.FlattenHierarchy).Invoke(null,
                                                                          new object[] { owner, mediaTypeWithParams, stream }));
        }
        /// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="contentType">Content type.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>contentType</b> is null reference.</exception>
        /// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception>
        public MIME_b_Multipart(MIME_h_ContentType contentType) : base(contentType)
        {
            if (contentType == null)
            {
                throw new ArgumentNullException("contentType");
            }
            if (string.IsNullOrEmpty(contentType.Param_Boundary))
            {
                throw new ArgumentException(
                    "Argument 'contentType' doesn't contain required boundary parameter.");
            }

            m_pBodyParts = new MIME_EntityCollection();
        }
        /// <summary>
        /// Parses MIME header from the specified stream.
        /// </summary>
        /// <param name="stream">MIME header stream.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>stream</b> is null.</exception>
        public void Parse(SmartStream stream)
        {
            //TODO: ���� ��������� �������! �������� ����! �� ��� ���� �������� � utf8 �����

            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            var headers          = new List <KeyValuePair <string, byte[]> >();
            var currentMemStream = new MemoryStream();

            SmartStream.ReadLineAsyncOP readLineOP = new SmartStream.ReadLineAsyncOP(new byte[Workaround.Definitions.MaxStreamLineLength],
                                                                                     SizeExceededAction.
                                                                                     ThrowException);
            while (true)
            {
                stream.ReadLine(readLineOP, false);
                if (readLineOP.Error != null)
                {
                    throw readLineOP.Error;
                }
                // We reached end of stream.
                if (readLineOP.BytesInBuffer == 0)
                {
                    if (currentMemStream.Length > 0)
                    {
                        AddToBinaryDict(headers, currentMemStream);
                    }
                    m_IsModified = false;

                    break;
                }
                // We got blank header terminator line.
                if (readLineOP.LineBytesInBuffer == 0)
                {
                    if (currentMemStream.Length > 0)
                    {
                        AddToBinaryDict(headers, currentMemStream);
                    }
                    m_IsModified = false;

                    break;
                }

                string line       = Encoding.UTF8.GetString(readLineOP.Buffer, 0, readLineOP.BytesInBuffer);
                var    realBuffer = new List <byte>();

                if ((line.StartsWith("From: \"") || line.StartsWith("To: \"")) && !line.EndsWith(">\r\n"))
                {
                    var tmpArr = new byte[readLineOP.BytesInBuffer];
                    Array.Copy(readLineOP.Buffer, 0, tmpArr, 0, readLineOP.BytesInBuffer);
                    realBuffer.AddRange(tmpArr);
                    do
                    {
                        stream.ReadLine(readLineOP, false);

                        if (readLineOP.LineBytesInBuffer == 0)
                        {
                            break;
                        }

                        line = Encoding.UTF8.GetString(readLineOP.Buffer, 0, readLineOP.BytesInBuffer);

                        tmpArr = new byte[readLineOP.BytesInBuffer];
                        Array.Copy(readLineOP.Buffer, 0, tmpArr, 0, readLineOP.BytesInBuffer);
                        realBuffer.AddRange(tmpArr);
                    } while (!line.EndsWith(">\r\n"));

                    if (realBuffer.Count > 0)
                    {
                        line = Encoding.UTF8.GetString(realBuffer.ToArray());
                    }
                }


                // New header field starts.
                if (currentMemStream.Length == 0)
                {
                    currentMemStream.Write(readLineOP.Buffer, 0, readLineOP.BytesInBuffer);
                }
                // Header field continues.
                else if (char.IsWhiteSpace(line[0]))
                {
                    currentMemStream.Write(readLineOP.Buffer, 0, readLineOP.BytesInBuffer);
                }
                // Current header field closed, new starts.
                else
                {
                    AddToBinaryDict(headers, currentMemStream);

                    currentMemStream = new MemoryStream();
                    if (realBuffer.Count > 0)
                    {
                        currentMemStream.Write(realBuffer.ToArray(), 0, realBuffer.Count);
                    }
                    else
                    {
                        currentMemStream.Write(readLineOP.Buffer, 0, readLineOP.BytesInBuffer);
                    }
                }
            }
            //Process dictionary
            //Find content type
            var contentTypeHeader =
                headers
                .Where(x => x.Value != null)
                .Where(x => "content-type".Equals(x.Key, StringComparison.OrdinalIgnoreCase))
                .Select(x => Encoding.UTF8.GetString(x.Value))
                .SingleOrDefault();
            var encoding = Encoding.UTF8;

            if (contentTypeHeader != null)
            {
                var mime = MIME_h_ContentType.Parse(contentTypeHeader);
                if (!string.IsNullOrEmpty(mime.Param_Charset))
                {
                    encoding = EncodingTools.GetEncodingByCodepageName(mime.Param_Charset) ?? Encoding.UTF8;
                }
                else
                {
                    //Join headers
                    var subjectRaw =
                        headers
                        .Where(x => x.Value != null)
                        .Where(x => "subject".Equals(x.Key, StringComparison.OrdinalIgnoreCase))
                        .Select(x => x.Value)
                        .SingleOrDefault();
                    //Try to detect hueristic
                    encoding = subjectRaw != null?EncodingTools.DetectInputCodepage(subjectRaw) : Encoding.UTF8;
                }
            }

            foreach (var keyValuePair in headers)
            {
                Add(encoding.GetString(keyValuePair.Value));
            }
        }
        /// <summary>
        /// Parses header field from the specified value.
        /// </summary>
        /// <param name="value">Header field value. Header field name must be included. For example: 'Content-Type: text/plain'.</param>
        /// <returns>Returns parsed header field.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>value</b> is null reference.</exception>
        /// <exception cref="ParseException">Is raised when header field parsing errors.</exception>
        public static MIME_h_ContentType Parse(string value)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }

            MIME_h_ContentType retVal = new MIME_h_ContentType();

            string[] name_value = value.Split(new[] {':'}, 2);
            if (name_value.Length != 2)
            {
                throw new ParseException("Invalid Content-Type: header field value '" + value + "'.");
            }

            MIME_Reader r = new MIME_Reader(name_value[1]);
            string type = r.Token();
            if (type == null)
            {
                throw new ParseException("Invalid Content-Type: header field value '" + value + "'.");
            }
            retVal.m_Type = type;

            if (r.Char(false) != '/')
            {
                throw new ParseException("Invalid Content-Type: header field value '" + value + "'.");
            }

            string subtype = r.Token();
            if (subtype == null)
            {
                //throw new ParseException("Invalid Content-Type: header field value '" + value + "'.");
                subtype = "";
            }
            retVal.m_SubType = subtype;

            retVal.m_pParameters.Parse(r);

            retVal.m_ParseValue = value;
            retVal.m_IsModified = false;

            return retVal;
        }
        /// <summary>
        /// Parses MIME entiry from the specified stream.
        /// </summary>
        /// <param name="stream">Source stream.</param>
        /// <param name="defaultContentType">Default content type.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>stream</b> or <b>defaultContentType</b> is null reference.</exception>
        internal void Parse(SmartStream stream, MIME_h_ContentType defaultContentType)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }
            if (defaultContentType == null)
            {
                throw new ArgumentNullException("defaultContentType");
            }

            m_pHeader.Parse(stream);
            Body = m_pBodyProvider.Parse(this, stream, ContentType??defaultContentType);
        }
        /// <summary>
        /// Parses MIME entity body from specified stream.
        /// </summary>
        /// <param name="owner">Owner MIME entity.</param>
        /// <param name="stream">Stream from where to parse entity body.</param>
        /// <param name="defaultContentType">Default content type.</param>
        /// <returns>Returns parsed body.</returns>
        /// <exception cref="ArgumentNullException">Is raised when <b>owner</b>, <b>strean</b> or <b>defaultContentType</b> is null reference.</exception>
        /// <exception cref="ParseException">Is raised when header field parsing errors.</exception>
        public MIME_b Parse(MIME_Entity owner, SmartStream stream, MIME_h_ContentType defaultContentType)
        {
            if (owner == null)
            {
                throw new ArgumentNullException("owner");
            }
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }
            if (defaultContentType == null)
            {
                throw new ArgumentNullException("defaultContentType");
            }

            string mediaType = defaultContentType.TypeWithSubype;
            string mediaTypeWithParams = defaultContentType.ToString().Split(':')[1].TrimStart(' ');
            if (owner.ContentType != null)
            {
                mediaType = owner.ContentType.TypeWithSubype;
                mediaTypeWithParams = owner.ContentType.ToString().Split(':')[1].TrimStart(' ');
            }

            Type bodyType = null;

            // We have exact body provider for specified mediaType.
            if (m_pBodyTypes.ContainsKey(mediaType))
            {
                bodyType = m_pBodyTypes[mediaType];
            }
                // Use default mediaType.
            else
            {
                // Registered list of mediaTypes are available: http://www.iana.org/assignments/media-types/.

                string mediaRootType = mediaType.Split('/')[0].ToLowerInvariant();
                if (mediaRootType == "application")
                {
                    bodyType = typeof (MIME_b_Application);
                }
                else if (mediaRootType == "audio")
                {
                    bodyType = typeof (MIME_b_Audio);
                }
                else if (mediaRootType == "image")
                {
                    bodyType = typeof (MIME_b_Image);
                }
                else if (mediaRootType == "message")
                {
                    bodyType = typeof (MIME_b_Message);
                }
                else if (mediaRootType == "multipart")
                {
                    bodyType = typeof (MIME_b_Multipart);
                }
                else if (mediaRootType == "text")
                {
                    bodyType = typeof (MIME_b_Text);
                }
                else if (mediaRootType == "video")
                {
                    bodyType = typeof (MIME_b_Video);
                }
                else
                {
                    throw new ParseException("Invalid media-type '" + mediaType + "'.");
                }
            }

            return
                (MIME_b)
                bodyType.GetMethod("Parse",
                                   BindingFlags.Static | BindingFlags.NonPublic |
                                   BindingFlags.FlattenHierarchy).Invoke(null,
                                                                         new object[] { owner, mediaTypeWithParams, stream });
        }