2005-08-26 Iain McCoy <iain@mccoy.id.au>
[mono.git] / mcs / class / System.Web / System.Web.Mail / SmtpStream.cs
1 //
2 // System.Web.Mail.SmtpStream.cs
3 //
4 // Author(s):
5 //   Per Arneng <pt99par@student.bth.se>
6 //
7 //
8
9 //
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:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
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.
28 //
29 using System;
30 using System.IO;
31 using System.Collections;
32 using System.Text;
33 using System.Security.Cryptography;
34
35 namespace System.Web.Mail {
36
37     internal class SmtpStream {
38         
39         protected Stream stream;
40         protected Encoding encoding;
41         protected SmtpResponse lastResponse;
42         protected string command = "";
43
44         public SmtpStream( Stream stream ) {
45             this.stream = stream;
46             encoding = new ASCIIEncoding();
47         }
48         
49         public Stream Stream {
50             get { return stream; }
51         }
52         
53         public SmtpResponse LastResponse {
54             get { return lastResponse; }
55         }
56         
57         public void WriteRset() {
58             command = "RSET";
59             WriteLine( command );
60             ReadResponse();
61             CheckForStatusCode( 250 );
62         
63         }
64         
65         public void WriteHelo( string hostName ) { 
66             command = "HELO " + hostName;
67             WriteLine( command );
68             ReadResponse();
69             CheckForStatusCode( 250 );
70             
71         }
72         
73         public void WriteMailFrom( string from ) {
74             command = "MAIL FROM: <" + from + ">";
75             WriteLine( command );
76             ReadResponse();
77             CheckForStatusCode( 250 );
78             
79         }
80         
81         public void WriteRcptTo( string to ) {
82             command = "RCPT TO: <" + to + ">";  
83             WriteLine( command );
84             ReadResponse();
85             CheckForStatusCode( 250 );
86                     
87         }
88         
89
90         public void WriteData() {
91             command = "DATA";
92             WriteLine( command );
93             ReadResponse();
94             CheckForStatusCode( 354 );
95         
96         }
97         
98         public void WriteQuit() {
99             command = "QUIT";
100             WriteLine( command );
101             ReadResponse();
102             CheckForStatusCode( 221 );
103         
104         }
105                 
106         public void WriteBoundary( string boundary ) {
107         
108             WriteLine( "\r\n--{0}" , boundary );
109         
110         }
111         
112         public void WriteFinalBoundary( string boundary ) {
113         
114             WriteLine( "\r\n--{0}--" , boundary );
115         
116         }
117         
118         // single dot by itself
119         public void WriteDataEndTag() {
120             command = "\r\n.";
121             WriteLine( command );
122             ReadResponse();
123             CheckForStatusCode( 250 );
124         
125         }
126         
127         
128         public void WriteHeader( MailHeader header ) {
129             // write the headers
130             foreach( string key in header.Data.AllKeys )
131                 WriteLine( "{0}: {1}" , key , header.Data[ key ] );
132             
133             // write the header end tag
134             WriteLine( "" );
135         }
136         
137         public void CheckForStatusCode( int statusCode ) {
138             
139             if( LastResponse.StatusCode != statusCode ) {
140                 
141                 string msg = "" + 
142                     "Server reponse: '" + lastResponse.RawResponse + "';" +
143                     "Status code: '" +  lastResponse.StatusCode + "';" + 
144                     "Expected status code: '" + statusCode + "';" + 
145                     "Last command: '" + command + "'";
146                 
147                 throw new SmtpException( msg ); 
148                                         
149             }
150         }
151         
152         
153         // write buffer's bytes to the stream
154         public void WriteBytes( byte[] buffer ) {
155             stream.Write( buffer , 0 , buffer.Length );
156         }
157         
158         // writes a formatted line to the server
159         public void WriteLine( string format ,  params object[] args ) {
160             WriteLine( String.Format( format , args ) );
161         }
162         
163         // writes a line to the server
164         public void WriteLine( string line ) {
165             byte[] buffer = encoding.GetBytes( line + "\r\n" );
166             
167             stream.Write( buffer , 0 , buffer.Length );
168         
169             #if DEBUG 
170               DebugPrint( line );
171             #endif
172         }
173         
174         // read a line from the server
175         public void ReadResponse( ) {
176             string line = null;
177             
178             byte[] buffer = new byte[ 4096 ];
179             
180             int readLength = stream.Read( buffer , 0 , buffer.Length );
181             
182             if( readLength > 0 ) { 
183             
184                 line = encoding.GetString( buffer , 0 , readLength );
185                 
186                 line = line.TrimEnd( new Char[] { '\r' , '\n' , ' ' } );
187                         
188             }
189            
190             // parse the line to the lastResponse object
191             lastResponse = SmtpResponse.Parse( line );
192            
193             #if DEBUG
194               DebugPrint( line );
195             #endif
196         }
197         
198     #if DEBUG
199         /// debug printing 
200         private void DebugPrint( string line ) {
201             Console.WriteLine( "smtp: {0}" , line );
202         }
203     #endif
204
205     }
206
207
208 }