Overview
Features
Download
Documentation
Community
Add-Ons & Services

Pop3 Server - Read Notification not received

Please post support and help requests here.

Pop3 Server - Read Notification not received

Postby srini2174 » 08 Sep 2008, 16:25

Hi,
First of all I would like to thank for the wonderful piece of library. I was looking for a library of this sort for a long time.

I am working on creating a POP3 server. For this I had taken the EchoServer sample provided and modified it according to my need. But when i run this code i am unable to get the Read notification at all.

Further I noticed that even when I run the EchoServer example the first character is never reproduced. Only the next characters are echoed back. I would greatly appreciate if anybody could help in resolving this issue.

Regards,
Srinivasan.B

Code: Select all

#include "Poco/Net/SocketReactor.h"
#include "Poco/Net/SocketAcceptor.h"
#include "Poco/Net/SocketNotification.h"
#include "Poco/Net/StreamSocket.h"
#include "Poco/Net/ServerSocket.h"
#include "Poco/Net/DialogSocket.h"
#include "Poco/Net/SocketAddress.h"
#include "Poco/NObserver.h"
#include "Poco/Timespan.h"
#include "Poco/StringTokenizer.h"
#include "Poco/Exception.h"
#include "Poco/Thread.h"
#include "Poco/Util/ServerApplication.h"
#include "Poco/Util/Option.h"
#include "Poco/Util/OptionSet.h"
#include "Poco/Util/HelpFormatter.h"
#include <iostream>


using Poco::Net::SocketReactor;
using Poco::Net::SocketAcceptor;
using Poco::Net::ReadableNotification;
using Poco::Net::ShutdownNotification;
using Poco::Net::WritableNotification;
using Poco::Net::ErrorNotification;
using Poco::Net::TimeoutNotification;
using Poco::Net::ServerSocket;
using Poco::Net::StreamSocket;
using Poco::NObserver;
using Poco::AutoPtr;
using Poco::Thread;
using Poco::Timespan;
using Poco::Util::ServerApplication;
using Poco::Util::Application;
using Poco::Util::Option;
using Poco::Util::OptionSet;
using Poco::Util::HelpFormatter;
using Poco::Net::DialogSocket;
using Poco::Net::SocketAddress;
using Poco::StringTokenizer;


class popServiceHandler
{
private:
   enum
   {
      BUFFER_SIZE = 1024
   };

   enum
   {
      RESET = 0,
      AUTHORIZATION =1,
      TRANSACTION = 2,
      UPDATE = 3
   } state;
   
   int have_username;
   std::string username;
   std::string extension;
   std::string password;
   DialogSocket   _socket;
   SocketReactor& _reactor;

public:
   popServiceHandler(StreamSocket& socket, SocketReactor& reactor):
      _socket(socket),
      _reactor(reactor),
      state(AUTHORIZATION)
   {
      Application& app = Application::instance();
      app.logger().information("Connection from " + socket.peerAddress().toString());
      app.logger().information("POP3 Server Ready for Authorization");

      Timespan interval(1,0);
      _reactor.setTimeout(interval);
      _reactor.addEventHandler(_socket, NObserver<popServiceHandler, ReadableNotification>(*this, &popServiceHandler::onReadable));
      //_reactor.addEventHandler(_socket, NObserver<popServiceHandler, WritableNotification>(*this, &popServiceHandler::onWritable));
      //_reactor.addEventHandler(_socket, NObserver<popServiceHandler, ErrorNotification>(*this, &popServiceHandler::onError));
      //_reactor.addEventHandler(_socket, NObserver<popServiceHandler, TimeoutNotification>(*this, &popServiceHandler::onTimeout));
      _reactor.addEventHandler(_socket, NObserver<popServiceHandler, ShutdownNotification>(*this, &popServiceHandler::onShutdown));
   }
   
