Exemplo n.º 1
0
        /// <summary>
        /// Parses headers from message or mime entry.
        /// </summary>
        /// <param name="entryStrm">Stream from where to read headers.</param>
        /// <returns>Returns header lines.</returns>
        public static string ParseHeaders(Stream entryStrm)
        {
            /* Rfc 2822 3.1.  GENERAL DESCRIPTION
             *      A message consists of header fields and, optionally, a body.
             *      The  body  is simply a sequence of lines containing ASCII charac-
             *      ters.  It is separated from the headers by a null line  (i.e.,  a
             *      line with nothing preceding the CRLF).
             */

            byte[]           crlf      = new byte[] { (byte)'\r', (byte)'\n' };
            MemoryStream     msHeaders = new MemoryStream();
            StreamLineReader r         = new StreamLineReader(entryStrm);

            byte[] lineData = r.ReadLine();
            while (lineData != null)
            {
                if (lineData.Length == 0)
                {
                    break;
                }

                msHeaders.Write(lineData, 0, lineData.Length);
                msHeaders.Write(crlf, 0, crlf.Length);
                lineData = r.ReadLine();
            }

            return(System.Text.Encoding.Default.GetString(msHeaders.ToArray()));
        }
Exemplo n.º 2
0
        /// <summary>
        /// Parses header fields from stream. Stream position stays where header reading ends.
        /// </summary>
        /// <param name="stream">Stream from where to parse.</param>
        public void Parse(Stream stream)
        {
            /* Rfc 2822 2.2 Header Fields
             *      Header fields are lines composed of a field name, followed by a colon
             *      (":"), followed by a field body, and terminated by CRLF.  A field
             *      name MUST be composed of printable US-ASCII characters (i.e.,
             *      characters that have values between 33 and 126, inclusive), except
             *      colon.  A field body may be composed of any US-ASCII characters,
             *      except for CR and LF.  However, a field body may contain CRLF when
             *      used in header "folding" and  "unfolding" as described in section
             *      2.2.3.  All field bodies MUST conform to the syntax described in
             *      sections 3 and 4 of this standard.
             *
             * Rfc 2822 2.2.3 Long Header Fields
             *      The process of moving from this folded multiple-line representation
             *      of a header field to its single line representation is called
             *      "unfolding". Unfolding is accomplished by simply removing any CRLF
             *      that is immediately followed by WSP.  Each header field should be
             *      treated in its unfolded form for further syntactic and semantic
             *      evaluation.
             *
             *      Example:
             *              Subject: aaaaa<CRLF>
             *              <TAB or SP>aaaaa<CRLF>
             */

            m_pHeaderFields.Clear();

            StreamLineReader r    = new StreamLineReader(stream);
            string           line = r.ReadLineString();

            while (line != null)
            {
                // End of header reached
                if (line == "")
                {
                    break;
                }

                // Store current header line and read next. We need to read 1 header line to ahead,
                // because of multiline header fields.
                string headerField = line;
                line = r.ReadLineString();

                // See if header field is multiline. See comment above.
                while (line != null && (line.StartsWith("\t") || line.StartsWith(" ")))
                {
                    headerField += line;
                    line         = r.ReadLineString();
                }

                string[] name_value = headerField.Split(new char[] { ':' }, 2);
                // There must be header field name and value, otherwise invalid header field
                if (name_value.Length == 2)
                {
                    Add(name_value[0] + ":", Core.CanonicalDecode(name_value[1].Trim()));
                }
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Does period handling.
        /// </summary>
        /// <param name="strm">Input stream.</param>
        /// <param name="add_Remove">If true add periods, else removes periods.</param>
        /// <param name="setStrmPosTo0">If true sets stream position to 0.</param>
        /// <returns></returns>
        public static MemoryStream DoPeriodHandling(Stream strm, bool add_Remove, bool setStrmPosTo0)
        {
            MemoryStream replyData = new MemoryStream();

            byte[] crlf = new byte[] { (byte)'\r', (byte)'\n' };

            if (setStrmPosTo0)
            {
                strm.Position = 0;
            }

            StreamLineReader r = new StreamLineReader(strm);

            byte[] line = r.ReadLine();

            // Loop through all lines
            while (line != null)
            {
                if (line.Length > 0)
                {
                    if (line[0] == (byte)'.')
                    {
                        /* Add period Rfc 2821 4.5.2
                         * -  Before sending a line of mail text, the SMTP client checks the
                         * first character of the line.  If it is a period, one additional
                         * period is inserted at the beginning of the line.
                         */
                        if (add_Remove)
                        {
                            replyData.WriteByte((byte)'.');
                            replyData.Write(line, 0, line.Length);
                        }

                        /* Remove period Rfc 2821 4.5.2
                         * If the first character is a period , the first characteris deleted.
                         */
                        else
                        {
                            replyData.Write(line, 1, line.Length - 1);
                        }
                    }
                    else
                    {
                        replyData.Write(line, 0, line.Length);
                    }
                }

                replyData.Write(crlf, 0, crlf.Length);

                // Read next line
                line = r.ReadLine();
            }

            replyData.Position = 0;

            return(replyData);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Scans invalid CR or LF combination in stream. Returns true if contains invalid CR or LF combination.
        /// </summary>
        /// <param name="strm">Stream which to check.</param>
        /// <returns>Returns true if contains invalid CR or LF combination.</returns>
        public static bool ScanInvalid_CR_or_LF(Stream strm)
        {
            StreamLineReader lineReader = new StreamLineReader(strm);

            byte[] line = lineReader.ReadLine();
            while (line != null)
            {
                foreach (byte b in line)
                {
                    // Contains CR or LF. It cannot conatian such sumbols, because CR must be paired with LF
                    // and we currently reading lines with CRLF combination.
                    if (b == 10 || b == 13)
                    {
                        return(true);
                    }
                }

                line = lineReader.ReadLine();
            }

            return(false);
        }