Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -338,3 +338,31 @@ ImageMagic/
EXE/NotForGit/
viewtube/
WebFixes/

## MacOS gitignore ##

# General
.DS_Store
__MACOSX/
.AppleDouble
.LSOverride
Icon[]

# Thumbnails
._*

# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent

# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
7 changes: 7 additions & 0 deletions HttpTransit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,13 @@ public void ProcessTransit()
string RefererUri = ClientRequest.Headers["Referer"];
if (RefererUri == "") RefererUri = null;

//check for web snapshot viewer mode
if (Program.SnapshotViewerMode)
{
new WebOne.SnapshotViewer.WebSnapshotViewer(ClientRequest, ClientResponse, Log).Handle(RequestURL);
return;
}

//check for blacklisted URL
if (CheckString(RequestURL.ToString(), ConfigFile.UrlBlackList))
{
Expand Down
54 changes: 54 additions & 0 deletions Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ public static class Program

public static string Protocols = "HTTP 1.1";
public static bool DaemonMode = false;
public static bool SnapshotViewerMode = false;
public static bool SnapshotViewerHeaded = false;
public static int JpegQuality = 85;
public static int StripHeight = 100;
public static int MinThreads = 1000;
static bool ShutdownInitiated = false;
static bool RebuildCA = false;

Expand Down Expand Up @@ -253,6 +258,13 @@ static void Main(string[] args)
return;
}

//allow up to MinThreads concurrent requests without thread pool starvation
System.Threading.ThreadPool.SetMinThreads(MinThreads, MinThreads);

//pre-warm the browser driver so the first snapshot request doesn't wait for it
if (SnapshotViewerMode)
WebOne.SnapshotViewer.ScreenshotEngine.EnsureContextAsync().GetAwaiter().GetResult();

//start the server from 1 or 2 attempts
for (int StartAttempts = 0; StartAttempts < 2; StartAttempts++)
{
Expand Down Expand Up @@ -340,6 +352,7 @@ public static void Shutdown(int Code = 0)
ShutdownInitiated = true;

if (Server != null && Server.Working) Server.Stop();
if (SnapshotViewerMode) WebOne.SnapshotViewer.ScreenshotEngine.ShutdownAsync().GetAwaiter().GetResult();

if (!DaemonMode && !Environment.HasShutdownStarted && !ShutdownInitiated) try
{
Expand Down Expand Up @@ -438,6 +451,47 @@ private static void ProcessCommandLine(string[] args)
case "--daemon":
DaemonMode = true;
break;
case "--web-snapshot-viewer":
SnapshotViewerMode = true;
Console.WriteLine("Web Snapshot Viewer mode enabled.");
break;
case "--snapshot-headed":
SnapshotViewerHeaded = true;
Console.WriteLine("Snapshot Viewer: browser will run in headed (visible) mode.");
break;
case "--quality":
if (int.TryParse(kvp.Value, out int q) && q >= 1 && q <= 100)
{
JpegQuality = q;
Console.WriteLine("JPEG quality set to {0}.", JpegQuality);
}
else
{
Console.WriteLine("Invalid --quality value: {0}. Expected a number between 1 and 100.", kvp.Value);
}
break;
case "--strip-size":
if (int.TryParse(kvp.Value, out int sh) && sh > 0)
{
StripHeight = sh;
Console.WriteLine("Strip height set to {0}px.", StripHeight);
}
else
{
Console.WriteLine("Invalid --strip-size value: {0}. Expected a positive number.", kvp.Value);
}
break;
case "--set-min-threads":
if (int.TryParse(kvp.Value, out int mt) && mt > 0)
{
MinThreads = mt;
Console.WriteLine("Min threads set to {0}.", MinThreads);
}
else
{
Console.WriteLine("Invalid --set-min-threads value: {0}. Expected a positive number.", kvp.Value);
}
break;
case "--help":
case "-?":
case "/?":
Expand Down
5 changes: 5 additions & 0 deletions WebOne.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,10 @@ fi

<ItemGroup>
<Compile Remove="EXE\**" />
<Compile Remove="tests\**" />
<EmbeddedResource Remove="EXE\**" />
<EmbeddedResource Remove="tests\**" />
<None Remove="tests\**" />
<None Remove="docs/**" />
<None Remove="EXE/**" />
<None Remove="EXE\**" />
Expand All @@ -191,6 +194,8 @@ fi
<ItemGroup>
<PackageReference Include="System.Diagnostics.PerformanceCounter" Version="4.7.0" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.7.0" />
<PackageReference Include="Microsoft.Playwright" Version="1.*" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.*" />
</ItemGroup>

<ItemGroup>
Expand Down
88 changes: 88 additions & 0 deletions tests/ScreenshotEngineTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
using System;
using System.Threading.Tasks;
using Microsoft.Playwright;
using Xunit;
using Xunit.Abstractions;

namespace SnapshotViewerTests
{
public class ScreenshotEngineTests
{
private readonly ITestOutputHelper _output;

public ScreenshotEngineTests(ITestOutputHelper output)
{
_output = output;
}

[Fact]
public async Task Firefox_LaunchesHeadless()
{
using var playwright = await Playwright.CreateAsync();
var browser = await playwright.Firefox.LaunchAsync(new BrowserTypeLaunchOptions
{
Headless = true
});

Assert.True(browser.IsConnected);
_output.WriteLine("Firefox launched OK.");
await browser.CloseAsync();
}

[Fact]
public async Task Firefox_NavigatesAndReturnsTitle()
{
using var playwright = await Playwright.CreateAsync();
await using var browser = await playwright.Firefox.LaunchAsync(new BrowserTypeLaunchOptions
{
Headless = true
});

var page = await browser.NewPageAsync();
await page.GotoAsync("https://example.com", new PageGotoOptions
{
WaitUntil = WaitUntilState.Load,
Timeout = 30000
});

string title = await page.TitleAsync();
_output.WriteLine($"Page title: {title}");

Assert.False(string.IsNullOrEmpty(title));
await page.CloseAsync();
}

[Fact]
public async Task Firefox_TakesFullPageScreenshot()
{
using var playwright = await Playwright.CreateAsync();
await using var browser = await playwright.Firefox.LaunchAsync(new BrowserTypeLaunchOptions
{
Headless = true
});

var page = await browser.NewPageAsync(new BrowserNewPageOptions
{
ViewportSize = new ViewportSize { Width = 1280, Height = 800 }
});

await page.GotoAsync("https://example.com", new PageGotoOptions
{
WaitUntil = WaitUntilState.Load,
Timeout = 30000
});

byte[] jpg = await page.ScreenshotAsync(new PageScreenshotOptions
{
FullPage = true,
Type = ScreenshotType.Jpeg,
Quality = 85
});

_output.WriteLine($"Screenshot size: {jpg.Length} bytes");

Assert.True(jpg.Length > 1000, "Screenshot should be larger than 1KB");
await page.CloseAsync();
}
}
}
24 changes: 24 additions & 0 deletions tests/SnapshotViewerTests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="Microsoft.Playwright" Version="1.58.0" />
<PackageReference Include="xunit" Version="2.5.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3" />
</ItemGroup>

<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>

</Project>
Loading