   ~popServiceHandler()
   {
      Application& app = Application::instance();
      try
      {
         app.logger().information("Disconnecting " + _socket.peerAddress().toString());
      }
      catch (...)
      {
      }
      _reactor.removeEventHandler(_socket, NObserver<popServiceHandler, ReadableNotification>(*this, &popServiceHandler::onReadable));
      //_reactor.removeEventHandler(_socket, NObserver<popServiceHandler, WritableNotification>(*this, &popServiceHandler::onWritable));
      //_reactor.removeEventHandler(_socket, NObserver<popServiceHandler, ErrorNotification>(*this, &popServiceHandler::onError));
      //_reactor.removeEventHandler(_socket, NObserver<popServiceHandler, TimeoutNotification>(*this, &popServiceHandler::onTimeout));
      _reactor.removeEventHandler(_socket, NObserver<popServiceHandler, ShutdownNotification>(*this, &popServiceHandler::onShutdown));
      //delete [] _pBuffer;
   }

   //void onWritable(const AutoPtr<WritableNotification>& pNf)
   //{
   //   Application& app = Application::instance();
   //   app.logger().information("writable notification received");
   //   std::string msg = "+OK POP3 Server Ready";
   //}

   //void onError(const AutoPtr<ErrorNotification>& pNf)
   //{
   //   Application& app = Application::instance();
   //   app.logger().information("Error notification received");
   //}
   
   //void onTimeout(const AutoPtr<TimeoutNotification>& pNf)
   //{
   //   Application& app = Application::instance();
   //   app.logger().information("Timeout notification received");
   //}

   void onReadable(const AutoPtr<ReadableNotification>& pNf)
   {
      std::string msg = "";
      _socket.receiveMessage(msg);
      //int length = msg.length();
      if (parseLine(msg)){
         delete this;
      }
   }

   void sendOk(std::string line)
   {
        line = "+OK " + line;
      _socket.sendMessage(line);
        //logger.fine("+OK " + line);
    }

   void sendErr(std::string line) {
        line = "-ERR " + line;
      _socket.sendMessage(line);
        //logger.fine("-ERR " + line);
    }

   int parseLine(std::string line)
   {
      Application& app = Application::instance();
      if (line.length() == 0) {
         sendOk("Please Enter a valid POP3 COMMAND");
         return false;
      }

      StringTokenizer toker(line," ",2);

      /* Authorization state */
      /* USER */
      if (toker[0] == "USER") {         
         if (toker.count() == 2) {
            std::string login = toker[1];
            StringTokenizer extToker(login,"@",2);
            if (extToker.count() != 0) {
               username = extToker[0];
               extension = extToker[1];
               app.logger().information("Username: " + username);
               app.logger().information("Extension: " + extension);
               have_username = true;
               sendOk("user " + login + " accepted");
               return false;
            } else {
               sendErr(" please provide complete email address for username e.g. user@hotmail.com or user@yahoo.com");
               return false;
            }
         }
         else {
            sendErr("Syntax: USER user@abc.com");
            return false;         
         }
      }
      else if (toker[0] == "PASS") {         /* PASS */
         if (!have_username) {
            sendErr("please provide username first");
            return false;
         }
         if (toker.count() == 2) {
            password = toker[1];
            //   switch (wms.login(login, password, false)) {
            //      case WebMailSession.WMS_LOGIN_OK:
            //      // All is good,
            //      break;
            //   case WebMailSession.WMS_LOGIN_FAILED:
            //      sendErr("Authorization failed. See ya.");
            //      logger.warning("'" + usernameExtension + "': Login unsuccessful");
            //      return true;
            //   case WebMailSession.WMS_PAGE_STRUCTURE:
            //      sendErr("Unexpected remote webmail page structure. See ya.");
            //      logger.warning("'" + usernameExtension + "': Login unsuccessful");
            //      return true;
            //   default:
            //      sendErr("Unexpected remote webmail page structure. See ya.");
            //      logger.warning("'" + usernameExtension + "': Login unsuccessful");
            //      return true;
            //   }
            //   logger.info("'" + usernameExtension + "': Logged in ok");
            sendOk("password accepted");
            state = TRANSACTION;
            app.logger().information("Entering into transaction state");
            return false;
         }
         else {
            sendErr("Syntax: PASS xxxxxxxx");
            return false;         
         }   
      }
      else if (toker[0] == "QUIT") {   /* QUIT */
         sendOk("Good Bye");
         //logger.info("'" + usernameExtension + "': Logged out ok");
         return true;
      }
      else if (toker[0] == "NOOP") {   /* NOOP */
         if (state == TRANSACTION) {
            sendOk("whatever");
         } else {
            sendErr("not in transaction state");
         }
         return false;
      }
      else if (toker[0] == "RSET") { /* RSET */
         sendOk("");
         return false;   
      }
      else {
         sendErr("Command not supported or recognized");
      }
      return false;
   }

