2 // System.Web.Mail.SmtpStream.cs
5 // Per Arneng <pt99par@student.bth.se>
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System.Collections;
33 using System.Security.Cryptography;
35 namespace System.Web.Mail {
37 internal class SmtpStream {
39 protected Stream stream;
40 protected Encoding encoding;
41 protected SmtpResponse lastResponse;
42 protected string command = "";
44 public SmtpStream( Stream stream ) {
46 encoding = new ASCIIEncoding();
49 public Stream Stream {
50 get { return stream; }
53 public SmtpResponse LastResponse {
54 get { return lastResponse; }
57 public void WriteRset() {
61 CheckForStatusCode( 250 );
65 public void WriteHelo( string hostName ) {
66 command = "HELO " + hostName;
69 CheckForStatusCode( 250 );
73 public void WriteMailFrom( string from ) {
74 command = "MAIL FROM: <" + from + ">";
77 CheckForStatusCode( 250 );
81 public void WriteRcptTo( string to ) {
82 command = "RCPT TO: <" + to + ">";
85 CheckForStatusCode( 250 );
90 public void WriteData() {
94 CheckForStatusCode( 354 );
98 public void WriteQuit() {
100 WriteLine( command );
102 CheckForStatusCode( 221 );
106 public void WriteBoundary( string boundary ) {
108 WriteLine( "\r\n--{0}" , boundary );
112 public void WriteFinalBoundary( string boundary ) {
114 WriteLine( "\r\n--{0}--" , boundary );
118 // single dot by itself
119 public void WriteDataEndTag() {
121 WriteLine( command );
123 CheckForStatusCode( 250 );
128 public void WriteHeader( MailHeader header ) {
130 foreach( string key in header.Data.AllKeys )
131 WriteLine( "{0}: {1}" , key , header.Data[ key ] );
133 // write the header end tag
137 public void CheckForStatusCode( int statusCode ) {
139 if( LastResponse.StatusCode != statusCode ) {
142 "Server reponse: '" + lastResponse.RawResponse + "';" +
143 "Status code: '" + lastResponse.StatusCode + "';" +
144 "Expected status code: '" + statusCode + "';" +
145 "Last command: '" + command + "'";
147 throw new SmtpException( msg );
153 // write buffer's bytes to the stream
154 public void WriteBytes( byte[] buffer ) {
155 stream.Write( buffer , 0 , buffer.Length );
158 // writes a formatted line to the server
159 public void WriteLine( string format , params object[] args ) {
160 WriteLine( String.Format( format , args ) );
163 // writes a line to the server
164 public void WriteLine( string line ) {
165 byte[] buffer = encoding.GetBytes( line + "\r\n" );
167 stream.Write( buffer , 0 , buffer.Length );
174 // read a line from the server
175 public void ReadResponse( ) {
178 byte[] buffer = new byte[ 4096 ];
180 int readLength = stream.Read( buffer , 0 , buffer.Length );
182 if( readLength > 0 ) {
184 line = encoding.GetString( buffer , 0 , readLength );
186 line = line.TrimEnd( new Char[] { '\r' , '\n' , ' ' } );
190 // parse the line to the lastResponse object
191 lastResponse = SmtpResponse.Parse( line );
200 private void DebugPrint( string line ) {
201 Console.WriteLine( "smtp: {0}" , line );