aboutsummaryrefslogtreecommitdiff
path: root/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'README.md')
-rw-r--r--README.md78
1 files changed, 47 insertions, 31 deletions
diff --git a/README.md b/README.md
index 872e793..e4960e3 100644
--- a/README.md
+++ b/README.md
@@ -22,41 +22,34 @@ MDA such as Dovecot.
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)}`);
- }
- },
-};
-```
+## Protocol
-## Response codes
+`POST /inject`
-| Status | Meaning | Client action |
+| Header | Required | Description |
|---|---|---|
-| `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 |
+| `authorization` | yes | `Bearer <INGEST_TOKEN>` |
+| `content-type` | no | `message/rfc822` |
+| `x-envelope-from` | no | SMTP `MAIL FROM` address |
+| `x-envelope-to` | no | SMTP `RCPT TO` address, unless `LMTP_RCPT` is set |
-Note: `http2lmtp` itself never retries. The client is responsible for
-it.
+The body is the raw RFC 5322 message.
+
+```sh
+curl -i -X POST http://127.0.0.1:1234/inject \
+ -H "authorization: Bearer $INGEST_TOKEN" \
+ -H "content-type: message/rfc822" \
+ -H "x-envelope-from: [email protected]" \
+ -H "x-envelope-to: [email protected]" \
+ --data-binary @message.eml
+```
+
+| Status | Meaning |
+|---|---|
+| `204` | Delivered. |
+| `401` | Missing or invalid token. |
+| `422` | LMTP rejected the message permanently (5xx). Do not retry. |
+| `503` | LMTP unreachable or rejected temporarily (4xx). Retry later. |
## Environment
@@ -80,3 +73,26 @@ LISTEN_ADDR=127.0.0.1:1234
RUST_LOG=http2lmtp=info
```
+
+## Example client (cloudflare workers)
+```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)}`);
+ }
+ },
+};
+```