File: UsingSubEthaSMTP.md

package info (click to toggle)
subethasmtp 4.0~rc6-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 964 kB
  • sloc: java: 6,330; xml: 322; sh: 12; makefile: 2
file content (106 lines) | stat: -rw-r--r-- 4,801 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
SubEthaSMTP depends on the [SLF4J](http://www.slf4j.org/) logging library and [JavaMail](http://www.oracle.com/technetwork/java/javamail/index.html). You will need  slf4j-api-X.X.X.jar and one of the SLF4J binding jars such as  slf4j-simple-X.X.X.jar, both of which are included in our distribution. Other binding jars (Log4J, java.util.logging, LogKit, etc) are available in the SLF4J distribution which you can download from their website.

Note that [Wiser](Wiser.md) has additional dependencies.

SubEthaSMTP implements a powerful, low-level API that lets you handle incoming mail and (optionally) authenticate clients.  It also provides several helper classes that make life easier, if perhaps less flexible.

## The Basic API ##
```
SMTPServer smtpServer = SMTPServer.port(25).messageHandlerFactory(myFactory).build();
smtpServer.start();
```

```
public interface MessageHandlerFactory
{
	/**
	 * Called for the exchange of a single message during an SMTP conversation.
	 */
	public MessageHandler create(MessageContext ctx);
}

public interface MessageHandler
{
	/**
	 * Called first, after the MAIL FROM during a SMTP exchange.
	 */
	public void from(String from) throws RejectException;
	
	/**
	 * Called once for every RCPT TO during a SMTP exchange.
	 * This will occur after a from() call.
	 */
	public void recipient(String recipient) throws RejectException;
	
	/**
	 * Called when the DATA part of the SMTP exchange begins.
	 */
	public void data(InputStream data) throws RejectException, TooMuchDataException, IOException;
}
```

For every message delivery, SubEthaSMTP will call your Factory to create a MessageHandler.  The from(), recipient(), and data() methods will be called during each stage of the SMTP transaction. If multiple messages are delivered within a single SMTP session (via the RSET command), multiple MessageHandlers will be created.

## Higher-Level Help ##

If you simply wish to receive one copy of each message/recipient combination, the SimpleMessageListener will help you.

```
SMTPServer server = SMTPServer
  .port(25)
  .messageHandlerFactory(new SimpleMessageListenerAdapter(myListener))
  .build();
server.start();
```

The SimpleMessageListener is easy to implement:

```
public interface SimpleMessageListener
{
	/**
	 * Called once for every RCPT TO during a SMTP exchange.  Each accepted recipient
	 * will result in a separate deliver() call later.
	 */
	public boolean accept(String from, String recipient);

	/**
	 * When message data arrives, this method will be called for every recipient
	 * this listener accepted.
	 */
	public void deliver(String from, String recipient, InputStream data)
			throws TooMuchDataException, IOException;
}
```

Your listener simply accept()s any recipients it cares about, and the SMTP server will deliver() an input stream of the message data. Any recipients which are not accepted by a listener will be rejected.

Beware, however, that delivering mail to multiple recipients requires that the entire message be buffered as it is read by the first consumer.  The buffer will start to memory, then switch to disk if the size exceeds a threshold.

Look at the source code for [Wiser](Wiser.md) to see a simple example of how to implement SimpleMessageListener.deliver() so that it receives a message and converts it into a JavaMail MimeMessage object.

## Authentication ##

SubEtha SMTP supports the SMTP AUTH commands through a factory interface similar to the MessageHandlerFactory.  For convenience, a pluggable authenticator implementation that supports PLAIN and LOGIN is provided with the distribution.

```
SMTPServer server = SMTPServer
  .port(port)
  .messageHandlerFactory(myMessageHandlerFactory);
  .authenticationHandlerFactory(new EasyAuthenticationHandlerFactory(myUsernamePasswordValidator))
  .build();
server.start();
```

If you do not explicitly set an AuthenticationHandlerFactory, SMTP AUTH will not be advertised or supported.  See the javadocs for AuthenticationHandlerFactory for more information.

## Threading ##

SubEthaSMTP is a multithreaded server.  You may change settings on a stopped server (ie the # of simultaneous connections allowed) but not after calling start().  Each SMTP connection will be serviced by a new thread.

## Using Port 25 on Unix ##

On unix, it is possible to run SubEthatSMTP on port 25 without running the JVM as root. Please see the iptables/ipfw instructions here: [UsingPort25](http://code.google.com/p/subetha/wiki/UsingPort25)

## SSL Configuration ##
A fully worked example of StartTLS is available in the unit test [StartTLSFullTest.java](src/test/java/org/subethamail/smtp/StartTLSFullTest.java). The basis of the unit test was the excellent [blog posting](https://blog.trifork.com/2009/11/10/securing-connections-with-tls/) by Erik van Oosten.