You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: Rnwood.Smtp4dev/CommandLineParser.cs
+6-4Lines changed: 6 additions & 4 deletions
Original file line number
Diff line number
Diff line change
@@ -70,7 +70,9 @@ public static MapOptions<CommandLineOptions> TryParseCommandLine(IEnumerable<str
70
70
{"sslprotocols=","Specifies the SSL/TLS protocol version(s) that will be allowed. Separate with commas. See https://learn.microsoft.com/en-us/dotnet/api/system.security.authentication.sslprotocols?view=net-9.0", data =>map.Add(data, x =>x.ServerOptions.SslProtocols)},
71
71
{"tlsciphersuites=","Specifies the TLS cipher suites to be allowed. Not supported on Windows. Separate with commas. See https://learn.microsoft.com/en-us/dotnet/api/system.net.security.tlsciphersuite?view=net-9.0", data =>map.Add(data, x =>x.ServerOptions.TlsCipherSuites)},
72
72
{"HtmlValidateConfigfile=","Defines path to a config file used for HTML validation. See https://html-validate.org/usage/index.html#configuration", data =>map.Add(File.ReadAllText(data), x =>x.ServerOptions.HtmlValidateConfig)},
73
-
{"maxmessagesize=","Defines the maximum message size in bytes accepted by the SMTP server", data =>map.Add(data, x =>x.ServerOptions.MaxMessageSize)}
73
+
{"maxmessagesize=","Defines the maximum message size in bytes accepted by the SMTP server", data =>map.Add(data, x =>x.ServerOptions.MaxMessageSize)},
74
+
{"delivertostdout=","Specifies mailboxes (comma-separated) or '*' to output received raw message content to stdout", data =>map.Add(data, x =>x.ServerOptions.DeliverToStdout)},
75
+
{"exitafter=","Specifies the number of messages to receive before exiting the application (used with delivertostdout)", data =>map.Add(data, x =>x.ServerOptions.ExitAfterMessages)}
74
76
};
75
77
76
78
if(!isDesktopApp)
@@ -112,9 +114,9 @@ public static MapOptions<CommandLineOptions> TryParseCommandLine(IEnumerable<str
112
114
}
113
115
else
114
116
{
115
-
Console.WriteLine();
116
-
Console.WriteLine(" > For help use argument --help");
117
-
Console.WriteLine();
117
+
Console.Error.WriteLine();
118
+
Console.Error.WriteLine(" > For help use argument --help");
log.Information("Processing received message for mailbox '{mailbox}' for recipients '{recipients}'",targetMailboxWithRecipients.Key.Name,targetMailboxWithRecipients.ToArray());
Copy file name to clipboardExpand all lines: docs/Configuration.md
+75Lines changed: 75 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -161,4 +161,79 @@ If you want to customize the default mailbox behavior, you can explicitly config
161
161
162
162
**Regex not working**: Ensure the pattern is surrounded by forward slashes (`/pattern/`) and test the regex with an online regex tester.
163
163
164
+
## Deliver to Stdout Feature
165
+
166
+
smtp4dev can output raw message content to stdout for automated processing or testing scenarios. This feature is useful for CI/CD pipelines, automated testing, or integrating with other tools.
167
+
168
+
### Configuration Options
169
+
170
+
#### DeliverToStdout
171
+
172
+
Specifies which mailboxes should have their messages output to stdout:
173
+
174
+
-**`*`** - Deliver all messages from all mailboxes to stdout
175
+
-**`mailbox1,mailbox2`** - Deliver only messages from specified mailboxes (comma-separated)
**Command Line**: `--delivertostdout="*"` or `--delivertostdout="Sales,Support"`
179
+
180
+
**Configuration File**:
181
+
```json
182
+
{
183
+
"ServerOptions": {
184
+
"DeliverToStdout": "*"
185
+
}
186
+
}
187
+
```
188
+
189
+
#### ExitAfterMessages
190
+
191
+
Automatically exit the application after delivering a specified number of messages to stdout. Useful for automated testing scenarios.
192
+
193
+
**Command Line**: `--exitafter=5`
194
+
195
+
**Configuration File**:
196
+
```json
197
+
{
198
+
"ServerOptions": {
199
+
"ExitAfterMessages": 5
200
+
}
201
+
}
202
+
```
203
+
204
+
### Message Format
205
+
206
+
Messages delivered to stdout are wrapped with delimiters to separate multiple messages:
207
+
208
+
```
209
+
--- BEGIN SMTP4DEV MESSAGE ---
210
+
<raw message content>
211
+
--- END SMTP4DEV MESSAGE ---
212
+
```
213
+
214
+
### Logging Behavior
215
+
216
+
When using deliver to stdout, all diagnostic and application logs are automatically redirected to stderr, ensuring stdout contains only message content.
**Want messages in multiple mailboxes**: This is not supported due to "first match wins" logic. Consider using a single mailbox with multiple recipient patterns instead.
Copy file name to clipboardExpand all lines: docs/Testing.md
+119Lines changed: 119 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -406,6 +406,125 @@ public class SmtpTestcontainersTests : IAsyncLifetime
406
406
awaitsmtp4devContainer.DisposeAsync();
407
407
}
408
408
}
409
+
410
+
## Capturing raw messages via stdout (--delivertostdout)
411
+
412
+
For CI and automated tests you can have smtp4dev write the raw message bytes it receives to stdout so your test harness can capture and inspect them directly.
413
+
414
+
How itworks
415
+
- Use `--delivertostdout` to specify either `*` (all mailboxes) or a comma-separated list of mailboxnames (case-insensitive). The server checks the configured mailbox name for each delivered message and, when matched, writes the message's raw bytes to stdout.
416
+
- Each message written to stdout is wrapped with clear ASCII delimiters to make parsing simple:
417
+
418
+
```
419
+
--- BEGIN SMTP4DEV MESSAGE ---
420
+
<raw message content (bytes)>
421
+
--- END SMTP4DEV MESSAGE ---
422
+
```
423
+
424
+
- The server writes the message bytes directly to the stdout stream (soattachmentsandbinarycontentare preserved). The delimiters are written using normal Console.WriteLine calls.
425
+
- When `--delivertostdout` is used the application logs and diagnostics should be captured from stderr (thedefaultSerilogconsoleconfigurationwritesapplicationlogstostderr), ensuring stdout contains only message content.
426
+
427
+
Exit after N messages
428
+
- Use `--exitafter=<n>` to make smtp4dev automatically exit once it has delivered `n` messages to stdout. This is intended for short-lived test runs where you start smtp4dev, send test emails, and wait for the process to exit.
429
+
- The server tracks the number of messages written to stdout and, when the configured threshold is reached, schedules an orderly exit (Environment.Exit(0)) after a short delay to allow output to flush.
430
+
431
+
Important notes and examples
432
+
- `--delivertostdout` accepts `*` or a list of mailbox names: `--delivertostdout="*"` or `--delivertostdout="Sales,Support"`.
433
+
- `--exitafter` only counts messages that were actually delivered to stdout (i.e. matchedby `--delivertostdout`).
434
+
- Because the raw bytes are written to stdout, redirect stdout to a file to capture messages and keep stderr for logs:
435
+
436
+
```powershell
437
+
# Capture all messages and logs separately (WindowsPowerShell syntax)
- When parsing the captured file, split on the delimiter lines (`--- BEGINSMTP4DEV MESSAGE ---` / `--- ENDSMTP4DEV MESSAGE ---`) to extract each message's raw content.
448
+
- The server uses a short delay before exiting to allow output buffers to flush; exit code will be `0` on normal shutdown triggered by `--exitafter`.
449
+
450
+
Concurrency andreliability
451
+
- Writing to stdout is synchronized internally to avoid interleaving when multiple messages arrive concurrently.
452
+
- The count used by `--exitafter` is updated under the same lock that writes themessage, sotheexitthresholdisreliableevenunderconcurrentdeliveries.
0 commit comments