Coder Social home page Coder Social logo

smtp-1's Introduction

SMTP client for Tarantool 1.6+

The tarantool/smtp module is for sending email via SMTP with the Tarantool application server.

Since Tarantool already has facilities for setting up Internet servers, and can take advantage of the libcurl library for data transfer via URLs, tarantool/smtp simply builds on functionality that is in the main package.

With Tarantool and tarantool/smtp, developers have the routines for setting up an email client, and the facilities for testing locally before deploying to the Internet. This may be particularly interesting for developers who use Tarantool's database, Lua application server, and HTTP features.

Contents

How to install

You will need:

  • Tarantool 1.6+ with header files (tarantool and tarantool-dev modules)
  • curl
  • an operating system with developer tools including cmake, a C compiler, git and Lua

You have two ways to install tarantool/smtp:

  1. The first way is to use the Tarantool Lua rocks repository.

    With Tarantool 1.7.4+, say:

    tarantoolctl rocks install smtp
    

    With earlier Tarantool versions, set up Lua rocks and then say:

    luarocks --local install smtp
    
  2. The second way is to clone from https://github.com/tarantool/smtp, build, and use the produced library:

    git clone https://github.com/tarantool/smtp.git smtp
    cd smtp
    cmake . && make
    # and use the library as shown in "Ok, run it" section below

Whichever way you choose, it is still a good idea to look at the files in the github.com/tarantool/smtp repository. There are example files and commented test files, which will aid you in understanding how tarantool/smtp was put together.

Back to contents

The client request function

There is only one function in the smtp module: client().

It is a tool for handling the job of communicating with the server at a high level.

Format: client(url, from, to, body [, options])

The parameters are:

url -- type = string; value = the URL of the SMTP, including the protocol. Example: "smtp://127.0.0.1:34324".

from -- type = string; value = the name of the sender as it would appear in an email 'From:' line. Example: "[email protected]".

to -- type = string; value = the name of the recipients as they would appear in an email 'To:' line. There can be more than one recipient, separated by commas. Example: "[email protected]".

body -- type = string; value = the contents of the message. Example: "Test Message".

options -- type = table; value = one or more of the following:

Example: {timeout = 2}

Example of a complete request:

response =
client:request("smtp://127.0.0.1:34324",`"[email protected]"`,`"[email protected]"`,"Test
Message",{timeout=2})

The response to the request will be a table containing a status (number) and a reason (string). Example: {status: 250, reason: Ok} (The standard status code 250 means the request was executed.)

Back to contents

The server

An SMTP server does not come with tarantool/smtp, but tarantool/smtp does supply example code of an SMTP server that can be run on Tarantool -- tmtp.test.lua. We will use some of the code from this example to show that the request function works correctly.

Before simply presenting the code and saying "OK, run it", we should explain what it is supposed to handle.

Tarantool has a module named socket which contains a tcp_server() function. It is possible to make the TCP server run in the background as a fiber. As is common with client/server action, the example code has a loop that watches for incoming messages and processes them. In this case, it is processing according to the standard expected format that goes to an SMTP server, such as "EHLO", "RCPT FROM", "RCPT TO", and "DATA", which are all Simple Mail Transfer Protocol commands. When it encounters "DATA", it starts another loop to get all the lines of the message body.

To make the example simple, it is done on the local host without troubling to check CA certificates or passwords. The idea is not to compete with Internet giants like Mail.Ru, but to prove tarantool/smtp's request function calls work quickly.

Back to contents

OK, run it

Start Tarantool, run as a console:

tarantool

If you cloned and built the library from source, add the library path to package.cpath, for example:

-- for Ubuntu
package.cpath = package.cpath .. './smtp/?.so;'
-- for Mac OS
package.cpath = package.cpath .. './smtp/?.dylib;'

Execute these requests:

-- STARTUP

box.cfg{}

fiber = require('fiber')
socket = require('socket')
mails = fiber.channel(100)
-- SERVER CODE

function smtp_h(s)
     s:write('220 localhost ESMTP Tarantool\r\n')
     local l
     local mail = {rcpt = {}}
     while true do
         l = s:read('\r\n')
print(l)
         if l:find('EHLO') then
print(' EHLO')
             s:write('250-localhost Hello localhost.lan [127.0.0.1]\r\n')
             s:write('250-SIZE 52428800\r\n')
             s:write('250-8BITMIME\r\n')
             s:write('250-PIPELINING\r\n')
             s:write('250-CHUNKING\r\n')
             s:write('250-PRDR\r\n')
             s:write('250 HELP\r\n')
         elseif l:find('MAIL FROM:') then
print(' MAIL FROM')
             mail.from = l:sub(11):sub(1, -3)
             s:write('250 OK\r\n')
         elseif l:find('RCPT TO:') then
print(' RCPT TO')
             mail.rcpt[#mail.rcpt + 1] = l:sub(9):sub(1, -3)
             s:write('250 OK\r\n')
         elseif l == 'DATA\r\n' then
print(' DATA')
             s:write('354 Enter message, ending with "." on a line by itself\r\n')
             while true do
                 local l = s:read('\r\n')
print(' DATA: ' .. l)
                 if l == '.\r\n' then
                     break
                 end
                 mail.text = (mail.text or '') .. l
             end
             mails:put(mail)
             mail = {rcpt = {}}
             s:write('250 OK OK OK\r\n')
         elseif l:find('QUIT') then
print(' QUIT')
             return
         elseif l ~= nil then
print(' not implemented')
             s:write('502 Not implemented')
         else
             return
         end
     end
end

server = socket.tcp_server('127.0.0.1', 0, smtp_h)
addr = 'smtp://127.0.0.1:' .. server:name().port
-- TARANTOOL/SMTP REQUEST CODE

client = require('smtp').new()

response = client:request(addr, '[email protected]',
     '[email protected]',
     'mail.body')

Now pause and look at what the server's print() requests did: they should show that the server received EHLO, MAIL FROM, RCPT TO and DATA.

Now look at the response. It should look like this:

tarantool> response
---
- status: 250
   reason: Ok
...

This means the request has been sent and handled. (It does not mean that the request will pop up on the mailbox of [email protected], because this is done with a local test server, with none of the usual authorization options.)

Once you see that the response is 'Ok', you can switch from being a sender to being a receiver. Say:

mails:get()

And now the response should look like this:

tarantool> mails.get()
---
- from: <[email protected]>
   rcpt:
   - <[email protected]>
   text: "TO: [email protected]\r\nCC: \r\n\r\nmail.body\r\n"
...

If that is what you see, then you have successfully installed tarantool/smtp and successfully executed a request function that sent an email to an SMTP server, and confirmed it by getting the email back to yourself.

Back to contents

Contacts

The Tarantool organization at this time includes dozens of developers and support staffers, so you will have no trouble contacting and getting a response from an expert.

If you see what you think is a bug, or if you have a feature request, go to github.com/tarantool/smtp/issues and fill out a description.

If you want to hear more about Tarantool, go to tarantool.org and look for new announcements about this and other modules.

Back to contents

smtp-1's People

Contributors

rtsisyk avatar lenkis avatar totktonada avatar bigbes avatar kostja avatar georgykirichenko avatar funny-falcon avatar rosik avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.