   void onShutdown(const AutoPtr<ShutdownNotification>& pNf)
   {
      delete this;
   }
   

};


class popServer: public Poco::Util::ServerApplication
{
public:
   popServer(): _helpRequested(false)
   {
   }
   
   ~popServer()
   {
   }

protected:
   void initialize(Application& self)
   {
      loadConfiguration(); // load default configuration files, if present
      ServerApplication::initialize(self);
   }
      
   void uninitialize()
   {
      ServerApplication::uninitialize();
   }

   void defineOptions(OptionSet& options)
   {
      ServerApplication::defineOptions(options);
      
      options.addOption(
         Option("help", "h", "display help information on command line arguments")
            .required(false)
            .repeatable(false));
   }

   void handleOption(const std::string& name, const std::string& value)
   {
      ServerApplication::handleOption(name, value);

      if (name == "help")
         _helpRequested = true;
   }

   void displayHelp()
   {
      HelpFormatter helpFormatter(options());
      helpFormatter.setCommand(commandName());
      helpFormatter.setUsage("OPTIONS");
      helpFormatter.setHeader("An echo server implemented using the Reactor and Acceptor patterns.");
      helpFormatter.format(std::cout);
   }

   int main(const std::vector<std::string>& args)
   {
      if (_helpRequested)
      {
         displayHelp();
      }
      else
      {
         // get parameters from configuration file
         unsigned short port = (unsigned short) config().getInt("popServer.port", 11110);

         const std::string HOST("127.0.0.1");
         const Timespan interval(10,0);
         SocketAddress sa(HOST, port);
         // set-up a server socket
         ServerSocket svs(sa);
         svs.setReceiveTimeout(interval);
         svs.setSendTimeout(interval);

         // set-up a SocketReactor...
         SocketReactor reactor;
         reactor.setTimeout(interval);

         // ... and a SocketAcceptor
         SocketAcceptor<popServiceHandler> acceptor(svs, reactor);

         // run the reactor in its own thread so that we can wait for
         // a termination request
         Thread thread;
         thread.start(reactor);
         this->logger().information("POP Server Ready");
         // wait for CTRL-C or kill
         waitForTerminationRequest();
         // Stop the SocketReactor
         reactor.stop();
         thread.join();
      }
      return Application::EXIT_OK;
   }
   
private:
   bool _helpRequested;
};


int main(int argc, char** argv)
{
   popServer app;
   return app.run(argc, argv);
}
srini2174
 
Posts: 5
Joined: 31 Aug 2008, 16:45
Location: India

Re: Pop3 Server - Read Notification not received

Postby srini2174 » 10 Sep 2008, 18:29

Hi,

Any help please. I am desperate for help on this topic. Is my approach to this problem a correct one.

Regards,

Srinivasan.B


> Hi,
> First of all I would like to thank for the wonderful piece of library. I was looking for a library of this sort for a long time.
>
> I am working on creating a POP3 server. For this I had taken the EchoServer sample provided and modified it according to my need. But when i run this code i am unable to get the Read notification at all.
>
> Further I noticed that even when I run the EchoServer example the first character is never reproduced. Only the next characters are echoed back. I would greatly appreciate if anybody could help in resolving this issue.
>
> Regards,
> Srinivasan.B
>
srini2174
 
