I wanted to send an email from my desktop using a simple Ruby program.
I installed 1st SMTP Server
(http://www.emailarms.com/products/1st_smtp.html\) - an easy to use
SMTP mail relay server. It is used for relaying your email messages to
its destinations quickly and easily. For this server, I need to use
localhost and port 25 on my PC.
Then the program I wrote was (based on RFC 821) -
require 'socket'
t = TCPSocket.new('localhost', 25)
puts t.gets
t.puts 'HELO Welcome from Ruby'
puts t.gets
t.puts 'MAIL FROM:<abc@gmail.com>'
puts t.gets
t.puts 'RCPT TO:<abc@gmail.com>'
puts t.gets
t.puts 'DATA'
puts t.gets
t.puts 'Test Email from Ruby'
t.puts "\r\n.\r\n"
puts t.gets
t.puts 'QUIT'
puts t.gets
t.close
However, while running the program, I get an error as follows:
220 Welcome to the 1st SMTP Server
250 Hello Welcome from Ruby
250 abc@gmail.com Address Okay
250 abc@gmail.com Address Okay
354 Start mail input; end with <CRLF>.<CRLF>
nil
email.rb:15:in `write': Invalid argument (Errno::EINVAL)
from email.rb:15:in `puts'
from email.rb:15
Exit code: 1
I am unable to figure out what the problem is. All help appreciated.
This line:
t.puts "\r\n.\r\n"
puts one more linefeed on the output than you perhaps intended, which
may account for the nil in your output. The QUIT command may be
causing the localhost server-connection to close before your process
has a chance to read the input. Meaning that the EINVAL error is
generated by the gets call you make right after sending QUIT.
Try the same program with a mail server located on a different machine
and see if you get a different result. After sending QUIT on an SMTP
connection, you don't really need to read the server response. (Unless
you suspect for some reason the server will send an interesting
error-response to your QUIT, which I've never seen in many years of
working with SMTP servers.)
···
On 7/30/06, Satish Talim <satish.talim@gmail.com> wrote:
I wanted to send an email from my desktop using a simple Ruby program.
I installed 1st SMTP Server
(http://www.emailarms.com/products/1st_smtp.html\) - an easy to use
SMTP mail relay server. It is used for relaying your email messages to
its destinations quickly and easily. For this server, I need to use
localhost and port 25 on my PC.
Then the program I wrote was (based on RFC 821) -
require 'socket'
t = TCPSocket.new('localhost', 25)
puts t.gets
t.puts 'HELO Welcome from Ruby'
puts t.gets
t.puts 'MAIL FROM:<abc@gmail.com>'
puts t.gets
t.puts 'RCPT TO:<abc@gmail.com>'
puts t.gets
t.puts 'DATA'
puts t.gets
t.puts 'Test Email from Ruby'
t.puts "\r\n.\r\n"
puts t.gets
t.puts 'QUIT'
puts t.gets
t.close
However, while running the program, I get an error as follows:
220 Welcome to the 1st SMTP Server
250 Hello Welcome from Ruby
250 abc@gmail.com Address Okay
250 abc@gmail.com Address Okay
354 Start mail input; end with <CRLF>.<CRLF>
nil
email.rb:15:in `write': Invalid argument (Errno::EINVAL)
from email.rb:15:in `puts'
from email.rb:15
>Exit code: 1
I am unable to figure out what the problem is. All help appreciated.
"Satish Talim" <satish.talim@gmail.com> writes:
I wanted to send an email from my desktop using a simple Ruby program.
I installed 1st SMTP Server
(http://www.emailarms.com/products/1st_smtp.html\) - an easy to use
SMTP mail relay server. It is used for relaying your email messages to
its destinations quickly and easily. For this server, I need to use
localhost and port 25 on my PC.
Then the program I wrote was (based on RFC 821) -
require 'socket'
t = TCPSocket.new('localhost', 25)
puts t.gets
t.puts 'HELO Welcome from Ruby'
puts t.gets
t.puts 'MAIL FROM:<abc@gmail.com>'
puts t.gets
t.puts 'RCPT TO:<abc@gmail.com>'
puts t.gets
t.puts 'DATA'
puts t.gets
t.puts 'Test Email from Ruby'
t.puts "test email from ruby\r\n"
···
t.puts "\r\n.\r\n"
puts t.gets
t.puts 'QUIT'
puts t.gets
t.close
However, while running the program, I get an error as follows:
220 Welcome to the 1st SMTP Server
250 Hello Welcome from Ruby
250 abc@gmail.com Address Okay
250 abc@gmail.com Address Okay
354 Start mail input; end with <CRLF>.<CRLF>
nil
email.rb:15:in `write': Invalid argument (Errno::EINVAL)
from email.rb:15:in `puts'
from email.rb:15
Exit code: 1
I am unable to figure out what the problem is. All help appreciated.
Satish Talim wrote:
> t.puts 'DATA'
puts t.gets
t.puts 'Test Email from Ruby'
t.puts "\r\n.\r\n"
Ok, so obviously you're not sending a normal RFC-822 header here. Is it
possible that your SMTP server is so strict about this that it closes
the connection silently?
···
--
Posted via http://www.ruby-forum.com/\.
One more thing that affects localhost connections. I like to avoid
puts(some_line) in favor of write("#{some_line}\r\n") because on many
kernels, the latter will result in one kernel-crossing system call while the
former results in two. I haven't investigated but I suspect this is caused
by an implementation detail in Ruby.
···
On 7/30/06, Francis Cianfrocca <garbagecat10@gmail.com> wrote:
This line:
t.puts "\r\n.\r\n"
puts one more linefeed on the output than you perhaps intended, which
may account for the nil in your output. The QUIT command may be
causing the localhost server-connection to close before your process
has a chance to read the input. Meaning that the EINVAL error is
generated by the gets call you make right after sending QUIT.
Try the same program with a mail server located on a different machine
and see if you get a different result. After sending QUIT on an SMTP
connection, you don't really need to read the server response. (Unless
you suspect for some reason the server will send an interesting
error-response to your QUIT, which I've never seen in many years of
working with SMTP servers.)
On 7/30/06, Satish Talim <satish.talim@gmail.com> wrote:
> I wanted to send an email from my desktop using a simple Ruby program.
> I installed 1st SMTP Server
> (http://www.emailarms.com/products/1st_smtp.html\) - an easy to use
> SMTP mail relay server. It is used for relaying your email messages to
> its destinations quickly and easily. For this server, I need to use
> localhost and port 25 on my PC.
>
> Then the program I wrote was (based on RFC 821) -
>
> require 'socket'
> t = TCPSocket.new('localhost', 25)
> puts t.gets
> t.puts 'HELO Welcome from Ruby'
> puts t.gets
> t.puts 'MAIL FROM:<abc@gmail.com>'
> puts t.gets
> t.puts 'RCPT TO:<abc@gmail.com>'
> puts t.gets
> t.puts 'DATA'
> puts t.gets
> t.puts 'Test Email from Ruby'
> t.puts "\r\n.\r\n"
> puts t.gets
> t.puts 'QUIT'
> puts t.gets
> t.close
>
> However, while running the program, I get an error as follows:
>
> 220 Welcome to the 1st SMTP Server
>
> 250 Hello Welcome from Ruby
>
> 250 abc@gmail.com Address Okay
>
> 250 abc@gmail.com Address Okay
>
> 354 Start mail input; end with <CRLF>.<CRLF>
>
> nil
> email.rb:15:in `write': Invalid argument (Errno::EINVAL)
> from email.rb:15:in `puts'
> from email.rb:15
> >Exit code: 1
>
> I am unable to figure out what the problem is. All help appreciated.
>
I tried the various suggestions given by Francis and Yohanes, but still it
does not work.
The executable code now is:
require 'socket'
t = TCPSocket.new('localhost', 25)
puts t.gets
t.puts "HELO Welcome from Ruby\r\n"
puts t.gets
t.puts "MAIL FROM:<satish_talim@yahoo.com>\r\n"
puts t.gets
t.puts "RCPT TO:<satish.talim@gmail.com>\r\n"
puts t.gets
t.puts 'DATA'
puts t.gets
t.puts "Test email from ruby\r\n"
t.puts "\r\n.\r\n"
t.puts 'QUIT'
puts t.gets
t.close
and the output is:
ruby email.rb
220 Welcome to the 1st SMTP Server
250 Hello Welcome from Ruby
250 satish_talim@yahoo.com Address Okay
250 satish.talim@gmail.com Address Okay
354 Start mail input; end with <CRLF>.<CRLF>
nil
Exit code: 0
I'd appreciate any other suggestions. Incidentally, if I write a program
using the Net::SMTP class, I am able to send off emails with my current
configuration.
···
On 7/31/06, Francis Cianfrocca <garbagecat10@gmail.com> wrote:
Satish Talim wrote:
> t.puts 'DATA'
> puts t.gets
> t.puts 'Test Email from Ruby'
> t.puts "\r\n.\r\n"
Ok, so obviously you're not sending a normal RFC-822 header here. Is it
possible that your SMTP server is so strict about this that it closes
the connection silently?
--
Posted via http://www.ruby-forum.com/\.
--
Satish Talim
http://www.puneruby.com/blog/
"Satish Talim" <satish.talim@gmail.com> writes:
I tried the various suggestions given by Francis and Yohanes, but still it
does not work.
The executable code now is:
require 'socket'
t = TCPSocket.new('localhost', 25)
puts t.gets
t.puts "HELO Welcome from Ruby\r\n"
puts t.gets
t.puts "MAIL FROM:<satish_talim@yahoo.com>\r\n"
puts t.gets
t.puts "RCPT TO:<satish.talim@gmail.com>\r\n"
puts t.gets
t.puts 'DATA'
puts t.gets
t.puts "Test email from ruby\r\n"
t.puts "\r\n.\r\n"
t.puts 'QUIT'
puts t.gets
t.close
and the output is:
ruby email.rb
220 Welcome to the 1st SMTP Server
250 Hello Welcome from Ruby
250 satish_talim@yahoo.com Address Okay
250 satish.talim@gmail.com Address Okay
354 Start mail input; end with <CRLF>.<CRLF>
nil
Exit code: 0
/tmp $ ruby try.rb
220 jenny-gnome.dyndns.org ESMTP
250 jenny-gnome.dyndns.org
250 ok
250 ok
354 go ahead
250 ok 1154319423 qp 25461
/tmp $
What is your SMTP server?
I'd appreciate any other suggestions. Incidentally, if I write a program
using the Net::SMTP class, I am able to send off emails with my current
configuration.
Please paste this code that uses Net::SMTP.
YS.
Satish Talim wrote:
I tried the various suggestions given by Francis and Yohanes, but still
it
does not work.
What happens if you simply telnet to the SMTP server and enter all of
the commands interactively? And, based on your last code framgment, you
haven't cleaned up all the extra linefeeds you're sending. Change puts
to write throughout, and change "QUIT" to "QUIT\r\n"
Also, your Net::SMTP fragment uses authentication and your socket-code
fragment does not. Although most mail servers would give a recognizable
error msg if they required auth.
···
--
Posted via http://www.ruby-forum.com/\.
Like I said before I am using a relay SMTP server called 1st SMTP server on
my Windows XP. The code using TCPSocket does not do authenticate and as such
I am not using our actual SMTP server.
Since you asked for the code using Net::SMTP class, I have pasted it here -
# rubysmtp.rb
require 'net/smtp'
user_from = "abc@puneruby.com"
user_to = "abc@gmail.com"
the_email = "From: abc@puneruby.com\nSubject: Hello\n\nEmail by Ruby.\n\n"
# handling exceptions
begin
Net::SMTP.start('auth.smtp.1and1.co.uk', 25, 'auth.smtp.1and1.co.uk',
'abc@puneruby.com', 'password', :login) do
smtpclient>
smtpclient.send_message(the_email, user_from, user_to)
end
rescue Exception => e
print "Exception occured: " + e
end
···
On 7/31/06, Yohanes Santoso <ysantoso-rubytalk@dessyku.is-a-geek.org> wrote:
"Satish Talim" <satish.talim@gmail.com> writes:
> I tried the various suggestions given by Francis and Yohanes, but still
it
> does not work.
>
> The executable code now is:
>
> require 'socket'
> t = TCPSocket.new('localhost', 25)
> puts t.gets
> t.puts "HELO Welcome from Ruby\r\n"
> puts t.gets
> t.puts "MAIL FROM:<satish_talim@yahoo.com>\r\n"
> puts t.gets
> t.puts "RCPT TO:<satish.talim@gmail.com>\r\n"
> puts t.gets
> t.puts 'DATA'
> puts t.gets
> t.puts "Test email from ruby\r\n"
> t.puts "\r\n.\r\n"
> t.puts 'QUIT'
> puts t.gets
> t.close
>
> and the output is:
>
>>ruby email.rb
> 220 Welcome to the 1st SMTP Server
>
> 250 Hello Welcome from Ruby
>
> 250 satish_talim@yahoo.com Address Okay
>
> 250 satish.talim@gmail.com Address Okay
>
> 354 Start mail input; end with <CRLF>.<CRLF>
>
> nil
>>Exit code: 0
/tmp $ ruby try.rb
220 jenny-gnome.dyndns.org ESMTP
250 jenny-gnome.dyndns.org
250 ok
354 go ahead
250 ok 1154319423 qp 25461
/tmp $
What is your SMTP server?
> I'd appreciate any other suggestions. Incidentally, if I write a program
> using the Net::SMTP class, I am able to send off emails with my current
> configuration.
Please paste this code that uses Net::SMTP.
YS.
--
Satish Talim
http://www.puneruby.com/blog/
I used Telnet and it got stuck when I typed . to stop the DATA. What change
do I need to make in the TCPSocket code for authentication?
···
On 7/31/06, Francis Cianfrocca <garbagecat10@gmail.com> wrote:
Satish Talim wrote:
> I tried the various suggestions given by Francis and Yohanes, but still
> it
> does not work.
>
What happens if you simply telnet to the SMTP server and enter all of
the commands interactively? And, based on your last code framgment, you
haven't cleaned up all the extra linefeeds you're sending. Change puts
to write throughout, and change "QUIT" to "QUIT\r\n"
Also, your Net::SMTP fragment uses authentication and your socket-code
fragment does not. Although most mail servers would give a recognizable
error msg if they required auth.
--
Posted via http://www.ruby-forum.com/\.
--
Satish Talim
http://www.puneruby.com/blog/
Satish Talim wrote:
I used Telnet and it got stuck when I typed . to stop the DATA. What
change
do I need to make in the TCPSocket code for authentication?
What does "got stuck" mean? Did it give an error message? Did it close
the connection? Did it hang? Show us a screenshot of the telnet
conversation.
···
--
Posted via http://www.ruby-forum.com/\.
"Satish Talim" <satish.talim@gmail.com> writes:
Like I said before I am using a relay SMTP server called 1st SMTP server on
my Windows XP. The code using TCPSocket does not do authenticate and as such
I am not using our actual SMTP server.
Could it be that the SMTP server (relay or not), does a running
verification for the content of the data?
That is, if the data is not in RFC822 format, then it aborts the
connection ungracefully.
Or, could it be aborting the connection because you don't authenticate
when using the TCPSocket version?
YS.
···
Since you asked for the code using Net::SMTP class, I have pasted it here -
# rubysmtp.rb
require 'net/smtp'
user_from = "abc@puneruby.com"
user_to = "abc@gmail.com"
the_email = "From: abc@puneruby.com\nSubject: Hello\n\nEmail by Ruby.\n\n"
# handling exceptions
begin
Net::SMTP.start('auth.smtp.1and1.co.uk', 25, 'auth.smtp.1and1.co.uk',
'abc@puneruby.com', 'password', :login) do
>smtpclient>
smtpclient.send_message(the_email, user_from, user_to)
end
rescue Exception => e
print "Exception occured: " + e
end
On 7/31/06, Yohanes Santoso <ysantoso-rubytalk@dessyku.is-a-geek.org> wrote:
"Satish Talim" <satish.talim@gmail.com> writes:
> I tried the various suggestions given by Francis and Yohanes, but still
it
> does not work.
>
> The executable code now is:
>
> require 'socket'
> t = TCPSocket.new('localhost', 25)
> puts t.gets
> t.puts "HELO Welcome from Ruby\r\n"
> puts t.gets
> t.puts "MAIL FROM:<satish_talim@yahoo.com>\r\n"
> puts t.gets
> t.puts "RCPT TO:<satish.talim@gmail.com>\r\n"
> puts t.gets
> t.puts 'DATA'
> puts t.gets
> t.puts "Test email from ruby\r\n"
> t.puts "\r\n.\r\n"
> t.puts 'QUIT'
> puts t.gets
> t.close
>
> and the output is:
>
>>ruby email.rb
> 220 Welcome to the 1st SMTP Server
>
> 250 Hello Welcome from Ruby
>
> 250 satish_talim@yahoo.com Address Okay
>
> 250 satish.talim@gmail.com Address Okay
>
> 354 Start mail input; end with <CRLF>.<CRLF>
>
> nil
>>Exit code: 0
/tmp $ ruby try.rb
220 jenny-gnome.dyndns.org ESMTP
250 jenny-gnome.dyndns.org
250 ok
250 ok
354 go ahead
250 ok 1154319423 qp 25461
/tmp $
What is your SMTP server?
> I'd appreciate any other suggestions. Incidentally, if I write a program
> using the Net::SMTP class, I am able to send off emails with my current
> configuration.
Please paste this code that uses Net::SMTP.
YS.
--
Satish Talim
http://www.puneruby.com/blog/
Here's my Telnet session using 1st SMTP server.
···
----------------------------------
220 Welcome to the 1st SMTP Server
HELO
250 Hello
MAIL FROM:<satish@puneruby.com>
250 satish@puneruby.com Address Okay
RCPT TO:<satish.talim@gmail.com>
250 satish.talim@gmail.com Address Okay
DATA
354 Start mail input; end with <CRLF>.<CRLF>
This is the Telnet transcript
For Ruby Talk
.
----------------------------------
After this no progress.
On 7/31/06, Francis Cianfrocca <garbagecat10@gmail.com> wrote:
Satish Talim wrote:
> I used Telnet and it got stuck when I typed . to stop the DATA. What
> change
> do I need to make in the TCPSocket code for authentication?
What does "got stuck" mean? Did it give an error message? Did it close
the connection? Did it hang? Show us a screenshot of the telnet
conversation.
--
Posted via http://www.ruby-forum.com/\.
--
Satish Talim
http://www.puneruby.com/blog/
Yohanes, you are right. The RFC's and specifically which ones to use are a
bit confusing. I read thro' RFC's 1869, 2554, 2821 and 3207 but am still not
clear of the exact sequence of commands to be executed while using
TCPSocket. I searched Google but did not find a specific solution. Still
searching...
I am abonding the local relay server and now trying to connect to the remote
ESMTP server that requires authentication.
···
On 7/31/06, Yohanes Santoso <ysantoso-rubytalk@dessyku.is-a-geek.org> wrote:
"Satish Talim" <satish.talim@gmail.com> writes:
> Like I said before I am using a relay SMTP server called 1st SMTP server
on
> my Windows XP. The code using TCPSocket does not do authenticate and as
such
> I am not using our actual SMTP server.
Could it be that the SMTP server (relay or not), does a running
verification for the content of the data?
That is, if the data is not in RFC822 format, then it aborts the
connection ungracefully.
Or, could it be aborting the connection because you don't authenticate
when using the TCPSocket version?
YS.
>
> Since you asked for the code using Net::SMTP class, I have pasted it
here -
>
> # rubysmtp.rb
> require 'net/smtp'
> user_from = "abc@puneruby.com"
> user_to = "abc@gmail.com"
> the_email = "From: abc@puneruby.com\nSubject: Hello\n\nEmail by
Ruby.\n\n"
> # handling exceptions
> begin
> Net::SMTP.start('auth.smtp.1and1.co.uk', 25, 'auth.smtp.1and1.co.uk',
> 'abc@puneruby.com', 'password', :login) do
> >smtpclient>
> smtpclient.send_message(the_email, user_from, user_to)
> end
> rescue Exception => e
> print "Exception occured: " + e
> end
>
> On 7/31/06, Yohanes Santoso <ysantoso-rubytalk@dessyku.is-a-geek.org> > wrote:
>>
>> "Satish Talim" <satish.talim@gmail.com> writes:
>>
>> > I tried the various suggestions given by Francis and Yohanes, but
still
>> it
>> > does not work.
>> >
>> > The executable code now is:
>> >
>> > require 'socket'
>> > t = TCPSocket.new('localhost', 25)
>> > puts t.gets
>> > t.puts "HELO Welcome from Ruby\r\n"
>> > puts t.gets
>> > t.puts "MAIL FROM:<satish_talim@yahoo.com>\r\n"
>> > puts t.gets
>> > t.puts "RCPT TO:<satish.talim@gmail.com>\r\n"
>> > puts t.gets
>> > t.puts 'DATA'
>> > puts t.gets
>> > t.puts "Test email from ruby\r\n"
>> > t.puts "\r\n.\r\n"
>> > t.puts 'QUIT'
>> > puts t.gets
>> > t.close
>> >
>> > and the output is:
>> >
>> >>ruby email.rb
>> > 220 Welcome to the 1st SMTP Server
>> >
>> > 250 Hello Welcome from Ruby
>> >
>> > 250 satish_talim@yahoo.com Address Okay
>> >
>> > 250 satish.talim@gmail.com Address Okay
>> >
>> > 354 Start mail input; end with <CRLF>.<CRLF>
>> >
>> > nil
>> >>Exit code: 0
>>
>> /tmp $ ruby try.rb
>> 220 jenny-gnome.dyndns.org ESMTP
>> 250 jenny-gnome.dyndns.org
>> 250 ok
>> 354 go ahead
>> 250 ok 1154319423 qp 25461
>> /tmp $
>>
>> What is your SMTP server?
>>
>> > I'd appreciate any other suggestions. Incidentally, if I write a
program
>> > using the Net::SMTP class, I am able to send off emails with my
current
>> > configuration.
>>
>> Please paste this code that uses Net::SMTP.
>>
>> YS.
>>
>
> --
> Satish Talim
> http://www.puneruby.com/blog/
--
Satish Talim
http://www.puneruby.com/blog/
Francis, thanks for helping me along. I tried your suggestions. However, it
still does not work. Do you know the ESMTP command sequence to send an email
over TSL and Authenticate?
···
On 7/31/06, Francis Cianfrocca <garbagecat10@gmail.com> wrote:
Satish Talim wrote:
> Here's my Telnet session using 1st SMTP server.
>
> ----------------------------------
> 220 Welcome to the 1st SMTP Server
> HELO
> 250 Hello
> MAIL FROM:<satish@puneruby.com>
> 250 satish@puneruby.com Address Okay
> RCPT TO:<satish.talim@gmail.com>
> 250 satish.talim@gmail.com Address Okay
> DATA
> 354 Start mail input; end with <CRLF>.<CRLF>
> This is the Telnet transcript
> For Ruby Talk
> .
> ----------------------------------
>
> After this no progress.
Try this instead:
-------------------------
DATA
354 Start.....
Subject: This is an email
This is the telnet transcript
.
--------------------------
Notice the blank line between the RFC-822 header and the message
content. Also, try running the same telnet conversation across a network
from a Windows client. (Telnet on Windows sends CRLF line-endings, which
your mail server may be anal-retentive enough to require.)
--
Posted via http://www.ruby-forum.com/\.
--
Satish Talim
http://www.puneruby.com/blog/
Satish Talim wrote:
Francis, thanks for helping me along. I tried your suggestions. However,
it
still does not work. Do you know the ESMTP command sequence to send an
email
over TSL and Authenticate?
Well, maybe try something like this:
Use EHLO instead of HELO.
After EHLO and before MAIL FROM, send:
AUTH PLAIN xxx\r\n
where xxx is the base-64 encoding of a string consisting of a binary
zero followed by your account name (on the mail server), followed by
another binary zero, followed by your password. In Ruby, perhaps
something like
require 'base64'
Base64.encode64( "\000#{username}\000#{psw}" ).chomp
···
--
Posted via http://www.ruby-forum.com/\.