Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

EWS Mail Notifier

, 19 Apr 2010 CPOL
Simple mail notifier for Exchange
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Web;
using System.Collections;
using System.Threading;
using Microsoft.Web.Services3;
using Microsoft.Web.Services3.Addressing;
using Microsoft.Web.Services3.Messaging;
using System.Xml.Serialization;
using System.Xml;

namespace EWSConsoleNotify
{
  enum RState
   {
      METHOD, URL, URLPARM, URLVALUE, VERSION, 
      HEADERKEY, HEADERVALUE, BODY, OK
   };

   enum RespState
   {
      OK = 200, 
      BAD_REQUEST = 400,
      NOT_FOUND = 404
   }

   public struct HTTPRequestStruct
   {
      public string Method;
      public string URL;
      public string Version;
      public Hashtable Args;
      public bool Execute;
      public Hashtable Headers;
      public int BodySize;
      public byte[] BodyData;
   }

   public struct HTTPResponseStruct
   {
      public int status;
      public string version;
      public Hashtable Headers;
      public int BodySize;
      public byte[] BodyData;
   }

   /// <SUMMARY>

   /// Summary description for CsHTTPRequest.

   /// </SUMMARY>

   public class CSHTTPRequest
   {
       private TcpClient _client;

       private RState _parserState;

       private HTTPRequestStruct _httpRequest;

       private HTTPResponseStruct _httpResponse;

       private SendNotificationResultType _result;

       private Notify _parent;
       
       byte[] myReadBuffer;


       public CSHTTPRequest(TcpClient Client, Notify Parent)
       {
           _client = Client;
           _parent = Parent;

           _httpResponse.BodySize = 0;
       }

