2

I am trying to write a simple POP3 client for gmail in node.js. I initially wrote one where I enter the POP3 commands and they get sent to the server, and the server responds. This works fine because I can wait for the server's response before entering the next command.

But I want to make an automated conversation, where the program itself sends the commands and awaits its own responses. Simply doing:

stream.write('USER ***&@gmail.com');
stream.write('PASS *****');
stream.write('LIST');

doesn't work, because of the asynchronous nature of streams in node. I have to wait for the stream's 'data' event before sending the next message, otherwise, nothing happens at all. So tried it like this:

var tls =require ('tls');

var stream = tls.connect(995,'pop.gmail.com', function() {
    console.log ('Conexion establecida');
});

stream.on('data', function(data)
{
    var str = data.toString();
    console.log(str.substr(0,14));
    if(str.substr(0,14)=="+OK Gpop ready")
    {
        console.log('Sending username...');
        process.nextTick(function() {
            stream.write ('USER ***********@gmail.com');
        });
    }

    if(str.substr(0,14)=="+OK send PASS")
    {
        console.log('Recieving list of email...');
        process.nextTick(function(){
            stream.write('PASS *********');
        });
    }
});

The idea is that the 'data' event listener handles the sending of the next command depending on the last reply recieved. Again, doing stream.write alone did not seem to work, so I wrapped the write() calls in process.nextTick() calls. It seems that the USER command is sent, but never the PASS command. Can someone tell me why? Or if there is a more effective way to do this? Thanks for any information.

WiredPrairie
  • 58,954
  • 17
  • 116
  • 143
tutiplain
  • 1,427
  • 4
  • 19
  • 37
  • fyi: `substr` second parameter is length. You've only got `13` characters, yet are comparing `14`. – WiredPrairie Oct 20 '13 at 13:52
  • Thanks for that, but even after fixing it, nothing is being sent, still. – tutiplain Oct 20 '13 at 16:58
  • I tried it and get back `-ERR bad command` after sending the `USER` – WiredPrairie Oct 20 '13 at 17:06
  • In my case, the only reply I got from the server was the original "+OK Gpop is ready for requests message". After sending USER, nothing else happens, not even an error message. Note, I've tried this code on two different machines on different places with the same result. It is definitely not a firewall issue. Also, I made a client in which you enter the commands at the console and it sends them. This works fine on both locations. – tutiplain Oct 20 '13 at 19:10

2 Answers2

1

Your commands are being sent, however they are not being recognized, as they are missing the newline character, which denotes the end of a command. Adding a newline character to the end of your commands should get it working.

Additionally, you can simplify your commands by implementing a queue like so:

var tls = require('tls');
var commands = [];

commands.push('USER ***********@gmail.com\n');
commands.push('PASS *********\n');

var stream = tls.connect(995, 'pop.gmail.com', function () {
    console.log('Conexion establecida');
});

stream.on('data', function (data) {
    if (data.toString().indexOf('OK') > -1 && commands.length) {
        stream.write(commands.shift());
    }
});
levi
  • 23,693
  • 18
  • 59
  • 73
  • This doesn't seem to work. I added `console.log(data.toString())` at the beginning of the data event to see what is happening. Only the first messsage (+OK Gpop ready...) is being recieved. – tutiplain Oct 20 '13 at 17:12
  • Thanks! I was missing the new line character, just like you said. Now it's working. – tutiplain Oct 21 '13 at 00:36
0

Without seeing all the code, it is a bit difficult to answer.

However I noticed that in your first example, you write

stream.write('USER *&@gmail.com');

with an ampersand "&"

However in the second example there is no ampersand - could that be the source of the issue?

GMauro
  • 111
  • 1
  • 3