jstedfast / mailkit Goto Github PK
View Code? Open in Web Editor NEWA cross-platform .NET library for IMAP, POP3, and SMTP.
Home Page: http://www.mimekit.net
License: MIT License
A cross-platform .NET library for IMAP, POP3, and SMTP.
Home Page: http://www.mimekit.net
License: MIT License
Got a crash when trying to do a fetch:
OutOfMemoryException
2014-01-25 19:56:45.808 Support[3831:80b] Unhandled managed exception: Out of memory (System.OutOfMemoryException)
at (wrapper managed-to-native) string:InternalAllocateStr (int)
at System.Text.StringBuilder.InternalEnsureCapacity (Int32 size) [0x000b1] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Text/StringBuilder.cs:716
at System.Text.StringBuilder.Append (System.String value) [0x00082] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Text/StringBuilder.cs:373
at System.String.FormatHelper (System.Text.StringBuilder result, IFormatProvider provider, System.String format, System.Object[] args) [0x001d1] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System/String.cs:2049
at System.Text.StringBuilder.AppendFormat (IFormatProvider provider, System.String format, System.Object[] args) [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Text/StringBuilder.cs:537
at System.Text.StringBuilder.AppendFormat (System.String format, System.Object arg0, System.Object arg1) [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Text/StringBuilder.cs:550
at MailKit.Net.Imap.ImapUtils.FormatUidSet (System.UInt32[] uids) [0x00083] in /Users/fak/Dropbox/Projects/PersonalMail/MailKit/MailKit/Net/Imap/ImapUtils.cs:145
at MailKit.Net.Imap.ImapUtils.FormatUidSet (System.String[] uids) [0x0005b] in /Users/fak/Dropbox/Projects/PersonalMail/MailKit/MailKit/Net/Imap/ImapUtils.cs:210
at MailKit.Net.Imap.ImapFolder.Fetch (System.String[] uids, MessageSummaryItems items, CancellationToken cancellationToken) [0x0000a] in /Users/fak/Dropbox/Projects/PersonalMail/MailKit/MailKit/Net/Imap/ImapFolder.cs:1733
at Support.MailSupportService+<GetRecentMessagesAsync>c__async0+<GetRecentMessagesAsync>c__AnonStorey5.<>m__0 () [0x0007d] in /Users/fak/Dropbox/Projects/PersonalMail/Support/Support/MailSupportService.cs:44
Here is the code:
var inbox = imap.Inbox;
inbox.Open (MailKit.FolderAccess.ReadOnly, token);
var uids = inbox.Search (SearchQuery.SentAfter (DateTime.UtcNow.AddDays (-2)), token);
var sums = inbox.Fetch (uids, MessageSummaryItems.Envelope, token);
var q = from m in sums
select new SupportMessage {
Date = m.Envelope.Date.Value.UtcDateTime,
Subject = m.Envelope.Subject,
};
var r = q.ToList ();
inbox.Close (false, token);
Hi,
I'm using Mailkit library for couple of months in a pilot project. I'm facing a strange issue while authenticating with GoDaddy pop server using MailKit Pop3 Client.
Here is the code.
MailKit.Net.Pop3.Pop3Client client = new MailKit.Net.Pop3.Pop3Client();
CancellationTokenSource cancel = new CancellationTokenSource();
var credentials = new System.Net.NetworkCredential("XXX", "XXX");
var uri = new Uri("pops://pop.secureserver.net:995");
client.Connect(uri, cancel.Token);
client.Authenticate(credentials, cancel.Token);
Exception : "Unable to login. Unexpected response from server: warning: auth_error: authorization failed (authorization failed wrong password)".
Above code able the connect with godaddy pop server. But unable to authenticate the username & password (while the same pop setting and credentials are working fine with outlook.). While reviewing the code of MailKit.Net.Pop3.Pop3Client class, i found it is checking pop server capabilities in a order of 'APop','Sasl' and 'User'. In my scenario (with GoDaddy Pop server) Pop3Client class is using 'APop' capability to authenticate with pop server. Could you help me on this or guide me to follow correct approach.
Thanks.
It would be nice if there was a way to set the timeout value for requests on the client.
I using MailKit.Net.Imap to get the Attachments in mail,
with code like,
if (message.Attachments.Count() > 0)
{
System.IO.Directory.CreateDirectory(@"d:\mailAttachmentsTemp\");
System.IO.DirectoryInfo dir = System.IO.Directory.CreateDirectory(@"d:\mailAttachmentsTemp\" + message.MessageId);
foreach (var mp in message.Attachments)
{
using (var stream = System.IO.File.Create(dir.FullName + @"\" + mp.FileName))
{
mp.ContentObject.DecodeTo(stream);
stream.Close();
}
}
}
with an image like (122,332 bytes)
Downloaded file will be same size (122,332 bytes), but with something wrong,
other file format like .7z will get error too.
Thanks,
ImapClient.Connect
As far as I can tell, this code needs break
after the socket.Connect
line. Why connect to all IPs?
try {
socket.Connect (ipAddresses[i], port);
break;
} catch (Exception) {
if (i + 1 == ipAddresses.Length)
throw;
}
I'm trying to use SMTP the old way (with the password in plain text et-al... :-/ ), and it gives me this exception:
[SaslException: Invalid SASL challenge from the server: Username:]
MailKit.Security.DigestChallenge.Parse(String token) +1319
MailKit.Security.SaslMechanismDigestMd5.Challenge(Byte[] token, Int32 startIndex, Int32 length) +276
MailKit.Security.SaslMechanism.Challenge(String token) +54
MailKit.Net.Smtp.SmtpClient.Authenticate(ICredentials credentials, CancellationToken cancellationToken) +604
FsWeb.Controllers.BackOfficeController.SendEmail(MimeMessage msg) in C:\Users\knocte\documents\visual studio 2012\Projects\FSolar\src\ConclaveSolarWebWebAppApi\BackOfficeController.fs:38
I've verified like a thousand times that my username is correct, but MailKit insists in sending this error.
The code I'm using (F#) is:
use client = new SmtpClient()
let credentials =
new NetworkCredential(ConfigurationManager.AppSettings.["SmtpUsername"],
ConfigurationManager.AppSettings.["SmtpPassword"])
let uri = new Uri (ConfigurationManager.AppSettings.["SmtpHost"])
let cancelToken = new CancellationTokenSource()
client.Connect(uri, cancelToken.Token)
// Note: since we don't have an OAuth2 token, disable
// the XOAUTH2 authentication mechanism.
ignore(client.AuthenticationMechanisms.Remove ("XOAUTH2"))
// Note: only needed if the SMTP server requires authentication
client.Authenticate (credentials, cancelToken.Token);
client.Send (msg, cancelToken.Token);
client.Disconnect (true, cancelToken.Token);
This works well with a smtps:// host URI (like gmail), but not with a smtp:// one...
(I'm using MailKit 0.10.0 from nuget, does this sound like maybe being fixed in newer versions already?)
If MimeKit is truly the foundation for MailKit, then it should be a Git submodule. Tangent to this, is that in the "base" solution, I presume MailKit.Net40.sln, there are a handful of projects not loading. I can understand possibly BouncyCastle and possibly also Mono.Data.Sqlite, but not MimeKit (i.e. as a Git submodule).
Error en la instalación. Revirtiendo...
Install-Package : No se pudo instalar el paquete 'MailKit 0.11.0.0'. Está intentando instalar este paquete en un proyecto que tiene 'WindowsPhone,Version=v8.0' como
destino, pero el paquete no contiene referencias de ensamblado o archivos de contenido compatibles con dicho marco. Para obtener más información, póngase en contacto con
el autor del paquete.
En línea: 1 Carácter: 1
- CategoryInfo : NotSpecified: (:) [Install-Package], InvalidOperationException
- FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PowerShell.Commands.InstallPackageCommand
PM>
Hi Jeff, for an uknown reason I never get access to the Sent folders, result is null. Inbox works. Any idea?
Thanks,
Tomas
My mail server reports StartTLS capability, but in fact do not support it.
So when mailkit try to make handshake it fails.
It would be helpfull if I can disable some capabilities similar to the way I can disable
authentication methods.
Hi jstedfast,
small thing here:>
if folder.count=0 you get exception when Fetch parameter min =0 due to this condition:
if (min < 0 || min >= Count)
throw new ArgumentOutOfRangeException ("min");
fixed to min>Count in code...
pls check if this is correct.
KR,
Tomas
When abstracting over MailKit, I need to have a compatible type with UniqueId. That is, I need to be able to convert to and from UniqueId and some generic (compatible) type.
I can construct UniqueId with a uint, why can't I access it? Obviously, you had the need to otherwise it wouldn't be internal.
public struct UniqueId : IComparable<UniqueId>, IEquatable<UniqueId>
{
internal readonly uint Id;
hi,
How do I read mail in the body as a string..
using (var client = new ImapClient())
{
var credentials = new NetworkCredential("[email protected]", "xxx");
var uri = new Uri("imaps://imap.gmail.com");
using (var cancel = new CancellationTokenSource())
{
try
{
client.Connect(uri, cancel.Token);
client.Authenticate(credentials, cancel.Token);
var sent = client.GetFolder(SpecialFolder.Sent);
sent.Open(FolderAccess.ReadOnly, cancel.Token);
var query = SearchQuery.DeliveredAfter(Convert.ToDateTime("01-01-2014"));
foreach (var uid in sent.Search(query, cancel.Token))
{
var message = sent.GetMessage(uid, cancel.Token);
string mailUid = uid.ToString();
string mailTo = message.To.ToString();
string mailCc = message.Cc.ToString();
string mailSubject = message.Subject;
string mailDate = message.Date.ToString("yyyy-MM-dd HH:mm:ss");
string mailMessageId = message.MessageId;
txtMessages.Text = message.BodyParts.ToString();
}
}
catch (Exception)
{
throw;
}
client.Disconnect(true, cancel.Token);
}
}
When using Fetch against a Courier IMAP server that has this bug (current version on Ubuntu 12.04LTS) the client can hang at different points while trying to read when no more input is available.
In one example which I can repro the call stack looks like this:
System.dll!System.Net.Sockets.Socket.Receive(byte[] buffer, int offset, int size, System.Net.Sockets.SocketFlags socketFlags, out System.Net.Sockets.SocketError errorCode)
System.dll!System.Net.Sockets.NetworkStream.Read(byte[] buffer, int offset, int size)
System.dll!System.Net.FixedSizeReader.ReadPacket(byte[] buffer, int offset, int count)
System.dll!System.Net.Security._SslStream.StartFrameHeader(byte[] buffer, int offset, int count, System.Net.AsyncProtocolRequest asyncRequest)
System.dll!System.Net.Security._SslStream.StartReading(byte[] buffer, int offset, int count, System.Net.AsyncProtocolRequest asyncRequest)
System.dll!System.Net.Security._SslStream.ProcessRead(byte[] buffer, int offset, int count, System.Net.AsyncProtocolRequest asyncRequest)
System.dll!System.Net.Security.SslStream.Read(byte[] buffer, int offset, int count)
MailKit.dll!MailKit.Net.Imap.ImapStream.ReadAhead(byte* inbuf, int atleast)
MailKit.dll!MailKit.Net.Imap.ImapStream.ReadQuotedStringToken(byte* inbuf, System.Threading.CancellationToken cancellationToken)
MailKit.dll!MailKit.Net.Imap.ImapStream.ReadToken(System.Threading.CancellationToken cancellationToken)
MailKit.dll!MailKit.Net.Imap.ImapEngine.ReadToken(System.Threading.CancellationToken cancellationToken)
MailKit.dll!MailKit.Net.Imap.ImapUtils.AddEnvelopeAddress(MimeKit.InternetAddressList list, MailKit.Net.Imap.ImapEngine engine, System.Threading.CancellationToken cancellationToken)
MailKit.dll!MailKit.Net.Imap.ImapUtils.ParseEnvelopeAddressList(MailKit.Net.Imap.ImapEngine engine, System.Threading.CancellationToken cancellationToken)
MailKit.dll!MailKit.Net.Imap.ImapUtils.ParseEnvelope(MailKit.Net.Imap.ImapEngine engine, System.Threading.CancellationToken cancellationToken)
MailKit.dll!MailKit.Net.Imap.ImapFolder.FetchSummaryItems(MailKit.Net.Imap.ImapEngine engine, MailKit.Net.Imap.ImapCommand ic, int index, MailKit.Net.Imap.ImapToken tok)
MailKit.dll!MailKit.Net.Imap.ImapEngine.ProcessUntaggedResponse(System.Threading.CancellationToken cancellationToken)
MailKit.dll!MailKit.Net.Imap.ImapCommand.Step()
MailKit.dll!MailKit.Net.Imap.ImapEngine.Iterate()
MailKit.dll!MailKit.Net.Imap.ImapEngine.Wait(MailKit.Net.Imap.ImapCommand ic)
MailKit.dll!MailKit.Net.Imap.ImapFolder.Fetch(int min, int max, MailKit.MessageSummaryItems items, System.Threading.CancellationToken cancellationToken)
The last line in the log (unfortunately a real customer email so had to xxx out some information):
S: * 16 FETCH (UID 6353 FLAGS (nonjunk) INTERNALDATE "18-Mar-2014 10:57:48 +0100" ENVELOPE ("Tue, 18 Mar 2014 09:57:48 +0000" "=?us-ascii?Q?xxx?= =?us-ascii?Q?xxx?= =?us-ascii?Q?xxx?= =?us-ascii?Q?xxx?= =?us-ascii?Q?xxx?= =?us-ascii?Q?xxx?= =?us-ascii?Q?xxx?=" (("xxx" NIL "xxx" "xxx")) (("xxx" NIL "xxx" "xxx")) (("xxx" NIL "xxx" "xxx")) ((NIL NIL "sales" "up* BYE [ALERT] Fatal error: Invalid argument
I believe the problem is in ImapStream.ReadQuotedStringToken where it keeps looking for the closing quote although there are no more bytes to read.
I can't repro this right now, but at some point it also hung at ImapEngine.ReadLine at
while (!stream.ReadLine (out buf, out offset, out count)) {
cancellationToken.ThrowIfCancellationRequested ();
memory.Write (buf, offset, count);
}
Currently IDLE extension is not supported, however its one of the most useful extension for listening to imap server events. Any plans for adding it in?
It shouldn't be very hard so I could try to submit a pull request. Reading the source code, I guess adding a new function in ImapEngine, which issues the ImapCommand for IDLE and returns the imap command should do the trick? The caller could then add untaggedhandlers to the imap command for listening to the untagged events. But I am not sure how the API for waiting should look like.
Tested this on gmail
If i have a folder at the root like
Folder to be renamed
And i rename it to 'Folder to be renamed - renamed', it will result in
/Folder to be renamed - renamed
Including the / at the beginning of the name. This doesn't happen if the folder has a parent other than the root folder.
Looking at the source for imap rename folder, this is what the problem seems to be
var encodedName = ImapEncoding.Encode (parent.FullName + parent.DirectorySeparator + name);
var ic = Engine.QueueCommand (cancellationToken, null, "RENAME %F %S\r\n", this, encodedName);
encodedName will end up being '/Folder to be renamed - renamed'
Since the parent folder is the root and its FullName property is just an empty string
MailKit version: 0.16.0.0
But this seem to also be an issue in the latest version.
Hi, since the new Xamarin environment support the PCL as the VS 4.5.x why you don't migrate to this .net version and reduce the numbre of project and files you currently use ???
Thanks
Stefano
Is there the possibility to work with .Net 3.5?
Okay, so during the connection sequence, instead of a USER and PASS command, use the Uri interface?
The POP Uri from the spec is something like this? I have the following snippets in a configuration section. I noticed "pop3s" in the code, though (?).
Edit:
public Uri Uri
{
get
{
return new Uri(string.Format(@"{0}://{1};auth=*@{2}:{3}",
UseSsl ? @"pops" : @"pop", User, Server, Port));
}
}
public ICredentials Credentials
{
get { return new NetworkCredential(User, Password); }
}
Hi guys,
I was trying to retrieve the attachments from my emails, but once I execute the code below all the reviewed emails are returning 0 on the Count,
Below is the code, there are 5 emails and only one has the attachment
Dim message = inbox.GetMessage(indexMessage, cancel.Token)
If (message.Attachments.Count > 0) Then
For Each attachment As Object In message.Attachments
allAttachments.Add(attachment)
Next
Else
End If
Hi, i ve crossed with an issue and i dont know if mail kit supports my scenario.
I have users on my system, whom i give the chance to compose emails on my app and send them with some attachments.
I ve made a test app with the following code
MailMessage m= new MailMessage();
m.From= new MailAddress( "[email protected]","Joey Tribbiani");
m.To.Add(new MailAddress("[email protected]", "Mrs. Chanandler Bong"));
m.Subject = "How you doin'?";
m.Body = @"Hey Chandler,I just wanted to let you know that Monica and I were going to go play some paintball, you in?-- Joey" ;
var message = MimeMessage.CreateFromMailMessage(m);
using (var client = new SmtpClient())
{
var credentials = new NetworkCredential("[email protected]", "XXX");
// Note: if the server requires SSL-on-connect, use the "smtps" protocol instead
var uri = new Uri("smtp://smtp.gmail.com:587");
using (var cancel = new CancellationTokenSource())
{
client.Connect(uri, cancel.Token);
// Note: since we don't have an OAuth2 token, disable
// the XOAUTH2 authentication mechanism.
client.AuthenticationMechanisms.Remove("XOAUTH2");
// Note: only needed if the SMTP server requires authentication
client.Authenticate(credentials, cancel.Token);
client.Send(message, cancel.Token);
client.Disconnect(true, cancel.Token);
}
}
}
The problem is that if i enter on my hotmail account i see the sent message, but in the from of the mail i dont see [email protected], instead of that i see agmailaccountiown@gmail .com ... and i cant understand why, because i ve set the from and the message properties are correctly set.
Can you help me please?
I don't know what I'm doing wrong. I call into Connect with my Uri and it is disappearing into connection space. This was working using the OpenPop version(s) of the same code.
From a cursory examination of the Pop3Client.cs source as well, there doesn't look to be that much difference between a "pop" and a "pops" request.
My Uri is actually this: {pop://server:995/} (not literally server, but the actual POP3 server). I'll try the "pop3" thingy, thinking it might be this version of NuGet package.
I am using Xamarin @mac. I followed the instruction, forked and created local clones for all prerequisities. Next, I try to open MailKit.Mobile and it fails to find BouncyCastle.Android.csproj and BouncyCastle.iOS.csproj files, as those are not there. I tried adding crypto.csproj but Xamarin fails to do that (unknown file format).
Any clues?
// Get the first personal namespace and list the toplevel folders under it.
var personal = client.GetFolder (client.PersonalNamespaces[0]);
foreach (var folder in personal.GetSubfolders (false, cancel.Token))
Console.WriteLine ("[folder] {0}", folder.Name);
On Gmail this example returns a folder with an empty name and no subfolders.
Using Inbox, I don't get any of the folders that descend from the mail root.
If I use [Gmail] as the root folder, I can get all the special folders.
I can't determine how to get all the 'label' folders in Gmail that descend from the mail root, which is not Inbox in Gmail.
Calling ImapFolder.Fetch with 0 uids makes a call to the server and fails. It should probably short cut and just return an empty array.
MailKit.Net.Imap.ImapCommandException: The IMAP server replied to the 'FETCH' command with a 'BAD' response.
at MailKit.Net.Imap.ImapFolder.Fetch (MailKit.UniqueId[] uids, MessageSummaryItems items, CancellationToken cancellationToken) [0x000a9] in /Users/fak/Dropbox/Projects/PersonalMail/MailKit/MailKit/Net/Imap/ImapFolder.cs:1814
Hi Jeff,
I am facing a problem with only one of my mailboxes.
When I use the sample code shown on the repo's homepage (IMAP section)
// The Inbox folder is always available on all IMAP servers...
var inbox = client.Inbox;
inbox
variable returns null.
After inspection of the code, it appears that the problem is in the "QuerySpecialFolders" method (ImapEngine.cs)
if (!FolderCache.TryGetValue ("INBOX", out folder)) {
//Some Code
Inbox = list.Count > 0 ? list[0] : null;
}
With this email account FolderCache
already contains Inbox folder, therefore the Inbox
variable is never assigned.
Workaround :
if (!FolderCache.TryGetValue ("INBOX", out folder)) {
// Some code
}else {
Inbox = folder;
}
Now it works but I don't know if it's the right way..
I can create an email account for Tests if you need it
Getting this response from server: {"status":"400","schemes":"Bearer","scope":"https://mail.google.com/"}
Seems to be defaulting to use XOAUTH2
Hello,
Running the Pop3Client sample code in a timer keeps a lot of connections with CLOSE_WAIT state and ESTABLISHED state open (verified with sysinternals TCPView).
Checking 5 Mailaccounts every 30 seconds quickly produces about 150 open connections (about 50% with CLOSE_WAIT state).
About 10 minutes later all the connections get closed and then they start building up again.
Environment: Win8, Pop3s
Hi! i found this great lib and i really need async ops....
Do you have an ETA for this feature? any workaround?
Thanks!
Hi guys,
Is there a way to check if the retrieved emails are related to bounced emails, or other delivery issues?
Thanks
Hello,
This is the first time I'm using MailKit and I'm trying to get the IMAP sample to work.
Unfortunatly something seems to be going wrong during the GetMessage call. It seems to be in an endless loop and never returns out of the method.
I added a ProtocolLogger to the ImapClient and according to the log it does actually download the entire message properly. The last thing logged is the retrieval of an image:
S: --002_2A8DFCCDD7437146AA5EE829D9FC63918384E934HVMSGWP25troika
S: Content-Type: image/png; name="image001.png"
S: Content-Description: image001.png
S: Content-Disposition: inline; filename="image001.png"; size=8154;
S: creation-date="Tue, 17 Jun 2014 12:53:40 GMT";
S: modification-date="Tue, 17 Jun 2014 12:53:40 GMT"
S: Content-ID: [email protected]
S: Content-Transfer-Encoding: base64
S:
S: iVBORw0KGgoAAAANSUhEUgAAAIEAAAArCAYAAABfJ+vYAAAABGdBTUEAALGOfPtRkwAAACBjSFJN
S: AACHDwAAjA8AAP1SAACBQAAAfXkAAOmLAAA85QAAGcxzPIV3AAAKL2lDQ1BJQ0MgUHJvZmlsZQAA
S: SMedlndUVNcWh8+9d3qhzTACUobeu8AA0nuTXkVhmBlgKAMOMzSxIaICEUVEmiJIUMSA0VAkVkSx
S: EBRUsAckCCgxGEVULG9G1ouurLz38vL746xv7bP3ufvsvc9aFwCSpy+XlwZLAZDKE/CDPJzpEZFR
S: dOwAgAEeYIApAExWRrpfsHsIEMnLzYWeIXICXwQB8HpYvAJw09AzgE4H/5+kWel8geiYABGbszkZ
S: LBEXiDglS5Auts+KmBqXLGYYJWa+KEERy4k5YZENPvsssqOY2ak8tojFOaezU9li7hXxtkwhR8SI
etc. etc. etc.
What could be going wrong that causes the GetMessage to be in an endess loop? What other information can I share?
My guess is that MailEngine.Wait is pretty dangerous. Guess I will have to download the source to do some debugging.
Thanks!
Thanks for the great library. I was trying to create inbox sample and I am able to get the following attributes so far using Pop3Client.GetMessageHeaders:
From, Subject, Date, Index
Q1. How do I know that a message contains any attachments without downloading whole message? because of the internet speed, I can't download whole message. Each time the user clicks on a link, then I will fetch whole message.
Q2. I just want to display the links of attachments to download in UI without downloading whole message. Once the download attachment link is clicked, then I will download that particular attachment(s) without downloading message
In simple word, is it possible to download message only, attachment(s) only and identify that if message contains any attachment without downloading whole message?
or is there any other way around to address this issue?
Thanks for the help
Hello,
I'm a newbie so be kind :-)
When I'm downloading emails from my Exchange 2013 server, when I reach a chain emails (replies to replies...) the GetMessage returns null.
I have data in fetch envelope command but no fetch body or attachements.
And the same for accessing Tasks or Activities folder where I receive the "Retrieval using the IMAP4 protocol failed for the following message: 2" message.
Thank's
Per the POP3 specification, UID is an optional feature. Indexing, on the other hand, is considered fundamental; there is no other way to really and truly "index" messages than this. Even the UID depends on the underlying index, but risks falling out of sync with the index in all the client/server roundtrips. Short of providing a best-effort type of strategy pattern resolving index-UID issues, how hard would it be to put a simple IMessageSpool interface in; one in which it was simply index-based and not UID-based. I've got logic in my service that depends on indexing as well; that will save me having to rip that out and replace with UID-based approach (for previously mentioned risks).
What is the best way to render the html with embedded images?
Currently I am downloading the attachments and changing the paths in the html to reference the local paths.
Is there a way to leave the src paths intact in the html and still correctly render the embedded images?
TBD: I am evaluating MailKit for fitness whether it will do what I need it to do; or at least be open enough for extensibility (i.e. along SOLID design principle guidelines). TBD whether there are any issues come up along these lines.
So far what I can determine is the index-UID issue (another issue) is fairly substantial. After that I look for obvious opportunities; virtualized methods and properties, abstract classes that need to be, non-sealed classes that don't need to be, things of this nature.
Possibly more to come...
Hi,
I installed MailKit using NuGet (0.9.0.0) and when I run the second sample code (IMAP) from https://github.com/jstedfast/MailKit I get an exception. I'm connecting to imap.gmail.com as in the sample.
Any idea what's going on?
foreach (var summary in inbox.Fetch (0, -1, MessageSummaryItems.Full, cancel.Token)) {
Console.WriteLine ("[summary] {0:D2}: {1}", summary.Index, summary.Envelope.Subject);
}
Unhandled Exception: MailKit.Net.Imap.ImapProtocolException: Unexpected token in IMAP response: ')'
at MailKit.Net.Imap.ImapUtils.ParseEnvelope(ImapEngine engine, CancellationToken cancellationToken)
at MailKit.Net.Imap.ImapUtils.ParseBody(ImapEngine engine, String path, CancellationToken cancellationToken)
at MailKit.Net.Imap.ImapUtils.ParseMultipart(ImapEngine engine, String path, CancellationToken cancellationToken)
at MailKit.Net.Imap.ImapUtils.ParseBody(ImapEngine engine, String path, CancellationToken cancellationToken)
at MailKit.Net.Imap.ImapFolder.FetchSummaryItems(ImapEngine engine, ImapCommand ic, Int32 index, ImapToken tok)
at MailKit.Net.Imap.ImapEngine.ProcessUntaggedResponse(CancellationToken cancellationToken)
at MailKit.Net.Imap.ImapCommand.Step()
at MailKit.Net.Imap.ImapEngine.Iterate()
at MailKit.Net.Imap.ImapEngine.Wait(ImapCommand ic)
at MailKit.Net.Imap.ImapFolder.Fetch(Int32 min, Int32 max, MessageSummaryItems items, CancellationToken cancellationToken)
at ConsoleApplication2.Program.Main(String[] args) in d:\Users\dranger003\Documents\Visual Studio 2013\Projects\ConsoleApplication2\ConsoleApplication2\Program.cs:line 33
Hello,
I tried installing MailKit to a Windows Phone 8.1 app using nuget, but I get the following error:
PM> Install-Package MailKit
Attempting to resolve dependency 'MimeKit (≥ 0.36.0.0)'.
Installing 'MimeKit 0.36.0.0'.
Successfully installed 'MimeKit 0.36.0.0'.
Installing 'MailKit 0.15.0.0'.
Successfully installed 'MailKit 0.15.0.0'.
Adding 'MimeKit 0.36.0.0' to TestProject.
Uninstalling 'MimeKit 0.36.0.0'.
Successfully uninstalled 'MimeKit 0.36.0.0'.
Install failed. Rolling back...
Install-Package : Could not install package 'MimeKit 0.36.0.0'. You are trying to install this package into a project that targets 'WindowsPhoneApp,Version=v8.1', but
the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author.
At line:1 char:1
+ Install-Package MailKit
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Install-Package], InvalidOperationException
+ FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PowerShell.Commands.InstallPackageCommand
I thought that MailKit supports Windows Phone 8.1 ? Or is it a MimeKit issue?
Hey Jeffrey,
I need your advice.
I have the label "[Mailbox]" in my Gmail.
If I request
FETCH 1 (X-GM-LABELS)
response will be:
1 FETCH (X-GM-LABELS ([Mailbox]))
but it should be:
1 FETCH (X-GM-LABELS ("[Mailbox]")), because [Mailbox] is not an atom.
So, MailKit throw exception when I try fetch messages with MessageSummaryItems.GMailLabels.
How do you think, is it possible to patch up this behavior?
I agree, that throwing exception is right. But I want to fetch thousands messages in one request and exception in one message kill all other messages.
Hi jstedfast,
first of all, great job, finally an email/mime lib that works :-).
Receiving following exception during IFolder.Open(MailKit.FolderAccess.ReadOnly, token):
{"Unexpected token in IMAP response: [atom: 0]"}
at MailKit.Net.Imap.ImapEngine.ParseResponseCode(CancellationToken cancellationToken)
at MailKit.Net.Imap.ImapEngine.ProcessUntaggedResponse(CancellationToken cancellationToken)
at MailKit.Net.Imap.ImapCommand.Step()
at MailKit.Net.Imap.ImapEngine.Iterate()
at MailKit.Net.Imap.ImapEngine.Wait(ImapCommand ic)
at MailKit.Net.Imap.ImapFolder.Open(FolderAccess access, CancellationToken cancellationToken)
Ouput from ProtocolLogger:
S: * OK IceWarp 11.0.0.1 x64 IMAP4rev1 Thu, 10 Apr 2014 22:30:56 +0200
C: B00000000 CAPABILITY
S: * CAPABILITY IMAP4rev1 AUTH=PLAIN AUTH=LOGIN AUTH=DIGEST-MD5 AUTH=CRAM-MD5 SORT THREAD=ORDEREDSUBJECT UIDPLUS QUOTA ACL NAMESPACE
CHILDREN IDLE ID UNSELECT METADATA X-ICEWARP-SERVER X-MOVE MSEARCH XLIST CREATE-SPECIAL-USE X-ICEWARP-PRIVATEBUSY STARTTLS
S: B00000000 OK CAPABILITY Completed
C: B00000001 STARTTLS
S: B00000001 OK STARTTLS Ready to start TLS
C: B00000002 CAPABILITY
S: * CAPABILITY IMAP4rev1 AUTH=PLAIN AUTH=LOGIN AUTH=DIGEST-MD5 AUTH=CRAM-MD5 SORT THREAD=ORDEREDSUBJECT UIDPLUS QUOTA ACL NAMESPACE
CHILDREN IDLE ID UNSELECT METADATA X-ICEWARP-SERVER X-MOVE MSEARCH XLIST CREATE-SPECIAL-USE X-ICEWARP-PRIVATEBUSY
S: B00000002 OK CAPABILITY Completed
C: B00000003 AUTHENTICATE DIGEST-MD5
S: B00000003 NO AUTHENTICATE Unknown user or incorrect password
C: B00000004 AUTHENTICATE CRAM-MD5
S: B00000004 NO AUTHENTICATE Unknown user or incorrect password
C: B00000005 AUTHENTICATE PLAIN
S: B00000005 OK AUTHENTICATE Completed
C: B00000006 CAPABILITY
S: * CAPABILITY IMAP4rev1 AUTH=PLAIN AUTH=LOGIN AUTH=DIGEST-MD5 AUTH=CRAM-MD5 SORT THREAD=ORDEREDSUBJECT UIDPLUS QUOTA ACL NAMESPACE
CHILDREN IDLE ID UNSELECT METADATA X-ICEWARP-SERVER X-MOVE MSEARCH XLIST CREATE-SPECIAL-USE X-ICEWARP-PRIVATEBUSY
S: B00000006 OK CAPABILITY Completed
C: B00000007 NAMESPACE
S: * NAMESPACE (("" "/")) (("~" "/")) NIL
S: B00000007 OK NAMESPACE Completed
C: B00000008 LIST "" "INBOX"
S: * LIST (\HasChildren) "/" "INBOX"
S: B00000008 OK LIST Completed
C: B00000009 XLIST "" "_"
S: B00000009 OK XLIST Completed
C: B00000010 EXAMINE INBOX
S: * FLAGS (\Seen \Answered \Flagged \Deleted \Draft \Recent $Forwarded $Redirected Junk NonJunk)
S: * 60 EXISTS
S: * 0 RECENT
S: * OK [UIDVALIDITY 1145271872] UID validity
S: * OK [UNSEEN 54] Message 54 is first unseen
S: * OK [UIDNEXT 388] Predicted next UID
S: * OK [PERMANENTFLAGS ( _)]
S: B00000010 OK [READ-ONLY] EXAMINE Completed
C: B00000011 FETCH 1:* (UID)
S: B00000011 OK FETCH Completed
C: B00000012 CLOSE
S: B00000012 OK CLOSE Completed
C: B00000013 EXAMINE Sent
S: * FLAGS (\Seen \Answered \Flagged \Deleted \Draft \Recent $Forwarded $Redirected Junk NonJunk)
S: * 0 EXISTS
S: * 0 RECENT
S: * OK [UIDVALIDITY 1149933314] UID validity
S: * OK [UNSEEN 0]
S: * OK [UIDNEXT 1] Predicted next UID
S: * OK [PERMANENTFLAGS ( *)]
S: B00000013 OK [READ-ONLY] EXAMINE Completed
Any hint how to fix this?
Thank you very much!
Tomas
I am trying to get the text from the body of a mail. If i use "part.Text" it throws the error in the title. If i use breakpoints I can see that the Text in the "part" object does have the correct value for the body text I want, but i can't get them using '.Text' .
foreach (var summary in client.Inbox.Fetch(0, -1, MessageSummaryItems.Full, cancel.Token))
{
var text = summary.Body as BodyPartText;
if (text == null)
{
var multipart = summary.Body as BodyPartMultipart;
if (multipart != null)
text = multipart.BodyParts.OfType<BodyPartText>().FirstOrDefault();
}
if (text == null)
continue;
// this will download *just* the text part
var part = client.Inbox.GetBodyPart(summary.Index, text, cancel.Token);
if (!db.Emails.Any(a => a._Hash == _hash))
{
// create table to store mails in
Table<Email> mails = db.GetTable<Email>();
//new instance of email object
Email mail = new Email();
//select columns in mails table equal to matching email entity
mail.User_Email = username;
mail.E_Type = "In";
mail.EmailGUID = Guid.NewGuid();
mail.IsRead = false; //summary.Flags.Value;
mail.Sender = _trimaddress;
mail.CC = summary.Envelope.Cc.ToString();
mail.DateReceived = summary.Envelope.Date.Value;
mail.E_Subject = summary.Envelope.Subject;
mail.Body = part.Text;
mail.HasAttachments = false;
mail.Replied = false;
mail._Hash = _hash;
mails.InsertOnSubmit(mail);
//submit changes to database
db.SubmitChanges();
}
}
P.S I stripped some of my own logic to shorten the post but it should not interfere with the problem. Sorry if I'm being silly but I'm relatively new to programming.
When I do the following search:
var unreadMessageIds = inbox.Search(SearchQuery.NotSeen, cancel.Token);
and the checked gmail inbox is empty, I get the following exception:
MailKit.Net.Imap.ImapProtocolException: Unexpected token in IMAP response: '\n'
at MailKit.Net.Imap.ImapFolder.ESearchMatches(ImapEngine engine, ImapCommand ic, Int32 index, ImapToken tok)
at MailKit.Net.Imap.ImapEngine.ProcessUntaggedResponse(CancellationToken cancellationToken)
at MailKit.Net.Imap.ImapCommand.Step()
at MailKit.Net.Imap.ImapEngine.Iterate()
at MailKit.Net.Imap.ImapEngine.Wait(ImapCommand ic)
at MailKit.Net.Imap.ImapFolder.Search(SearchQuery query, CancellationToken cancellationToken)
On Windows code following exactly the Pop3Client sample code from the home page hangs in this call (never returns or throws):
client.GetMessage(i, cancel.Token);
in the ReadAhead function at:
if ((nread = Stream.Read (input, start, end - start)) > 0)
unsafe int ReadAhead (byte* inbuf, int atleast)
{
int left = inputEnd - inputIndex;
left has a value of 0 in this case
I'll try to find out what's going on...
Hi Jeff,
I have a problem using IMAP and DIGEST-MD5 with my E-Mail Provider STRATO, because I get a NullReferenceException during authentication. If I remove the authentication mechanism "DIGEST-MD5", everything works well.
I have looked into the code and I think the problem is within the constructor of the class DigestResponse (file MailKit.Security.SaslMechanismDigestMd5.cs), because in my case the value of challenge.Realms of the parameter challenge is null. Therfore the if-statement at the beginning
if (challenge.Realms.Length > 0)
casues the exception. If I change the statement to
if ((challenge.Realms != null) && (challenge.Realms.Length > 0))
the authentication process succeed.
Hi there,
I'm using the MailKit.Net.Pop3 client to connect to gmail to download emails with inline images but the images and attachments in the emails are not downloading corrrectly. They seem to have the same sizes but when you view them they are corrupted. Please see below
Downloaded using MailKit.Net.Pop3:
Code used:
public void DownloadMessages()
{
using (var client = new Pop3Client())
{
var credentials = new NetworkCredential(EmailAddress, Password);
// Note: if the server requires SSL-on-connect, use the "pops" protocol instead
var uri = new Uri(string.Format("pop{0}://{1}:{2}", (UseSsl ? "s" : ""), Server, Port));
using (var cancel = new CancellationTokenSource())
{
client.Connect(uri, cancel.Token);
// Note: since we don't have an OAuth2 token, disable
// the XOAUTH2 authentication mechanism.
client.AuthenticationMechanisms.Remove("XOAUTH2");
client.Authenticate(credentials, cancel.Token);
int messageCount = client.GetMessageCount(cancel.Token);
for (var i = 0; i < messageCount; i++)
{
var msg = client.GetMessage(i, cancel.Token);
using (FileStream file = new FileStream("c:\\temp\\message" + i + ".eml", FileMode.Create, FileAccess.Write))
{
msg.WriteTo(file);
}
foreach (var attachment in msg.BodyParts.Where(p => p.ContentType.MediaType == "image" || p.IsAttachment))
{
using (FileStream file = new FileStream("c:\\temp\\message" + i + "-" + attachment.FileName, FileMode.Create, FileAccess.Write))
{
attachment.ContentObject.DecodeTo(file);
}
}
}
}
}
}
Any ideas why this is happening?
In a competing API, OpenPop, there is the ability to bridge to built-in MailMessage through ToMailMessage, through which Attachments are accessible. I am trying to use a new Attachments method, property (some way of accessing Attachments) via the NuGet package but this does not seem to have the latest code in the code base (yet).
Method
IEnumerable Fetch (UniqueId[] uids, MessageSummaryItems items, CancellationToken cancellationToken = default (CancellationToken));
works correctly only if uids are sorted ascending. Otherwise, ImapUtils.FormatUidSet returns wrong string.
I think, it must be noted in method description (or method FormatUidSet need be improoved)
When I construct a MimeMessage with a body containing several TextPart objects within a MultiPart object only the first TextPart gets displayed in the email body when the email is received. The other part is received as an attachment. This occurs when the email is received on GMail and on Outlook 2010.
Sample code:
var message = new MimeMessage();
message.To.Add(new MailboxAddress("Destination Name", "[email protected]"));
message.From.Add(new MailboxAddress("Sender Name", "[email protected]"));
message.Subject = "How you doin'?";
Multipart multiPart = new Multipart();
TextPart textPart = new TextPart();
textPart.ContentType.MediaSubtype = "plain";
textPart.ContentType.MediaType = "text";
";
textPart.IsAttachment = false;
multiPart.Add(textPart);
textPart = new TextPart();
textPart.ContentType.MediaSubtype = "plain";
textPart.ContentType.MediaType = "text";
";
textPart.IsAttachment = false;
multiPart.Add(textPart);
message.Body = multiPart;
using (var client = new SmtpClient())
{
var credentials = new NetworkCredential("name", "password");
var uri = new Uri("smtp://emailServer.com");
using (var cancel = new CancellationTokenSource())
{
client.Connect(uri, cancel.Token);
client.Authenticate(credentials, cancel.Token);
client.Send(message, cancel.Token);
client.Disconnect(true, cancel.Token);
}
}
I tried it with two different email account (2 different provider) and don't work.
The function ehlo can't get response.
Searching by header against Microsoft Exchange (2010) fails.
Apparently Exchange does not support UTF8 (http://lists.horde.org/archives/bugs/Week-of-Mon-20110815/057209.html)
Example:
var searchCondition = SearchQuery.Header("Message-Id", messageId);
var ids = _client.Inbox.Search(searchCondition, _cancellationToken);
ImapFolder.Search adds CHARSET UTF-8
:
if (args.Count > 0)
command += "CHARSET UTF-8 ";
From the log:
C: A00000006 UID SEARCH CHARSET UTF-8 HEADER Message-Id <[email protected]>
S: A00000006 NO [BADCHARSET (US-ASCII)] The specified charset is not supported.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.