Skip to content

Commit

Permalink
Merge pull request #545 from Badgerati/Issue-543
Browse files Browse the repository at this point in the history
1.7.2
  • Loading branch information
Badgerati committed Apr 27, 2020
2 parents dc9d6ab + 5cfef79 commit 0b2d66f
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 21 deletions.
7 changes: 7 additions & 0 deletions docs/release-notes.md
@@ -1,5 +1,12 @@
# Release Notes

## v1.7.2

```plain
### Bugs
* #543: Fixes an internal issue that was causing errors in the SMTP server
```

## v1.7.1

```plain
Expand Down
10 changes: 9 additions & 1 deletion examples/mail-server.ps1
Expand Up @@ -4,13 +4,21 @@ Import-Module "$($path)/src/Pode.psm1" -Force -ErrorAction Stop
# or just:
# Import-Module Pode

<#
Example call:
Send-MailMessage -SmtpServer localhost -To 'to@pode.com' -From 'from@pode.com' -Body 'Hello' -Subject 'Hi there' -Port 25
#>

# create a server, and start listening on port 25
Start-PodeServer -Threads 2 {

Add-PodeEndpoint -Address localhost -Protocol SMTP

# enable logging
New-PodeLoggingMethod -Terminal | Enable-PodeErrorLogging

# allow the local ip
Add-PodeAccessRule -Access Allow -Type IP -Values 127.0.0.1
#Add-PodeAccessRule -Access Allow -Type IP -Values 127.0.0.1

# setup an smtp handler
Add-PodeHandler -Type Smtp -Name 'Main' -ScriptBlock {
Expand Down
11 changes: 10 additions & 1 deletion src/Private/Responses.ps1
Expand Up @@ -57,6 +57,11 @@ function Close-PodeTcpConnection
[Parameter()]
$Client,

[Parameter(ParameterSetName='Quit')]
[string]
$Message,

[Parameter(ParameterSetName='Quit')]
[switch]
$Quit
)
Expand All @@ -67,7 +72,11 @@ function Close-PodeTcpConnection

if ($null -ne $Client) {
if ($Quit -and $Client.Connected) {
Write-PodeTcpClient -Message '221 Bye'
if ([string]::IsNullOrWhiteSpace($Message)) {
$Message = '221 Bye'
}

Write-PodeTcpClient -Message $Message
}

Close-PodeDisposable -Disposable $Client -Close
Expand Down
5 changes: 5 additions & 0 deletions src/Private/Server.ps1
Expand Up @@ -170,6 +170,11 @@ function Restart-PodeInternalServer
# clear up shared state
$PodeContext.Server.State.Clear()

# reset type if smtp/tcp
if (@('smtp', 'tcp') -icontains $PodeContext.Server.Type) {
$PodeContext.Server.Type = [string]::Empty
}

# recreate the session tokens
Close-PodeDisposable -Disposable $PodeContext.Tokens.Cancellation
$PodeContext.Tokens.Cancellation = New-Object System.Threading.CancellationTokenSource
Expand Down
47 changes: 28 additions & 19 deletions src/Private/SmtpServer.ps1
Expand Up @@ -47,7 +47,7 @@ function Start-PodeSmtpServer
# scriptblock for the core smtp message processing logic
$process = {
# if there's no client, just return
if ($null -eq $SmtpEvent.Client) {
if ($null -eq $TcpEvent.Client) {
return
}

Expand All @@ -64,6 +64,9 @@ function Start-PodeSmtpServer
while ($true)
{
try { $msg = (Read-PodeTcpClient) }
catch [System.OperationCanceledException] {
throw
}
catch {
$_ | Write-PodeErrorLog
break
Expand Down Expand Up @@ -98,32 +101,35 @@ function Start-PodeSmtpServer
Write-PodeTcpClient -Message '250 OK'

# set event data/headers
$SmtpEvent.Email.From = $mail_from
$SmtpEvent.Email.To = $rcpt_tos
$SmtpEvent.Email.Data = $data
$SmtpEvent.Email.Headers = (Get-PodeSmtpHeadersFromData $data)
$TcpEvent.Email.From = $mail_from
$TcpEvent.Email.To = $rcpt_tos
$TcpEvent.Email.Data = $data
$TcpEvent.Email.Headers = (Get-PodeSmtpHeadersFromData $data)

# set the subject/priority/content-types
$SmtpEvent.Email.Subject = $SmtpEvent.Headers['Subject']
$SmtpEvent.Email.IsUrgent = (($SmtpEvent.Headers['Priority'] -ieq 'urgent') -or ($SmtpEvent.Headers['Importance'] -ieq 'high'))
$SmtpEvent.Email.ContentType = $SmtpEvent.Headers['Content-Type']
$SmtpEvent.Email.ContentEncoding = $SmtpEvent.Headers['Content-Transfer-Encoding']
$TcpEvent.Email.Subject = $TcpEvent.Email.Headers['Subject']
$TcpEvent.Email.IsUrgent = (($TcpEvent.Email.Headers['Priority'] -ieq 'urgent') -or ($TcpEvent.Email.Headers['Importance'] -ieq 'high'))
$TcpEvent.Email.ContentType = $TcpEvent.Email.Headers['Content-Type']
$TcpEvent.Email.ContentEncoding = $TcpEvent.Email.Headers['Content-Transfer-Encoding']

# set the email body
$SmtpEvent.Email.Body = (Get-PodeSmtpBody -Data $data -ContentType $SmtpEvent.ContentType -ContentEncoding $SmtpEvent.ContentEncoding)
$TcpEvent.Email.Body = (Get-PodeSmtpBody -Data $data -ContentType $TcpEvent.ContentType -ContentEncoding $TcpEvent.ContentEncoding)

# call user handlers for processing smtp data
$handlers = Get-PodeHandler -Type Smtp
foreach ($name in $handlers.Keys) {
$handler = $handlers[$name]
Invoke-PodeScriptBlock -ScriptBlock $handler.Logic -Arguments (@($SmtpEvent) + @($handler.Arguments)) -Scoped -Splat
Invoke-PodeScriptBlock -ScriptBlock $handler.Logic -Arguments (@($TcpEvent) + @($handler.Arguments)) -Scoped -Splat
}

# reset the to list
$rcpt_tos = @()
}
}
}
catch [System.OperationCanceledException] {
throw
}
catch [exception] {
$_ | Write-PodeErrorLog
throw $_.exception
Expand All @@ -137,23 +143,26 @@ function Start-PodeSmtpServer
{
# get an incoming request
$client = (Wait-PodeTask -Task $Listener.AcceptTcpClientAsync())
$TcpEvent = @{
Client = $client
Lockable = $PodeContext.Lockable
Email = @{}
}

# convert the ip
$ip = (ConvertTo-PodeIPAddress -Endpoint $client.Client.RemoteEndPoint)

# ensure the request ip is allowed
if (!(Test-PodeIPAccess -IP $ip) -or !(Test-PodeIPLimit -IP $ip)) {
Close-PodeTcpConnection -Quit
if (!(Test-PodeIPAccess -IP $ip)) {
Close-PodeTcpConnection -Quit -Message '550 Your IP address was rejected'
}

elseif (!(Test-PodeIPLimit -IP $ip)) {
Close-PodeTcpConnection -Quit -Message '550 Your IP address has hit the rate limit'
}

# deal with smtp call
else {
$SmtpEvent = @{
Client = $client
Lockable = $PodeContext.Lockable
Email = $null
}

Invoke-PodeScriptBlock -ScriptBlock $process
Close-PodeTcpConnection -Quit
}
Expand Down

0 comments on commit 0b2d66f

Please sign in to comment.