(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / class / System.Web / System.Web.Mail / SmtpClient.cs
blob1b0e388c9d25d7d2ff1544d28aca5488b2c0a46e
1 //
2 // System.Web.Mail.SmtpClient.cs
3 //
4 // Author(s):
5 // Per Arneng <pt99par@student.bth.se>
6 // Sanjay Gupta <gsanjay@novell.com>
7 // (C) 2004, Novell, Inc. (http://www.novell.com)
8 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 //
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 //
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System;
31 using System.Net;
32 using System.IO;
33 using System.Text;
34 using System.Collections;
35 using System.Net.Sockets;
37 namespace System.Web.Mail {
39 /// represents a conntection to a smtp server
40 internal class SmtpClient {
42 private string server;
43 private TcpClient tcpConnection;
44 private SmtpStream smtp;
45 private Encoding encoding;
47 //Initialise the variables and connect
48 public SmtpClient( string server ) {
50 this.server = server;
51 encoding = new ASCIIEncoding( );
53 Connect();
56 // make the actual connection
57 // and HELO handshaking
58 private void Connect() {
59 tcpConnection = new TcpClient( server , 25 );
61 Stream stream = tcpConnection.GetStream();
62 smtp = new SmtpStream( stream );
64 // read the server greeting
65 smtp.ReadResponse();
66 smtp.CheckForStatusCode( 220 );
68 // write the HELO command to the server
69 smtp.WriteHelo( Dns.GetHostName() );
73 public void Send( MailMessageWrapper msg ) {
75 if( msg.From == null ) {
76 throw new SmtpException( "From property must be set." );
79 if( msg.To == null ) {
80 if( msg.To.Count < 1 ) throw new SmtpException( "Atleast one recipient must be set." );
84 // start with a reset incase old data
85 // is present at the server in this session
86 smtp.WriteRset();
88 // write the mail from command
89 smtp.WriteMailFrom( msg.From.Address );
91 // write the rcpt to command for the To addresses
92 foreach( MailAddress addr in msg.To ) {
93 smtp.WriteRcptTo( addr.Address );
96 // write the rcpt to command for the Cc addresses
97 foreach( MailAddress addr in msg.Cc ) {
98 smtp.WriteRcptTo( addr.Address );
101 // write the rcpt to command for the Bcc addresses
102 foreach( MailAddress addr in msg.Bcc ) {
103 smtp.WriteRcptTo( addr.Address );
106 // write the data command and then
107 // send the email
108 smtp.WriteData();
110 if( msg.Attachments.Count == 0 ) {
111 #if NET_2_0
112 //The message might be multipart, if RelatedBodyParts are present
113 if (msg.RelatedBodyParts.Count != 0)
114 SendMultipartMail (msg);
115 else
116 #endif
117 SendSinglepartMail( msg );
118 } else {
120 SendMultipartMail( msg );
124 // write the data end tag "."
125 smtp.WriteDataEndTag();
129 // sends a single part mail to the server
130 private void SendSinglepartMail( MailMessageWrapper msg ) {
132 // write the header
133 smtp.WriteHeader( msg.Header );
135 // send the mail body
136 smtp.WriteBytes( msg.BodyEncoding.GetBytes( msg.Body ) );
140 // sends a multipart mail to the server
141 private void SendMultipartMail( MailMessageWrapper msg ) {
143 // generate the boundary between attachments
144 string boundary = MailUtil.GenerateBoundary();
146 // set the Content-Type header to multipart/mixed
147 string bodyContentType = msg.Header.ContentType;
149 #if NET_2_0
150 if (msg.RelatedBodyParts.Count != 0)
151 msg.Header.ContentType = String.Format( "multipart/related;\r\n boundary={0}" , boundary );
152 else
153 #endif
154 msg.Header.ContentType =
155 String.Format( "multipart/mixed;\r\n boundary={0}" , boundary );
157 // write the header
158 smtp.WriteHeader( msg.Header );
160 // write the first part text part
161 // before the attachments
162 smtp.WriteBoundary( boundary );
164 MailHeader partHeader = new MailHeader();
165 partHeader.ContentType = bodyContentType;
167 #if NET_1_1
168 // Add all the custom headers to body part as specified in
169 //Fields property of MailMessageWrapper
171 //Remove fields specific for authenticating to SMTP server.
172 //Need to incorporate AUTH command in SmtpStream to handle
173 //Authorization info. Its a temporary fix for Bug no 68829.
174 //Will dig some more on SMTP AUTH command, and then implement
175 //Authorization. - Sanjay
177 if (msg.Fields.Data ["http://schemas.microsoft.com/cdo/configuration/smtpauthenticate"] != null)
178 msg.Fields.Data.Remove ("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate");
179 if (msg.Fields.Data ["http://schemas.microsoft.com/cdo/configuration/sendusername"] != null)
180 msg.Fields.Data.Remove ("http://schemas.microsoft.com/cdo/configuration/sendusername");
181 if (msg.Fields.Data ["http://schemas.microsoft.com/cdo/configuration/sendpassword"] != null)
182 msg.Fields.Data.Remove ("http://schemas.microsoft.com/cdo/configuration/sendpassword");
183 partHeader.Data.Add (msg.Fields.Data);
184 #endif
186 smtp.WriteHeader( partHeader );
188 // FIXME: probably need to use QP or Base64 on everything higher
189 // then 8-bit .. like utf-16
190 smtp.WriteBytes( msg.BodyEncoding.GetBytes( msg.Body ) );
192 smtp.WriteBoundary( boundary );
194 #if NET_2_0
195 for (int i = 0; i < msg.RelatedBodyParts.Count; i++) {
196 RelatedBodyPart rbp = (RelatedBodyPart) msg.RelatedBodyParts [i];
197 FileInfo file = new FileInfo (rbp.Path);
198 MailHeader header = new MailHeader ();
199 header.ContentLocation = rbp.Path;
200 header.ContentType = String.Format (MimeTypes.GetMimeType (file.Name) + "; name=\"{0}\"",file.Name);
201 //If content id and ContentLocation both are present
202 //in mime header of a mail, than RelatedBodyPart of mail
203 //doesnt show up in a machine other than from which mail
204 //was sent, and hence only one of them is inserted in
205 //header. Need to check how the things go when another
206 //body part refers the content with the content id specified
207 /*if (rbp.Name != null)
208 header.Data.Add ("Content-ID", "<"+rbp.Name+">");*/
210 header.ContentTransferEncoding = "Base64";
211 header.ContentDisposition = String.Format( "inline; filename=\"{0}\"" , file.Name );
213 smtp.WriteHeader (header);
214 FileStream rbpStream = new FileStream (file.FullName, FileMode.Open);
215 IAttachmentEncoder rbpEncoder = new Base64AttachmentEncoder ();
216 rbpEncoder.EncodeStream (rbpStream, smtp.Stream);
217 rbpStream.Close();
218 smtp.WriteLine( "" );
220 if (i < (msg.RelatedBodyParts.Count - 1)) {
221 smtp.WriteBoundary (boundary);
222 } else {
223 if (msg.Attachments.Count == 0)
224 smtp.WriteFinalBoundary (boundary);
225 else
226 smtp.WriteBoundary (boundary);
230 #endif
231 // now start to write the attachments
233 for( int i=0; i< msg.Attachments.Count ; i++ ) {
234 MailAttachment a = (MailAttachment)msg.Attachments[ i ];
236 FileInfo fileInfo = new FileInfo( a.Filename );
238 MailHeader aHeader = new MailHeader();
240 aHeader.ContentType =
241 String.Format (MimeTypes.GetMimeType (fileInfo.Name) + "; name=\"{0}\"",fileInfo.Name);
243 aHeader.ContentDisposition =
244 String.Format( "attachment; filename=\"{0}\"" , fileInfo.Name );
246 aHeader.ContentTransferEncoding = a.Encoding.ToString();
248 smtp.WriteHeader( aHeader );
250 // perform the actual writing of the file.
251 // read from the file stream and write to the tcp stream
252 FileStream ins = new FileStream( fileInfo.FullName , FileMode.Open );
254 // create an apropriate encoder
255 IAttachmentEncoder encoder;
256 if( a.Encoding == MailEncoding.UUEncode ) {
257 encoder = new UUAttachmentEncoder( 644 , fileInfo.Name );
258 } else {
259 encoder = new Base64AttachmentEncoder();
262 encoder.EncodeStream( ins , smtp.Stream );
264 ins.Close();
267 smtp.WriteLine( "" );
269 // if it is the last attachment write
270 // the final boundary otherwise write
271 // a normal one.
272 if( i < (msg.Attachments.Count - 1) ) {
273 smtp.WriteBoundary( boundary );
274 } else {
275 smtp.WriteFinalBoundary( boundary );
282 // send quit command and
283 // closes the connection
284 public void Close() {
286 smtp.WriteQuit();
287 tcpConnection.Close();