       public void Process()
       {
           
           myReadBuffer = new byte[_client.ReceiveBufferSize];
           String myCompleteMessage = "";
           int numberOfBytesRead = 0;

           NetworkStream ns = _client.GetStream();

           string hValue = "";
           string hKey = "";

           try
           {
               // binary data buffer index

               int bfndx = 0;

               // Incoming message may be larger than the buffer size.

               do
               {
                   numberOfBytesRead = ns.Read(myReadBuffer, 0,
                                               myReadBuffer.Length);
                   myCompleteMessage =
                      String.Concat(myCompleteMessage,
                         Encoding.ASCII.GetString(myReadBuffer, 0,
                                                  numberOfBytesRead));

                   // read buffer index

                   int ndx = 0;
                   do
                   {
                       switch (_parserState)
                       {
                           case RState.METHOD:
                               if (myReadBuffer[ndx] != ' ')
                                   _httpRequest.Method += (char)myReadBuffer[ndx++];
                               else
                               {
                                   ndx++;
                                   _parserState = RState.URL;
                               }
                               break;
                           case RState.URL:
                               if (myReadBuffer[ndx] == '?')
                               {
                                   ndx++;
                                   hKey = "";
                                   _httpRequest.Execute = true;
                                   _httpRequest.Args = new Hashtable();
                                   _parserState = RState.URLPARM;
                               }
                               else if (myReadBuffer[ndx] != ' ')
                                   _httpRequest.URL += (char)myReadBuffer[ndx++];
                               else
                               {
                                   ndx++;
                                   _httpRequest.URL
                                            = HttpUtility.UrlDecode(_httpRequest.URL);
                                   _parserState = RState.VERSION;
                               }
                               break;
                           case RState.URLPARM:
                               if (myReadBuffer[ndx] == '=')
                               {
                                   ndx++;
                                   hValue = "";
                                   _parserState = RState.URLVALUE;
                               }
                               else if (myReadBuffer[ndx] == ' ')
                               {
                                   ndx++;

                                   _httpRequest.URL
                                            = HttpUtility.UrlDecode(_httpRequest.URL);
                                   _parserState = RState.VERSION;
                               }
                               else
                               {
                                   hKey += (char)myReadBuffer[ndx++];
                               }
                               break;
                           case RState.URLVALUE:
                               if (myReadBuffer[ndx] == '&')
                               {
                                   ndx++;
                                   hKey = HttpUtility.UrlDecode(hKey);
                                   hValue = HttpUtility.UrlDecode(hValue);
                                   _httpRequest.Args[hKey] =
                                        _httpRequest.Args[hKey] != null ?
                                            _httpRequest.Args[hKey] + ", " + hValue :
                                            hValue;
                                   hKey = "";
                                   _parserState = RState.URLPARM;
                               }
                               else if (myReadBuffer[ndx] == ' ')
                               {
                                   ndx++;
                                   hKey = HttpUtility.UrlDecode(hKey);
                                   hValue = HttpUtility.UrlDecode(hValue);
                                   _httpRequest.Args[hKey] =
                                        _httpRequest.Args[hKey] != null ?
                                           _httpRequest.Args[hKey] + ", " + hValue :
                                           hValue;

                                   _httpRequest.URL
                                           = HttpUtility.UrlDecode(_httpRequest.URL);
                                   _parserState = RState.VERSION;
                               }
                               else
                               {
                                   hValue += (char)myReadBuffer[ndx++];
                               }
                               break;
                           case RState.VERSION:
                               if (myReadBuffer[ndx] == '\r')
                                   ndx++;
                               else if (myReadBuffer[ndx] != '\n')
                                   _httpRequest.Version += (char)myReadBuffer[ndx++];
                               else
                               {
                                   ndx++;
                                   hKey = "";
                                   _httpRequest.Headers = new Hashtable();
                                   _parserState = RState.HEADERKEY;
                               }
                               break;
                           case RState.HEADERKEY:
                               if (myReadBuffer[ndx] == '\r')
                                   ndx++;
                               else if (myReadBuffer[ndx] == '\n')
                               {
                                   ndx++;
                                   if (_httpRequest.Headers["Content-Length"] != null)
                                   {
                                       _httpRequest.BodySize =
                                Convert.ToInt32(_httpRequest.Headers["Content-Length"]);
                                       _httpRequest.BodyData
                                                = new byte[_httpRequest.BodySize];
                                       _parserState = RState.BODY;
                                   }
                                   else
                                       _parserState = RState.OK;

                               }
                               else if (myReadBuffer[ndx] == ':')
                                   ndx++;
                               else if (myReadBuffer[ndx] != ' ')
                                   hKey += (char)myReadBuffer[ndx++];
                               else
                               {
                                   ndx++;
                                   hValue = "";
                                   _parserState = RState.HEADERVALUE;
                               }
                               break;
                           case RState.HEADERVALUE:
                               if (myReadBuffer[ndx] == '\r')
                                   ndx++;
                               else if (myReadBuffer[ndx] != '\n')
                                   hValue += (char)myReadBuffer[ndx++];
                               else
                               {
                                   ndx++;
                                   _httpRequest.Headers.Add(hKey, hValue);
                                   hKey = "";
                                   _parserState = RState.HEADERKEY;
                               }
                               break;
                           case RState.BODY:
                               // Append to request BodyData

                               Array.Copy(myReadBuffer, ndx,
                                  _httpRequest.BodyData,
                                  bfndx, numberOfBytesRead - ndx);
                               bfndx += numberOfBytesRead - ndx;
                               ndx = numberOfBytesRead;
                               if (_httpRequest.BodySize <= bfndx)
                               {
                                   _parserState = RState.OK;
                               }
                               break;
                           //default:

                           //   ndx++;

                           //   break;


                       }
                   }
                   while (ndx < numberOfBytesRead);

                   Thread.Sleep(500);
               }
               while (ns.DataAvailable);

               if (_httpRequest.BodyData != null)
               {

                   string soapMessage = Encoding.ASCII.GetString(_httpRequest.BodyData);

                   ParseBody(soapMessage);

                   MemoryStream ms = new MemoryStream();

                   XmlSerializer mySerializer = new XmlSerializer(_result.GetType());
                   mySerializer.Serialize(ms, _result);

                   // Send the result
                   _httpResponse.version = "HTTP/1.1";
                   _httpResponse.BodyData = ms.ToArray();

                   _httpResponse.Headers = new Hashtable();
                   _httpResponse.Headers.Add("Server", _parent.Name);
                   _httpResponse.Headers.Add("Date", DateTime.Now.ToString("r"));
                   _httpResponse.Headers.Add("Content-Type", "text/xml; charset=utf-8");
                   _httpResponse.Headers.Add("Content-Length", _httpResponse.BodyData.Length);
                   _httpResponse.Headers.Add("Connection", "close");


                   string HeadersString = _httpResponse.version + " "
                      + "200 OK" + "\r\n";

                   foreach (DictionaryEntry Header in _httpResponse.Headers)
                   {
                       HeadersString += Header.Key + ": " + Header.Value + "\r\n";
                   }

                   HeadersString += "\r\n";

                   byte[] bHeadersString = Encoding.ASCII.GetBytes(HeadersString);

                   // Send headers   
                   ns.Write(bHeadersString, 0, bHeadersString.Length);


                   // Send body
                   if (_httpResponse.BodyData != null)
                       ns.Write(_httpResponse.BodyData, 0,
                                _httpResponse.BodyData.Length);


               }
           }
         catch (Exception e) 
         {
            _parent.WriteLog(e.ToString());
         }
         finally 
         {
            ns.Close();
            _client.Close();
         }
      }

       private void ParseBody(string Body)
       {
           
           SoapEnvelope soapEnvelope = new SoapEnvelope();
                   
           soapEnvelope.InnerXml = Body;
           
           Type type = typeof(SendNotificationResponseType);

           XmlRootAttribute xRoot = new XmlRootAttribute();
           xRoot.ElementName = "SendNotification";
           xRoot.Namespace = "http://schemas.microsoft.com/exchange/services/2006/messages";
           XmlSerializer serializer = new XmlSerializer(type, xRoot);
           XmlNodeReader reader = new XmlNodeReader(soapEnvelope.Body.FirstChild);


           SendNotificationResponseType obj = (SendNotificationResponseType)serializer.Deserialize(reader);

           if (obj.ResponseMessages != null)
           {
               PushNotification pn = new PushNotification(_parent);

               _result = pn.ProcessNotification(obj);

           }

       }

   }



}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

avg360
Software Developer
Spain Spain
MCTS: .NET Framework 3.5 ASP.NET Applications

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.1411023.1 | Last Updated 19 Apr 2010
Article Copyright 2010 by avg360
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid