Exemplo n.º 1
0
            /// <summary>
            /// Is called when SMTP server 354 response sending has completed.
            /// </summary>
            /// <param name="op">Asynchronous operation.</param>
            private void Send354ResponseCompleted(SMTP_Session.SendResponseAsyncOP op)
            {
                try{
                    // RFC 5321.4.4 trace info.
                    byte[] recevived = m_pSession.CreateReceivedHeader();
                    m_pSession.m_pMessageStream.Write(recevived,0,recevived.Length);
                    
                    // Create asynchronous read period-terminated opeartion.
                    SmartStream.ReadPeriodTerminatedAsyncOP readPeriodTermOP = new SmartStream.ReadPeriodTerminatedAsyncOP(
                        m_pSession.m_pMessageStream,
                        m_pSession.Server.MaxMessageSize,
                        SizeExceededAction.JunkAndThrowException
                    );
                    // This event is raised only if read period-terminated opeartion completes asynchronously.
                    readPeriodTermOP.Completed += new EventHandler<EventArgs<SmartStream.ReadPeriodTerminatedAsyncOP>>(delegate(object sender,EventArgs<SmartStream.ReadPeriodTerminatedAsyncOP> e){                
                        MessageReadingCompleted(readPeriodTermOP);
                    });
                    // Read period-terminated completed synchronously.
                    if(m_pSession.TcpStream.ReadPeriodTerminated(readPeriodTermOP,true)){
                        MessageReadingCompleted(readPeriodTermOP);
                    }
                }
                catch(Exception x){
                    m_pException = x;
                    m_pSession.LogAddException("Exception: " + m_pException.Message,m_pException);
                    SetState(AsyncOP_State.Completed);
                }

                op.Dispose();
            }
Exemplo n.º 2
0
        /// <summary>
        /// Stores specified message header + specified lines of body to the specified stream.
        /// </summary>
        /// <param name="sequenceNumber">Message 1 based sequence number.</param>
        /// <param name="stream">Stream where to store data.</param>
        /// <param name="lineCount">Number of lines of message body to get.</param>
        internal void GetTopOfMessage(int sequenceNumber,Stream stream,int lineCount)
        {
            this.TcpStream.WriteLine("TOP " + sequenceNumber.ToString() + " " + lineCount.ToString());

            // Read first line of reply, check if it's ok.
            string line = ReadLine();
            if(line.StartsWith("+OK")){
                SmartStream.ReadPeriodTerminatedAsyncOP readTermOP = new SmartStream.ReadPeriodTerminatedAsyncOP(stream,999999999,SizeExceededAction.ThrowException);
                this.TcpStream.ReadPeriodTerminated(readTermOP,false);
                if(readTermOP.Error != null){
                    throw readTermOP.Error;
                }
                LogAddWrite(readTermOP.BytesStored,"Readed " + readTermOP.BytesStored.ToString() + " bytes.");
            }
            else{
                throw new POP3_ClientException(line);
            }
        }
