summaryrefslogtreecommitdiff
path: root/README.md
blob: b45d18f2a8a812ceea9b1ccd646323e9d172793d (plain)
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
# http2lmtp

Recieve HTTP-enveloped mail and route it as LMTP to local Unix socket.

Cloudflare Email Workers can only reach a cf tunnel over HTTP, so the
message has to be wrapped in an HTTP request to get through. On the
server side, `http2lmtp` unwraps it and hands it to an LMTP-capable
MDA such as Dovecot.

## Quickstart

    cat <<EOF >/etc/ingest.env
	INGEST_TOKEN=$(uuidgen)
	LMTP_SOCK=/var/run/dovecot/lmtp
	LISTEN_ADDR=127.0.0.1:1234
	RUST_LOG=info
	EOF

	cargo build --release
	cp target/release/ingest /usr/local/bin/
	cp mail-ingest.service /etc/systemd/system/
	systemctl daemon-reload
	systemctl enable --now mail-ingest.service

## Example client
```ts
export default {
  async email(message, env, ctx) {
    const res = await fetch("https://example.com/inject", {
      method: "POST",
      headers: {
        "authorization": `Bearer ${env.INGEST_TOKEN}`,
        "content-type": "message/rfc822",
        "x-envelope-from": message.from,
        "x-envelope-to": message.to,
      },
      body: message.raw,
    });

    if (!res.ok) {
      const detail = await res.text().catch(() => "");
      throw new Error(`ingest ${res.status} ${detail.slice(0, 200)}`);
    }
  },
};
```

## Response codes

| Status | Meaning | Client action |
|---|---|---|
| `204 No Content` | Message accepted by the MDA | Done |
| `401 Unauthorized` | Missing or wrong bearer token | Fix config; do not retry |
| `413 Payload Too Large` | Body exceeds 26 MiB | Do not retry |
| `422 Unprocessable Entity` | LMTP replied with a permanent error (5xx), e.g. unknown recipient | Do not retry; bounce |
| `503 Service Unavailable` | LMTP unreachable or replied with a temporary error (4xx) | Retry later |

Note: `http2lmtp` itself never retries. The client is responsible for
it.