Skip to content

Commit 90f769a

Browse files
committed
Implemented the FTP requester #10
1 parent 2e80dd4 commit 90f769a

File tree

5 files changed

+95
-2
lines changed

5 files changed

+95
-2
lines changed

src/AngleSharp.Io.Tests/AngleSharp.Io.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
</ItemGroup>
9494
<ItemGroup>
9595
<Compile Include="Helper.cs" />
96+
<Compile Include="Network\FtpRequesterTests.cs" />
9697
<Compile Include="Network\HttpClientRequesterTests.cs" />
9798
<Compile Include="Network\Mocks\Request.cs" />
9899
<Compile Include="Network\Mocks\HttpMockHandler.cs" />
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
namespace AngleSharp.Io.Tests.Network
2+
{
3+
using AngleSharp.Dom.Html;
4+
using AngleSharp.Extensions;
5+
using AngleSharp.Io.Network;
6+
using AngleSharp.Network.Default;
7+
using NUnit.Framework;
8+
using System.IO;
9+
using System.Threading;
10+
using System.Threading.Tasks;
11+
12+
[TestFixture]
13+
public class FtpRequesterTests
14+
{
15+
[Test]
16+
public async Task DownloadFtpRfcViaFtpRequester()
17+
{
18+
var url = "ftp://ftp.funet.fi/pub/standards/RFC/rfc959.txt";
19+
var requester = new FtpRequester();
20+
var request = new Request { Address = Url.Create(url) };
21+
22+
var response = await requester.RequestAsync(request, CancellationToken.None);
23+
Assert.IsNotNull(response);
24+
25+
var content = await new StreamReader(response.Content).ReadToEndAsync();
26+
Assert.AreEqual(147316, content.Length);
27+
}
28+
29+
[Test]
30+
public async Task FollowLinkToUseFtpRequesterUsingAllRequesters()
31+
{
32+
var config = Configuration.Default.WithRequesters();
33+
var context = BrowsingContext.New(config);
34+
var document = await context.OpenAsync(res => res.Content("<a href='ftp://ftp.funet.fi/pub/standards/RFC/rfc959.txt'>Download</a>"));
35+
var result = await document.QuerySelector<IHtmlAnchorElement>("a").NavigateAsync();
36+
var content = result.Body.TextContent;
37+
Assert.AreEqual(145730, content.Length);
38+
}
39+
40+
[Test]
41+
public async Task FollowLinkToUseFtpRequesterUsingStandardRequesters()
42+
{
43+
var config = Configuration.Default.WithDefaultLoader();
44+
var context = BrowsingContext.New(config);
45+
var document = await context.OpenAsync(res => res.Content("<a href='ftp://ftp.funet.fi/pub/standards/RFC/rfc959.txt'>Download</a>"));
46+
var result = await document.QuerySelector<IHtmlAnchorElement>("a").NavigateAsync();
47+
var content = result.Body.TextContent;
48+
Assert.AreEqual(0, content.Length);
49+
}
50+
}
51+
}

src/AngleSharp.Io/AngleSharp.Io.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
<Compile Include="Extensions\GeneralExtensions.cs" />
5353
<Compile Include="Dom\WebSocket.cs" />
5454
<Compile Include="Interfaces\IStorage.cs" />
55+
<Compile Include="Network\FtpRequester.cs" />
5556
<Compile Include="Network\HttpClientRequester.cs" />
5657
<Compile Include="Properties\AssemblyInfo.cs" />
5758
</ItemGroup>

src/AngleSharp.Io/ConfigurationExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public static class ConfigurationExtensions
2020
/// <returns>The new configuration.</returns>
2121
public static IConfiguration WithRequesters(this IConfiguration configuration, Action<LoaderService> setup = null)
2222
{
23-
var requesters = new IRequester[] { new HttpClientRequester(), new DataRequester() };
23+
var requesters = new IRequester[] { new HttpClientRequester(), new DataRequester(), new FtpRequester() };
2424
return configuration.WithDefaultLoader(setup, requesters);
2525
}
2626

@@ -36,7 +36,7 @@ public static IConfiguration WithRequesters(this IConfiguration configuration, A
3636
public static IConfiguration WithRequesters(this IConfiguration configuration, HttpMessageHandler httpMessageHandler, Action<LoaderService> setup = null)
3737
{
3838
var httpClient = new HttpClient(httpMessageHandler);
39-
var requesters = new IRequester[] { new HttpClientRequester(httpClient), new DataRequester() };
39+
var requesters = new IRequester[] { new HttpClientRequester(httpClient), new DataRequester(), new FtpRequester() };
4040
return configuration.WithDefaultLoader(setup, requesters);
4141
}
4242
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
namespace AngleSharp.Io.Network
2+
{
3+
using AngleSharp.Network;
4+
using AngleSharp.Network.Default;
5+
using System;
6+
using System.Net;
7+
using System.Threading;
8+
using System.Threading.Tasks;
9+
10+
public class FtpRequester : IRequester
11+
{
12+
public async Task<IResponse> RequestAsync(IRequest request, CancellationToken cancel)
13+
{
14+
var requester = FtpWebRequest.Create(request.Address.Href) as FtpWebRequest;
15+
16+
if (requester != null)
17+
{
18+
requester.Method = WebRequestMethods.Ftp.DownloadFile;
19+
requester.Credentials = new NetworkCredential("anonymous", String.Empty);
20+
21+
var response = await requester.GetResponseAsync().ConfigureAwait(false);
22+
var content = response.GetResponseStream();
23+
24+
return new Response
25+
{
26+
Address = request.Address,
27+
Content = content,
28+
StatusCode = HttpStatusCode.OK
29+
};
30+
}
31+
32+
return default(IResponse);
33+
}
34+
35+
public Boolean SupportsProtocol(String protocol)
36+
{
37+
return !String.IsNullOrEmpty(protocol) && protocol.Equals(ProtocolNames.Ftp);
38+
}
39+
}
40+
}

0 commit comments

Comments
 (0)