Exemplo n.º 3
0
// REMOVE ME:
        #region method DATA

        private bool DATA(string cmdText)
        {
            // RFC 5321 3.1.
            if(m_SessionRejected){
                WriteLine("503 bad sequence of commands: Session rejected.");
                return true;
            }
            // RFC 5321 4.1.4.
            if(string.IsNullOrEmpty(m_EhloHost)){
                WriteLine("503 Bad sequence of commands: send EHLO/HELO first.");
                return true;
            }
            // RFC 5321 4.1.4.
            if(m_pFrom == null){
                WriteLine("503 Bad sequence of commands: send 'MAIL FROM:' first.");
                return true;
            }
            // RFC 5321 4.1.4.
            if(m_pTo.Count == 0){
                WriteLine("503 Bad sequence of commands: send 'RCPT TO:' first.");
                return true;
            }
            // RFC 3030 BDAT.
            if(m_pMessageStream != null){
                WriteLine("503 Bad sequence of commands: DATA and BDAT commands cannot be used in the same transaction.");
                return true;
            }

            /* RFC 5321 4.1.1.4.
                The receiver normally sends a 354 response to DATA, and then treats
                the lines (strings ending in <CRLF> sequences, as described in
                Section 2.3.7) following the command as mail data from the sender.
                This command causes the mail data to be appended to the mail data
                buffer.  The mail data may contain any of the 128 ASCII character
                codes, although experience has indicated that use of control
                characters other than SP, HT, CR, and LF may cause problems and
                SHOULD be avoided when possible.
             
                The custom of accepting lines ending only in <LF>, as a concession to
                non-conforming behavior on the part of some UNIX systems, has proven
                to cause more interoperability problems than it solves, and SMTP
                server systems MUST NOT do this, even in the name of improved
                robustness.  In particular, the sequence "<LF>.<LF>" (bare line
                feeds, without carriage returns) MUST NOT be treated as equivalent to
                <CRLF>.<CRLF> as the end of mail data indication.
             
                Receipt of the end of mail data indication requires the server to
                process the stored mail transaction information.  This processing
                consumes the information in the reverse-path buffer, the forward-path
                buffer, and the mail data buffer, and on the completion of this
                command these buffers are cleared.  If the processing is successful,
                the receiver MUST send an OK reply.  If the processing fails, the
                receiver MUST send a failure reply.  The SMTP model does not allow
                for partial failures at this point: either the message is accepted by
                the server for delivery and a positive response is returned or it is
                not accepted and a failure reply is returned.  In sending a positive
                "250 OK" completion reply to the end of data indication, the receiver
                takes full responsibility for the message (see Section 6.1).  Errors
                that are diagnosed subsequently MUST be reported in a mail message,
                as discussed in Section 4.4.

                When the SMTP server accepts a message either for relaying or for
                final delivery, it inserts a trace record (also referred to
                interchangeably as a "time stamp line" or "Received" line) at the top
                of the mail data.  This trace record indicates the identity of the
                host that sent the message, the identity of the host that received
                the message (and is inserting this time stamp), and the date and time
                the message was received.  Relayed messages will have multiple time
                stamp lines.  Details for formation of these lines, including their
                syntax, is specified in Section 4.4.
            */

            DateTime startTime = DateTime.Now;

            m_pMessageStream = OnGetMessageStream();
            if(m_pMessageStream == null){
                m_pMessageStream = new MemoryStreamEx(32000);
            }
            // RFC 5321.4.4 trace info.
            byte[] recevived = CreateReceivedHeader();
            m_pMessageStream.Write(recevived,0,recevived.Length);

            WriteLine("354 Start mail input; end with <CRLF>.<CRLF>");
            
            // Create asynchronous read period-terminated opeartion.
            SmartStream.ReadPeriodTerminatedAsyncOP readPeriodTermOP = new SmartStream.ReadPeriodTerminatedAsyncOP(
                m_pMessageStream,
                this.Server.MaxMessageSize,
                SizeExceededAction.JunkAndThrowException
            );
            // This event is raised only if read period-terminated opeartion completes asynchronously.
            readPeriodTermOP.Completed += new EventHandler<EventArgs<SmartStream.ReadPeriodTerminatedAsyncOP>>(delegate(object sender,EventArgs<SmartStream.ReadPeriodTerminatedAsyncOP> e){                
                DATA_End(startTime,readPeriodTermOP);
            });
            // Read period-terminated completed synchronously.
            if(this.TcpStream.ReadPeriodTerminated(readPeriodTermOP,true)){
                DATA_End(startTime,readPeriodTermOP);

                return true;
            }
            // Read period-terminated completed asynchronously, Completed event will be raised once operation completes.
            // else{
         
            return false;
        }
Exemplo n.º 4
0
            /// <summary>
            /// Is called when POP3 server RETR response reading has completed.
            /// </summary>
            /// <param name="op">Asynchronous operation.</param>
            private void RetrReadResponseCompleted(SmartStream.ReadLineAsyncOP op)
            {
                try{
                    // Operation failed.
                    if(op.Error != null){
                        m_pException = op.Error;
                        m_pPop3Client.LogAddException("Exception: " + op.Error.Message,op.Error);
                        SetState(AsyncOP_State.Completed);
                    }
                    // Operation succeeded.
                    else{
                        // Log
                        m_pPop3Client.LogAddRead(op.BytesInBuffer,op.LineUtf8);
                                            
                        // Server returned success response.
                        if(string.Equals(op.LineUtf8.Split(new char[]{' '},2)[0],"+OK",StringComparison.InvariantCultureIgnoreCase)){
                            SmartStream.ReadPeriodTerminatedAsyncOP readMsgOP = new SmartStream.ReadPeriodTerminatedAsyncOP(m_pStream,long.MaxValue,SizeExceededAction.ThrowException);
                            readMsgOP.Completed += delegate(object sender,EventArgs<SmartStream.ReadPeriodTerminatedAsyncOP> e){
                                MessageReadingCompleted(readMsgOP);
                            };
                            if(m_pPop3Client.TcpStream.ReadPeriodTerminated(readMsgOP,true)){
                                MessageReadingCompleted(readMsgOP);
                            }
                        }
                        // Server returned error response.
                        else{
                            m_pException = new POP3_ClientException(op.LineUtf8);
                            SetState(AsyncOP_State.Completed);
                        }
                    }
                }
                catch(Exception x){
                    m_pException = x;
                    m_pPop3Client.LogAddException("Exception: " + x.Message,x);
                    SetState(AsyncOP_State.Completed);
                }

                op.Dispose();
            }