Skip to content

Commit 3ac3435

Browse files
committed
Merge branch 'master' into release/3.1.2
2 parents 96985d1 + 71b1765 commit 3ac3435

459 files changed

Lines changed: 29059 additions & 8529 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

FubarDev.FtpServer.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QuickStart.GenericHost", "s
6464
EndProject
6565
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QuickStart.AspNetCoreHost", "samples\QuickStart.AspNetCoreHost\QuickStart.AspNetCoreHost.csproj", "{D03594D1-84CC-4B55-A56D-20ED446CFDB1}"
6666
EndProject
67+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FubarDev.FtpServer.FileSystem.S3", "src\FubarDev.FtpServer.FileSystem.S3\FubarDev.FtpServer.FileSystem.S3.csproj", "{220D3222-EDF4-4E2D-BEE7-7E0C22F39A3E}"
68+
EndProject
6769
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "ReadLine", "third-party\ReadLine\ReadLine.shproj", "{F68F448F-E8A4-4536-9A83-12018B6294B0}"
6870
EndProject
6971
Global
@@ -138,6 +140,10 @@ Global
138140
{D03594D1-84CC-4B55-A56D-20ED446CFDB1}.Debug|Any CPU.Build.0 = Debug|Any CPU
139141
{D03594D1-84CC-4B55-A56D-20ED446CFDB1}.Release|Any CPU.ActiveCfg = Release|Any CPU
140142
{D03594D1-84CC-4B55-A56D-20ED446CFDB1}.Release|Any CPU.Build.0 = Release|Any CPU
143+
{220D3222-EDF4-4E2D-BEE7-7E0C22F39A3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
144+
{220D3222-EDF4-4E2D-BEE7-7E0C22F39A3E}.Debug|Any CPU.Build.0 = Debug|Any CPU
145+
{220D3222-EDF4-4E2D-BEE7-7E0C22F39A3E}.Release|Any CPU.ActiveCfg = Release|Any CPU
146+
{220D3222-EDF4-4E2D-BEE7-7E0C22F39A3E}.Release|Any CPU.Build.0 = Release|Any CPU
141147
EndGlobalSection
142148
GlobalSection(SolutionProperties) = preSolution
143149
HideSolutionNode = FALSE
@@ -163,6 +169,7 @@ Global
163169
{02D103B2-B9CA-4A7F-AB79-6FEC68C62B47} = {7004709E-5C0D-4D3E-AF27-89968FA47C19}
164170
{23752176-0F1A-4352-B677-CD7878B7E8FC} = {7004709E-5C0D-4D3E-AF27-89968FA47C19}
165171
{D03594D1-84CC-4B55-A56D-20ED446CFDB1} = {7004709E-5C0D-4D3E-AF27-89968FA47C19}
172+
{220D3222-EDF4-4E2D-BEE7-7E0C22F39A3E} = {A3AF1D22-494F-42F3-8DA5-CC2FD3391798}
166173
{F68F448F-E8A4-4536-9A83-12018B6294B0} = {441F13FB-D457-402E-8DAC-4B6485AFCE30}
167174
EndGlobalSection
168175
GlobalSection(ExtensibilityGlobals) = postSolution
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<SolutionConfiguration>
22
<Settings>
33
<AllowParallelTestExecution>True</AllowParallelTestExecution>
4+
<InstrumentationMode>Optimised</InstrumentationMode>
45
<SolutionConfigured>True</SolutionConfigured>
56
</Settings>
67
</SolutionConfiguration>

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Portable FTP server
22

3-
[![Build status](https://build.fubar-dev.de/app/rest/builds/buildType:%28id:FtpServer_ReleaseBuild%29/statusIcon.svg)](https://build.fubar-dev.com/project.html?projectId=FtpServer)
3+
[![Build Status](https://dev.azure.com/fubar-development/ftp-server/_apis/build/status/FubarDevelopment.FtpServer?branchName=master)](https://dev.azure.com/fubar-development/ftp-server/_build/latest?definitionId=5&branchName=master)
44

55
This FTP server is written as .NET Standard 2.0 library and has an
66
abstract file system which allows e.g. Google Drive as backend.
@@ -76,10 +76,10 @@ using (var serviceProvider = services.BuildServiceProvider())
7676

7777
// Start the FTP server
7878
ftpServerHost.StartAsync(CancellationToken.None).Wait();
79-
79+
8080
Console.WriteLine("Press ENTER/RETURN to close the test application.");
8181
Console.ReadLine();
82-
82+
8383
// Stop the FTP server
8484
ftpServerHost.StopAsync(CancellationToken.None).Wait();
8585
}

docfx_project/articles/upgrade-3.0.md

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ title: Upgrade from 2.x to 3.0
1111
- [Connection](#connection)
1212
- [Connection data changes](#connection-data-changes)
1313
- [Data connections](#data-connections)
14+
- [Connection checks](#connection-checks)
15+
- [Idle check](#idle-check)
16+
- [Connection check](#connection-check)
1417
- [FTP middleware](#ftp-middleware)
1518
- [FTP request middleware](#ftp-request-middleware)
1619
- [FTP command execution middleware](#ftp-command-execution-middleware)
@@ -34,8 +37,8 @@ title: Upgrade from 2.x to 3.0
3437

3538
After the upgrade 3.0, you'll see that the `IFtpServer.Start` and `IFtpServer.Stop` functions are
3639
deprecated. Please query the [`IFtpServerHost`](xref:FubarDev.FtpServer.IFtpServerHost) instead and
37-
use the [`StartAsync`](xref:FubarDev.FtpServer.IFtpServerHost.StartAsync(CancellationToken))
38-
and [`StopAsync`](xref:FubarDev.FtpServer.IFtpServerHost.StopAsync(CancellationToken)) functions instead.
40+
use the [`StartAsync`](xref:FubarDev.FtpServer.IFtpServerHost.StartAsync(System.Threading.CancellationToken))
41+
and [`StopAsync`](xref:FubarDev.FtpServer.IFtpServerHost.StopAsync(System.Threading.CancellationToken)) functions instead.
3942

4043
You will notice breaking changes in the following areas:
4144

@@ -149,9 +152,46 @@ We're now using two factories to create data connections:
149152

150153
This factories create a [`IFtpDataConnectionFeature`](xref:FubarDev.FtpServer.Features.IFtpDataConnectionFeature) which is used to create [`IFtpDataConnection`](xref:FubarDev.FtpServer.IFtpDataConnection) implementations. This allows us to abstract away the differences between active and passive data connections.
151154

152-
The function `IFtpConnection.CreateResponseSocket` was replaced by [`IFtpConnection.OpenDataConnectionAsync`](xref:FubarDev.FtpServer.IFtpConnection.OpenDataConnectionAsync(System.Nullable{TimeSpan},CancellationToken)) and returns a [`IFtpDataConnection`](xref:FubarDev.FtpServer.IFtpDataConnection) implementation. This function also takes care of SSL/TLS encryption as it wraps the [`IFtpDataConnection`](xref:FubarDev.FtpServer.IFtpDataConnection) implementation returned by the [`IFtpDataConnectionFeature`](xref:FubarDev.FtpServer.Features.IFtpDataConnectionFeature) into a new [`IFtpDataConnection`](xref:FubarDev.FtpServer.IFtpDataConnection) implementation with the help of the [`SecureDataConnectionWrapper`](xref:FubarDev.FtpServer.DataConnection.SecureDataConnectionWrapper).
155+
The function `IFtpConnection.CreateResponseSocket` was replaced by [`DataConnectionServerCommand`](xref:FubarDev.FtpServer.ServerCommands.DataConnectionServerCommand) server command.
156+
The passed [`AsyncDataConnectionDelegate`](xref:FubarDev.FtpServer.ServerCommands.AsyncDataConnectionDelegate) gets an
157+
[`IFtpDataConnection`](xref:FubarDev.FtpServer.IFtpDataConnection) implementation and may return a response.
158+
This function also takes care of SSL/TLS encryption as it wraps the [`IFtpDataConnection`](xref:FubarDev.FtpServer.IFtpDataConnection)
159+
implementation returned by the [`IFtpDataConnectionFeature`](xref:FubarDev.FtpServer.Features.IFtpDataConnectionFeature) into
160+
a new [`IFtpDataConnection`](xref:FubarDev.FtpServer.IFtpDataConnection) implementation with the help of
161+
the [`SecureDataConnectionWrapper`](xref:FubarDev.FtpServer.DataConnection.SecureDataConnectionWrapper).
153162

154-
The extension method `SendResponseAsync` on the `IFtpConnection` was replaced by [`SendDataAsync`](xref:FubarDev.FtpServer.ConnectionExtensions.SendDataAsync(FubarDev.FtpServer.IFtpConnection,Func{FubarDev.FtpServer.IFtpDataConnection,CancellationToken,Task{FubarDev.FtpServer.IFtpResponse}},ILogger,CancellationToken)) and takes care of closing the [`IFtpDataConnection`](xref:FubarDev.FtpServer.IFtpDataConnection).
163+
The extension method `SendResponseAsync` on the `IFtpConnection` was replaced by the [`DataConnectionServerCommand`](xref:FubarDev.FtpServer.ServerCommands.DataConnectionServerCommand)
164+
server command and takes care of closing the [`IFtpDataConnection`](xref:FubarDev.FtpServer.IFtpDataConnection).
165+
166+
## Connection checks
167+
168+
The FTP server allows to check if a connection is still active. It ensures that the server doesn't get filled with dead connections, where
169+
the server didn't recognize that the client is gone (e.g. client crash, aborted TCP connection, etc...).
170+
171+
This was made possible by using the following two implementations for [`IFtpConnectionCheck`](xref:FubarDev.FtpServer.ConnectionChecks.IFtpConnectionCheck):
172+
173+
- [`FtpConnectionEstablishedCheck`](xref:FubarDev.FtpServer.ConnectionChecks.FtpConnectionEstablishedCheck) checks if the TCP connection is still established
174+
- [`FtpConnectionIdleCheck`](xref:FubarDev.FtpServer.ConnectionChecks.FtpConnectionIdleCheck) checks if the connection is idle for too long
175+
176+
This checks are enabled by default and can be disabled and reenabled by the following extension methods for
177+
the [`IFtpServerBuilder`](xref:FubarDev.FtpServer.IFtpServerBuilder):
178+
179+
- [`DisableChecks`](xref:FubarDev.FtpServer.FtpServerBuilderExtensionsForChecks.DisableChecks*) disables all checks (the default ones and the ones manually enabled before)
180+
- [`EnableDefaultChecks`](xref:FubarDev.FtpServer.FtpServerBuilderExtensionsForChecks.EnableDefaultChecks*) enables all default checks (see above)
181+
- [`EnableIdleCheck`](xref:FubarDev.FtpServer.FtpServerBuilderExtensionsForChecks.EnableIdleCheck*) enables the check for an idle connection
182+
- [`EnableConnectionCheck`](xref:FubarDev.FtpServer.FtpServerBuilderExtensionsForChecks.EnableConnectionCheck*) enables the check for an establised TCP connection
183+
- [`DisableIdleCheck`](xref:FubarDev.FtpServer.FtpServerBuilderExtensionsForChecks.DisableIdleCheck*) enables the check for an idle connection
184+
- [`DisableConnectionCheck`](xref:FubarDev.FtpServer.FtpServerBuilderExtensionsForChecks.DisableConnectionCheck*) disables the check for an establised TCP connection
185+
186+
The checks above are enabled by default.
187+
188+
### Idle check
189+
190+
The idle check determines if the connection was idle for too long. The default timeout is 5 minutes, configured through [`FtpConnectionOptions.InactivityTimeout`](xref:FubarDev.FtpServer.FtpConnectionOptions.InactivityTimeout).
191+
192+
### Connection check
193+
194+
This determines if the TCP connection is still established by sending an empty data packet to the client.
155195

156196
# FTP middleware
157197

@@ -268,6 +308,7 @@ and [`FtpCommandCollector`](xref:FubarDev.FtpServer.FtpCommandCollector).
268308
- Root and home directories for an account can be queried
269309
- New [`IFtpMiddleware`](xref:FubarDev.FtpServer.IFtpMiddleware) interface for custom request middleware
270310
- New [`IFtpCommandMiddleware`](xref:FubarDev.FtpServer.Commands.IFtpCommandMiddleware) interface for custom command execution middleware
311+
- New [FTP connection checks](#connection-checks)
271312

272313
## What's changed?
273314

docfx_project/code-snippets/logging-serilog/Program.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace QuickStart
1212
{
1313
class Program
1414
{
15-
static void Main(string[] args)
15+
static async Task Main(string[] args)
1616
{
1717
// Configure Serilog
1818
Log.Logger = new LoggerConfiguration()
@@ -48,13 +48,13 @@ static void Main(string[] args)
4848
var ftpServerHost = serviceProvider.GetRequiredService<IFtpServerHost>();
4949

5050
// Start the FTP server
51-
ftpServerHost.StartAsync().Wait();
51+
await ftpServerHost.StartAsync();
5252

5353
Console.WriteLine("Press ENTER/RETURN to close the test application.");
5454
Console.ReadLine();
5555

5656
// Stop the FTP server
57-
ftpServerHost.StopAsync().Wait();
57+
await ftpServerHost.StopAsync();
5858
}
5959
}
6060
}

docfx_project/code-snippets/quickstart/Program.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace QuickStart
1212
{
1313
class Program
1414
{
15-
static void Main(string[] args)
15+
static async Task Main(string[] args)
1616
{
1717
// Setup dependency injection
1818
var services = new ServiceCollection();
@@ -38,13 +38,13 @@ static void Main(string[] args)
3838
var ftpServerHost = serviceProvider.GetRequiredService<IFtpServerHost>();
3939

4040
// Start the FTP server
41-
ftpServerHost.StartAsync().Wait();
41+
await ftpServerHost.StartAsync();
4242

4343
Console.WriteLine("Press ENTER/RETURN to close the test application.");
4444
Console.ReadLine();
4545

4646
// Stop the FTP server
47-
ftpServerHost.StopAsync().Wait();
47+
await ftpServerHost.StopAsync();
4848
}
4949
}
5050
}

docs/api/FubarDev.FtpServer.AccountManagement.Anonymous.BlockAnonymousValidation.html

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,35 @@ <h5>Inheritance</h5>
9595
<h5>Implements</h5>
9696
<div><a class="xref" href="FubarDev.FtpServer.AccountManagement.Anonymous.IAnonymousPasswordValidator.html">IAnonymousPasswordValidator</a></div>
9797
</div>
98+
<div class="inheritedMembers">
99+
<h5>Inherited Members</h5>
100+
<div>
101+
<a class="xref" href="https://docs.microsoft.com/dotnet/api/system.object.equals#System_Object_Equals_System_Object_">Object.Equals(Object)</a>
102+
</div>
103+
<div>
104+
<a class="xref" href="https://docs.microsoft.com/dotnet/api/system.object.equals#System_Object_Equals_System_Object_System_Object_">Object.Equals(Object, Object)</a>
105+
</div>
106+
<div>
107+
<a class="xref" href="https://docs.microsoft.com/dotnet/api/system.object.gethashcode#System_Object_GetHashCode">Object.GetHashCode()</a>
108+
</div>
109+
<div>
110+
<a class="xref" href="https://docs.microsoft.com/dotnet/api/system.object.gettype#System_Object_GetType">Object.GetType()</a>
111+
</div>
112+
<div>
113+
<a class="xref" href="https://docs.microsoft.com/dotnet/api/system.object.memberwiseclone#System_Object_MemberwiseClone">Object.MemberwiseClone()</a>
114+
</div>
115+
<div>
116+
<a class="xref" href="https://docs.microsoft.com/dotnet/api/system.object.referenceequals#System_Object_ReferenceEquals_System_Object_System_Object_">Object.ReferenceEquals(Object, Object)</a>
117+
</div>
118+
<div>
119+
<a class="xref" href="https://docs.microsoft.com/dotnet/api/system.object.tostring#System_Object_ToString">Object.ToString()</a>
120+
</div>
121+
</div>
98122
<h6><strong>Namespace</strong>: <a class="xref" href="FubarDev.FtpServer.AccountManagement.Anonymous.html">FubarDev.FtpServer.AccountManagement.Anonymous</a></h6>
99123
<h6><strong>Assembly</strong>: FubarDev.FtpServer.Abstractions.dll</h6>
100124
<h5 id="FubarDev_FtpServer_AccountManagement_Anonymous_BlockAnonymousValidation_syntax">Syntax</h5>
101125
<div class="codewrapper">
102-
<pre><code class="lang-csharp hljs">public class BlockAnonymousValidation : object, IAnonymousPasswordValidator</code></pre>
126+
<pre><code class="lang-csharp hljs">public class BlockAnonymousValidation : IAnonymousPasswordValidator</code></pre>
103127
</div>
104128
<h3 id="methods">Methods
105129
</h3>
@@ -108,12 +132,11 @@ <h3 id="methods">Methods
108132
<a href="https://github.com/FubarDevelopment/FtpServer/new/master/docfx_project/apidoc/new?filename=FubarDev_FtpServer_AccountManagement_Anonymous_BlockAnonymousValidation_IsValid_System_String_.md&amp;value=---%0Auid%3A%20FubarDev.FtpServer.AccountManagement.Anonymous.BlockAnonymousValidation.IsValid(System.String)%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
109133
</span>
110134
<span class="small pull-right mobile-hide">
111-
<a href="https://github.com/FubarDevelopment/FtpServer/blob/release/3.0/src/FubarDev.FtpServer.Abstractions/AccountManagement/Anonymous/BlockAnonymousValidation.cs/#L16">View Source</a>
135+
<a href="https://github.com/FubarDevelopment/FtpServer/blob/master/src/FubarDev.FtpServer.Abstractions/AccountManagement/Anonymous/BlockAnonymousValidation.cs/#L16">View Source</a>
112136
</span>
113137
<a id="FubarDev_FtpServer_AccountManagement_Anonymous_BlockAnonymousValidation_IsValid_" data-uid="FubarDev.FtpServer.AccountManagement.Anonymous.BlockAnonymousValidation.IsValid*"></a>
114138
<h4 id="FubarDev_FtpServer_AccountManagement_Anonymous_BlockAnonymousValidation_IsValid_System_String_" data-uid="FubarDev.FtpServer.AccountManagement.Anonymous.BlockAnonymousValidation.IsValid(System.String)">IsValid(String)</h4>
115-
<div class="markdown level1 summary"><p>Determines whether this password is valid for an anonymous login.</p>
116-
</div>
139+
<div class="markdown level1 summary"></div>
117140
<div class="markdown level1 conceptual"></div>
118141
<h5 class="decalaration">Declaration</h5>
119142
<div class="codewrapper">
@@ -132,8 +155,7 @@ <h5 class="parameters">Parameters</h5>
132155
<tr>
133156
<td><a class="xref" href="https://docs.microsoft.com/dotnet/api/system.string">String</a></td>
134157
<td><span class="parametername">password</span></td>
135-
<td><p>The password to validate.</p>
136-
</td>
158+
<td></td>
137159
</tr>
138160
</tbody>
139161
</table>
@@ -148,8 +170,7 @@ <h5 class="returns">Returns</h5>
148170
<tbody>
149171
<tr>
150172
<td><a class="xref" href="https://docs.microsoft.com/dotnet/api/system.boolean">Boolean</a></td>
151-
<td><pre><code>true</code></pre> when the password is valid for this kind of anonymous authentication.
152-
</td>
173+
<td></td>
153174
</tr>
154175
</tbody>
155176
</table>
@@ -168,7 +189,7 @@ <h3 id="implements">Implements</h3>
168189
<a href="https://github.com/FubarDevelopment/FtpServer/new/master/docfx_project/apidoc/new?filename=FubarDev_FtpServer_AccountManagement_Anonymous_BlockAnonymousValidation.md&amp;value=---%0Auid%3A%20FubarDev.FtpServer.AccountManagement.Anonymous.BlockAnonymousValidation%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A" class="contribution-link">Improve this Doc</a>
169190
</li>
170191
<li>
171-
<a href="https://github.com/FubarDevelopment/FtpServer/blob/release/3.0/src/FubarDev.FtpServer.Abstractions/AccountManagement/Anonymous/BlockAnonymousValidation.cs/#L13" class="contribution-link">View Source</a>
192+
<a href="https://github.com/FubarDevelopment/FtpServer/blob/master/src/FubarDev.FtpServer.Abstractions/AccountManagement/Anonymous/BlockAnonymousValidation.cs/#L13" class="contribution-link">View Source</a>
172193
</li>
173194
</ul>
174195
</div>

docs/api/FubarDev.FtpServer.AccountManagement.Anonymous.IAnonymousPasswordValidator.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ <h3 id="methods">Methods
9999
<a href="https://github.com/FubarDevelopment/FtpServer/new/master/docfx_project/apidoc/new?filename=FubarDev_FtpServer_AccountManagement_Anonymous_IAnonymousPasswordValidator_IsValid_System_String_.md&amp;value=---%0Auid%3A%20FubarDev.FtpServer.AccountManagement.Anonymous.IAnonymousPasswordValidator.IsValid(System.String)%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A">Improve this Doc</a>
100100
</span>
101101
<span class="small pull-right mobile-hide">
102-
<a href="https://github.com/FubarDevelopment/FtpServer/blob/release/3.0/src/FubarDev.FtpServer.Abstractions/AccountManagement/Anonymous/IAnonymousPasswordValidator.cs/#L20">View Source</a>
102+
<a href="https://github.com/FubarDevelopment/FtpServer/blob/master/src/FubarDev.FtpServer.Abstractions/AccountManagement/Anonymous/IAnonymousPasswordValidator.cs/#L20">View Source</a>
103103
</span>
104104
<a id="FubarDev_FtpServer_AccountManagement_Anonymous_IAnonymousPasswordValidator_IsValid_" data-uid="FubarDev.FtpServer.AccountManagement.Anonymous.IAnonymousPasswordValidator.IsValid*"></a>
105105
<h4 id="FubarDev_FtpServer_AccountManagement_Anonymous_IAnonymousPasswordValidator_IsValid_System_String_" data-uid="FubarDev.FtpServer.AccountManagement.Anonymous.IAnonymousPasswordValidator.IsValid(System.String)">IsValid(String)</h4>
@@ -155,7 +155,7 @@ <h5 class="returns">Returns</h5>
155155
<a href="https://github.com/FubarDevelopment/FtpServer/new/master/docfx_project/apidoc/new?filename=FubarDev_FtpServer_AccountManagement_Anonymous_IAnonymousPasswordValidator.md&amp;value=---%0Auid%3A%20FubarDev.FtpServer.AccountManagement.Anonymous.IAnonymousPasswordValidator%0Asummary%3A%20'*You%20can%20override%20summary%20for%20the%20API%20here%20using%20*MARKDOWN*%20syntax'%0A---%0A%0A*Please%20type%20below%20more%20information%20about%20this%20API%3A*%0A%0A" class="contribution-link">Improve this Doc</a>
156156
</li>
157157
<li>
158-
<a href="https://github.com/FubarDevelopment/FtpServer/blob/release/3.0/src/FubarDev.FtpServer.Abstractions/AccountManagement/Anonymous/IAnonymousPasswordValidator.cs/#L13" class="contribution-link">View Source</a>
158+
<a href="https://github.com/FubarDevelopment/FtpServer/blob/master/src/FubarDev.FtpServer.Abstractions/AccountManagement/Anonymous/IAnonymousPasswordValidator.cs/#L13" class="contribution-link">View Source</a>
159159
</li>
160160
</ul>
161161
</div>

0 commit comments

Comments
 (0)