Posts: 5
Joined: 31 Aug 2008, 16:45
Location: India

Re: Pop3 Server - Read Notification not received

Postby alex » 10 Sep 2008, 20:09

> I am working on creating a POP3 server. For this I had taken the EchoServer sample provided and modified it according to my need. But when i run this code i am unable to get the Read notification at all.

I can not reproduce your problem. The first character I type into telnet client ends up in the breakpoint in popServiceHandler::onReadable().

Bear in mind that DialogSocket operates on lines terminated by CR-LF.

> Further I noticed that even when I run the EchoServer example the first character is never reproduced. Only the next characters are echoed back. I would greatly appreciate if anybody could help in resolving this issue.

I could not reproduce this either. The very first character typed in telnet client ends up in the onReadable(). For whatever reason, some telnet clients (e.g. windows) do not display the first character typed on the client side, which may have mislead you.

So, I don't see a problem with your code or the sample. Also, in the future when posting, please try to keep your code concise and to the point. It helps to get the answer sooner.

Alex
alex
 
Posts: 1132
Joined: 11 Jul 2006, 16:27
Location: United_States

Re: Pop3 Server - Read Notification not received

Postby srini2174 » 11 Sep 2008, 18:33

Hi,

I am still struggling to get this code working. How can I attach a screenshot in this forum? I would try to capture the telnet window and post it in the forum.

I tried connecting from thunderbird as well with the pop3 port set to localhost port. But I do not get into the OnReadable() method.

Regards,
Srinivasan.B
srini2174
 
Posts: 5
Joined: 31 Aug 2008, 16:45
Location: India

Re: Re: Pop3 Server - Read Notification not received

Postby alex » 11 Sep 2008, 19:28

> I am still struggling to get this code working. How can I attach a screenshot in this forum? I would try to capture the telnet window and post it in the forum.

I don't see how problem could be in the window frame, so what's wrong with copy-pasting the text from the window (although I'm not sure what should I be able to conclude from that, either) ?

Alex
alex
 
Posts: 1132
Joined: 11 Jul 2006, 16:27
Location: United_States

Re: Pop3 Server - Read Notification not received

Postby srini2174 » 12 Sep 2008, 17:49

Hi Alex,

Thanks for your effort in helping me resolve this. Now I am able to get the ReadNotification when I do it from the telnet window. But still if I try to connect it from Thunderbird or any other POP3Client (I have a code in C#) I am unable to get into the OnReadable method. Thunderbird / Pop3 client just hangs.

Further even when I do it with a telnet I am unable to see just the first command I type in the window. Once I receive the message back through the SendMessge call then onwards I am able to see the commands I type on the telnet window. This is just I want to show in the screenshot.

I hope that you would be able to reproduce this issue with the thunderbird mail client.

Regards,
Srinivasan.B
srini2174
 
Posts: 5
Joined: 31 Aug 2008, 16:45
Location: India

Re: Re: Pop3 Server - Read Notification not received

Postby alex » 15 Sep 2008, 11:17

Srinivasan,

> I hope that you would be able to reproduce this issue with the thunderbird mail client.

I am sorry, but I don't think I'll be able to find time in order to provide further help for your problem, at least not in the near future. Maybe someone else may jump in here and help. If this is a commercial project and you need immediate answer, you may want to get some paid help (Applied Informatics offers support contracts for POCO).

Regards,

Alex
alex
 
Posts: 1132
Joined: 11 Jul 2006, 16:27
Location: United_States

Re: Pop3 Server - Read Notification not received

Postby srini2174 » 18 Sep 2008, 17:28

Hi WITTROCK,

Thanks for that. That one really helped me. Now it works after giving the OK message from the Pop server.

Regards,
Srinivasan.B
srini2174
 
Posts: 5
Joined: 31 Aug 2008, 16:45
Location: India


Return to Support

Who is online

Users browsing this forum: No registered users and 2 guests