[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

TCPSocket and RFC 821

Satish Talim

7/30/2006 7:24:00 AM

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...) - 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.

9 Answers

Francis Cianfrocca

7/30/2006 1:01:00 PM

0

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...) - 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.
>
>

Yohanes Santoso

7/30/2006 5:44:00 PM

0

"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...) - 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.

Francis Cianfrocca

7/30/2006 8:23:00 PM

0

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-....

Yohanes Santoso

7/31/2006 4:24:00 AM

0

"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.

Francis Cianfrocca

7/31/2006 6:31:00 AM

0

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-....

Francis Cianfrocca

7/31/2006 8:23:00 AM

0

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-....

Francis Cianfrocca

7/31/2006 12:03:00 PM

0

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

Francis Cianfrocca

7/31/2006 1:19:00 PM

0

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-....

Yohanes Santoso

7/31/2006 4:46:00 PM

0

"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...