34 changed files with 11864 additions and 113 deletions
+2 -2
View File
@@ -6,8 +6,8 @@
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<Platform>x64</Platform> <!--<Platform>x64</Platform>-->
<Optimize>true</Optimize> <Optimize>false</Optimize>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
+22 -8
View File
@@ -51,13 +51,13 @@ public class ContentFilter
{ {
while (!_stop) while (!_stop)
{ {
long indexes = _dbHandler.GetUnfilteredIndexes(); List<long> indexes = _dbHandler.GetUnfilteredIndexes();
for (long i = 0; i < indexes; i++) for (int i = 0; i < indexes.Count; i++)
{ {
if (_stop) break; if (_stop) break;
Unfiltered unfiltered = _dbHandler.ReadUnfilteredWithId(i); Unfiltered unfiltered = _dbHandler.ReadUnfilteredWithId(indexes[i]);
if (unfiltered.Filtered) continue; if (unfiltered.Filtered) continue;
@@ -161,19 +161,33 @@ public class ContentFilter
for (int i = 0; i < ports.Length; i++) for (int i = 0; i < ports.Length; i++)
{ {
string? html; string? html = "";
if (ports[i] == 80) if (ports[i] == 80)
{ {
if (string.IsNullOrWhiteSpace(url1)) continue; if (string.IsNullOrWhiteSpace(url1)) continue;
html = Task.Run(() => HttpClientHelper.GetHtml(url1, 80).Result).Result; try
{
html = HttpClientHelper.GetHtml(url1, 80).GetAwaiter().GetResult();
}
catch (Exception e)
{
Console.WriteLine(e);
}
} }
else else
{ {
if (string.IsNullOrWhiteSpace(url2)) continue; if (string.IsNullOrWhiteSpace(url2)) continue;
html = Task.Run(() => HttpClientHelper.GetHtml(url2, 443).Result).Result; try
{
html = HttpClientHelper.GetHtml(url2, 443).GetAwaiter().GetResult();
}
catch (Exception e)
{
Console.WriteLine(e);
}
} }
if (string.IsNullOrWhiteSpace(html)) continue; if (string.IsNullOrWhiteSpace(html)) continue;
@@ -182,8 +196,8 @@ public class ContentFilter
if (ports[i] == 443 && string.IsNullOrWhiteSpace(title2)) { FilterHelper.GetTitle(html ,out title2); } if (ports[i] == 443 && string.IsNullOrWhiteSpace(title2)) { FilterHelper.GetTitle(html ,out title2); }
if (ports[i] == 80 && string.IsNullOrWhiteSpace(description1)) { FilterHelper.GetDescription(html, out description1); } if (ports[i] == 80 && string.IsNullOrWhiteSpace(description1)) { FilterHelper.GetDescription(html, out description1); }
if (ports[i] == 443 && string.IsNullOrWhiteSpace(description2)) { FilterHelper.GetDescription(html, out description2); } if (ports[i] == 443 && string.IsNullOrWhiteSpace(description2)) { FilterHelper.GetDescription(html, out description2); }
if (ports[i] == 80 && !robotsTxt1) { robotsTxt1 = Task.Run(() => HttpClientHelper.HasRobotsTxt(url1, 80).Result).Result; } if (ports[i] == 80 && !robotsTxt1) { robotsTxt1 = HttpClientHelper.HasRobotsTxt(url1, 80).GetAwaiter().GetResult(); }
if (ports[i] == 443 && !robotsTxt2) { robotsTxt2 = Task.Run(() => HttpClientHelper.HasRobotsTxt(url2, 443).Result).Result; } if (ports[i] == 443 && !robotsTxt2) { robotsTxt2 = HttpClientHelper.HasRobotsTxt(url2, 443).GetAwaiter().GetResult(); }
} }
Filtered siteData = new() Filtered siteData = new()
+39 -6
View File
@@ -33,7 +33,7 @@ public class IpScanner
_unfilteredQueue = unfilteredQueue; _unfilteredQueue = unfilteredQueue;
_resumeQueue = resumeQueue; _resumeQueue = resumeQueue;
SetTimeout(128); SetTimeout(64);
} }
public void SetTimeout(int milliseconds) public void SetTimeout(int milliseconds)
@@ -41,7 +41,7 @@ public class IpScanner
_timeout = milliseconds; _timeout = milliseconds;
} }
public WaitHandle[] Start(int threads) public List<WaitHandle[]> Start(int threads)
{ {
int threadsAmount = 0; int threadsAmount = 0;
if (threads % 2 == 0) if (threads % 2 == 0)
@@ -49,7 +49,22 @@ public class IpScanner
threadsAmount = 256 / threads; threadsAmount = 256 / threads;
} }
WaitHandle[] waitHandles = new WaitHandle[threads]; WaitHandle[] waitHandle1;
WaitHandle[] waitHandle2;
if (threads <= 64)
{
waitHandle1 = new WaitHandle[threads];
waitHandle2 = new WaitHandle[threads];
}
else
{
waitHandle1 = new WaitHandle[64];
waitHandle2 = new WaitHandle[64];
}
int counter = 0;
int counter2 = 0;
for (int i = 0; i < threads; i++) for (int i = 0; i < threads; i++)
{ {
@@ -63,15 +78,32 @@ public class IpScanner
Handle = handle Handle = handle
}; };
waitHandles[i] = handle; if (i < 64)
{
waitHandle1[counter] = handle;
counter++;
}
else
{
waitHandle2[counter2] = handle;
counter2++;
}
Thread f = new (Scan!); Thread f = new (Scan!);
f.Start(scanSettings); f.Start(scanSettings);
Console.WriteLine($"Scanner thread ({i}) started"); Console.WriteLine($"Scanner thread ({i}) started");
Thread.Sleep(1000); Thread.Sleep(100);
} }
List<WaitHandle[]> waitHandles = new();
Console.WriteLine("Waithandle 1 count = " + waitHandle1.Length);
Console.WriteLine("Waithandle 2 count = " + waitHandle2.Length);
waitHandles.Add(waitHandle1);
waitHandles.Add(waitHandle2);
return waitHandles; return waitHandles;
} }
@@ -193,7 +225,8 @@ public class IpScanner
resumeObject.FirstByte = i; resumeObject.FirstByte = i;
break; break;
} }
//Console.WriteLine($"Thread ({scanSettings.ThreadNumber}) is at index ({i}) out of ({scanSettings.End}). Remaining ({scanSettings.End - i})");
Console.WriteLine($"Thread ({scanSettings.ThreadNumber}) is at index ({i}) out of ({scanSettings.End}). Remaining ({scanSettings.End - i})");
} }
_resumeQueue.Enqueue(resumeObject); _resumeQueue.Enqueue(resumeObject);
+8 -3
View File
@@ -59,9 +59,12 @@ public class ThreadHandler
{ {
Thread.Sleep(5000); // Let the database handler instantiate and warm up first. Thread.Sleep(5000); // Let the database handler instantiate and warm up first.
WaitHandle[] wait = _ipScanner.Start(64); List<WaitHandle[]> wait = _ipScanner.Start(128);
WaitHandle.WaitAll(wait); for (int i = 0; i < wait.Count; i++)
{
WaitHandle.WaitAll(wait[i]);
}
Console.WriteLine("Scanner finished"); Console.WriteLine("Scanner finished");
@@ -70,6 +73,8 @@ public class ThreadHandler
private void StartContentFilter() private void StartContentFilter()
{ {
Thread.Sleep(5000);
WaitHandle[] wait = _contentFilter.Start(); WaitHandle[] wait = _contentFilter.Start();
WaitHandle.WaitAll(wait); WaitHandle.WaitAll(wait);
@@ -96,7 +101,7 @@ public class ThreadHandler
private void StartDiscardedDbHandler() private void StartDiscardedDbHandler()
{ {
WaitHandle[] wait = _dbHandler.Start(2); WaitHandle[] wait = _dbHandler.Start(4);
WaitHandle.WaitAll(wait); WaitHandle.WaitAll(wait);
+5 -4
View File
@@ -18,9 +18,9 @@ public static class HttpClientHelper
} }
client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Clear();
client.Timeout = TimeSpan.FromSeconds(30); client.Timeout = TimeSpan.FromSeconds(1);
HttpResponseMessage? response = null; HttpResponseMessage? response;
try try
{ {
@@ -28,10 +28,10 @@ public static class HttpClientHelper
} }
catch catch
{ {
// return "";
} }
if (response is null || !response.IsSuccessStatusCode) if (!response.IsSuccessStatusCode)
{ {
return ""; return "";
} }
@@ -53,6 +53,7 @@ public static class HttpClientHelper
} }
client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Clear();
client.Timeout = TimeSpan.FromSeconds(1);
HttpResponseMessage? response = null; HttpResponseMessage? response = null;
Binary file not shown.
Binary file not shown.
Binary file not shown.
+112 -16
View File
@@ -1,4 +1,5 @@
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Diagnostics;
using Microsoft.Data.Sqlite; using Microsoft.Data.Sqlite;
using Models.Model.Backend; using Models.Model.Backend;
using Models.Model.External; using Models.Model.External;
@@ -24,18 +25,45 @@ public class DbHandler
" VALUES (@ip1, @ip2, @ip3, @ip4, @port1, @port2, @filtered)"; " VALUES (@ip1, @ip2, @ip3, @ip4, @port1, @port2, @filtered)";
private const string InsertIntoFiltered = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY;" + private const string InsertIntoFiltered = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY;" +
" PRAGMA journal_mode = MEMORY; PRAGMA foreign_keys = off;" + " PRAGMA journal_mode = MEMORY; PRAGMA foreign_keys = on;" +
" INSERT INTO Filtered (Ip1, Ip2, Ip3, Ip4, Port1, Port2, Title1, Title2," + " INSERT INTO Filtered (Ip1, Ip2, Ip3, Ip4, Port1, Port2, Title1, Title2," +
" Description1, Description2, Url1, Url2, ServerType1, ServerType2," + " Description1, Description2, Url1, Url2, ServerType1, ServerType2," +
" RobotsTXT1, RobotsTXT2, HttpVersion1, HttpVersion2, CertificateIssuerCountry," + " RobotsTXT1, RobotsTXT2, HttpVersion1, HttpVersion2, CertificateIssuerCountry," +
" CertificateOrganizationName, IpV6, TlsVersion, CipherSuite, KeyExchangeAlgorithm," + " CertificateOrganizationName, IpV6, TlsVersion, CipherSuite, KeyExchangeAlgorithm," +
" PublicKeyType1, PublicKeyType2, PublicKeyType3, AcceptEncoding1, AcceptEncoding2," + " PublicKeyType1, PublicKeyType2, PublicKeyType3, AcceptEncoding1, AcceptEncoding2," +
" ALPN, Connection1, Connection2) VALUES (@ip1, @ip2, @ip3, @ip4, @port1, @port2, " + " ALPN, Connection1, Connection2) VALUES (@ip1, @ip2, @ip3, @ip4, @port1, @port2, " +
" @title1, @title2, @description1, @description2, @url1, @url2, @serverType1," + " @title1, @title2, @description1, @description2, @url1, @url2, " +
" @serverType2, @robotsTXT1, @robotsTXT2, @httpVersion1, @httpVersion2," + " (SELECT ServerId FROM ServerType WHERE Type = @serverType1), " +
" @certificateIssuerCountry, @certificateOrganizationName, @ipV6, @tlsVersion," + " (SELECT ServerId FROM ServerType WHERE Type = @serverType2), " +
" @cipherSuite, @keyExchangeAlgorithm, @publicKeyType1, @publicKeyType2," + " @robotsTXT1, @robotsTXT2," +
" @publicKeyType3, @acceptEncoding1, @acceptEncoding2, @aLPN, @connection1, @connection2)"; " (SELECT HttpId FROM HttpVersion WHERE Version = @httpVersion1)," +
" (SELECT HttpId FROM HttpVersion WHERE Version = @httpVersion2)," +
" (SELECT CertificateIssuerId FROM CertificateIssuerCountry WHERE Country = @certificateIssuerCountry)," +
" (SELECT CertificateOrganizationId FROM CertificateOrganizationName WHERE Name = @certificateOrganizationName), " +
" @ipV6, " +
" (SELECT TlsId FROM TlsVersion WHERE Version = @tlsVersion)," +
" (SELECT CipherId FROM CipherSuite WHERE Suite = @cipherSuite)," +
" (SELECT KeyExchangeId FROM KeyExchangeAlgorithm WHERE Algorithm = @keyExchangeAlgorithm)," +
" (SELECT PublicKeyId FROM PublicKeyType WHERE Type = @publicKeyType1)," +
" (SELECT PublicKeyId FROM PublicKeyType WHERE Type = @publicKeyType2)," +
" (SELECT PublicKeyId FROM PublicKeyType WHERE Type = @publicKeyType3)," +
" (SELECT AcceptId FROM AcceptEncoding WHERE Encoding = @acceptEncoding1)," +
" (SELECT AcceptId FROM AcceptEncoding WHERE Encoding = @acceptEncoding2)," +
" (SELECT ALPNId FROM ALPN WHERE ALPNValue = @aLPN)," +
" (SELECT ConnectionId FROM Connection WHERE ConnectionValue = @connection1)," +
" (SELECT ConnectionId FROM Connection WHERE ConnectionValue = @connection2))";
private const string InsertIntoFilteredServerType = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY; PRAGMA journal_mode = MEMORY; INSERT OR IGNORE INTO ServerType (Type) VALUES (@type)";
private const string InsertIntoFilteredHttpVersion = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY; PRAGMA journal_mode = MEMORY; INSERT OR IGNORE INTO HttpVersion (Version) VALUES (@version)";
private const string InsertIntoFilteredCertificateIssuerCountry = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY; PRAGMA journal_mode = MEMORY; INSERT OR IGNORE INTO CertificateIssuerCountry (Country) VALUES (@country)";
private const string InsertIntoFilteredCertificateOrganizationName = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY; PRAGMA journal_mode = MEMORY; INSERT OR IGNORE INTO CertificateOrganizationName (Name) VALUES (@name)";
private const string InsertIntoFilteredTlsVersion = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY; PRAGMA journal_mode = MEMORY; INSERT OR IGNORE INTO TlsVersion (Version) VALUES (@version)";
private const string InsertIntoFilteredCipherSuite = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY; PRAGMA journal_mode = MEMORY; INSERT OR IGNORE INTO CipherSuite (Suite) VALUES (@suite)";
private const string InsertIntoFilteredKeyExchangeAlgorithm = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY; PRAGMA journal_mode = MEMORY; INSERT OR IGNORE INTO KeyExchangeAlgorithm (Algorithm) VALUES (@algorithm)";
private const string InsertIntoFilteredPublicKeyType = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY; PRAGMA journal_mode = MEMORY; INSERT OR IGNORE INTO PublicKeyType (Type) VALUES (@type)";
private const string InsertIntoFilteredAcceptEncoding = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY; PRAGMA journal_mode = MEMORY; INSERT OR IGNORE INTO AcceptEncoding (Encoding) VALUES (@encoding)";
private const string InsertIntoFilteredALPN = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY; PRAGMA journal_mode = MEMORY; INSERT OR IGNORE INTO ALPN (ALPNValue) VALUES (@alpnValue)";
private const string InsertIntoFilteredConnection = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY; PRAGMA journal_mode = MEMORY; INSERT OR IGNORE INTO Connection (ConnectionValue) VALUES (@connectionValue)";
private const string InsertIntoDiscarded = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY;" + private const string InsertIntoDiscarded = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY;" +
" PRAGMA journal_mode = MEMORY; PRAGMA foreign_keys = off;" + " PRAGMA journal_mode = MEMORY; PRAGMA foreign_keys = off;" +
@@ -48,7 +76,7 @@ public class DbHandler
" VALUES (@threadNumber, @startRange, @endRange, @firstByte, @secondByte, @thirdByte, @fourthByte);"; " VALUES (@threadNumber, @startRange, @endRange, @firstByte, @secondByte, @thirdByte, @fourthByte);";
private const string ReadUnfilteredStatement = "SELECT * FROM Unfiltered WHERE Id = @id;"; private const string ReadUnfilteredStatement = "SELECT * FROM Unfiltered WHERE Id = @id;";
private const string ReadUnfilteredIdsStatement = "SELECT Id FROM Unfiltered WHERE Id != 0 ORDER BY Id DESC LIMIT 1;"; private const string ReadUnfilteredIdsStatement = "SELECT Id FROM Unfiltered WHERE Filtered == 0;";
private const string ReadFilteredStatement = "SELECT Title2, Url2 FROM Filtered WHERE (Url2 NOT NULL AND Url2 != '') AND (Title2 NOT NULL AND Title2 != '') ORDER BY Url2 DESC;"; private const string ReadFilteredStatement = "SELECT Title2, Url2 FROM Filtered WHERE (Url2 NOT NULL AND Url2 != '') AND (Title2 NOT NULL AND Title2 != '') ORDER BY Url2 DESC;";
private const string ReadFilteredIdsStatement = "SELECT Id FROM Filtered WHERE Id != 0 ORDER BY Id DESC LIMIT 1;"; private const string ReadFilteredIdsStatement = "SELECT Id FROM Filtered WHERE Id != 0 ORDER BY Id DESC LIMIT 1;";
private const string ReadFilteredIpStatement = "SELECT Ip1, Ip2, Ip3, Ip4 FROM Filtered WHERE Ip1 == @ip1 AND Ip2 == @ip1 AND Ip3 == @ip1 AND Ip4 == @ip1 ORDER BY Ip1 DESC LIMIT 1;"; private const string ReadFilteredIpStatement = "SELECT Ip1, Ip2, Ip3, Ip4 FROM Filtered WHERE Ip1 == @ip1 AND Ip2 == @ip1 AND Ip3 == @ip1 AND Ip4 == @ip1 ORDER BY Ip1 DESC LIMIT 1;";
@@ -270,8 +298,75 @@ public class DbHandler
using SqliteConnection connection = new(_filteredConnectionString); using SqliteConnection connection = new(_filteredConnectionString);
connection.Open(); connection.Open();
using SqliteCommand command = new(InsertIntoFiltered, connection); SqliteCommand command = new(InsertIntoFilteredServerType, connection);
command.Parameters.AddWithValue("@type", filtered.ServerType1);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFilteredServerType, connection);
command.Parameters.AddWithValue("@type", filtered.ServerType2);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFilteredHttpVersion, connection);
command.Parameters.AddWithValue("@version", filtered.HttpVersion1);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFilteredHttpVersion, connection);
command.Parameters.AddWithValue("@version", filtered.HttpVersion2);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFilteredCertificateIssuerCountry, connection);
command.Parameters.AddWithValue("@country", filtered.CertificateIssuerCountry);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFilteredCertificateOrganizationName, connection);
command.Parameters.AddWithValue("@name", filtered.CertificateOrganizationName);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFilteredTlsVersion, connection);
command.Parameters.AddWithValue("@version", filtered.TlsVersion);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFilteredCipherSuite, connection);
command.Parameters.AddWithValue("@suite", filtered.CipherSuite);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFilteredKeyExchangeAlgorithm, connection);
command.Parameters.AddWithValue("@algorithm", filtered.KeyExchangeAlgorithm);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFilteredPublicKeyType, connection);
command.Parameters.AddWithValue("@type", filtered.PublicKeyType1);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFilteredPublicKeyType, connection);
command.Parameters.AddWithValue("@type", filtered.PublicKeyType2);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFilteredPublicKeyType, connection);
command.Parameters.AddWithValue("@type", filtered.PublicKeyType3);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFilteredAcceptEncoding, connection);
command.Parameters.AddWithValue("@encoding", filtered.AcceptEncoding1);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFilteredAcceptEncoding, connection);
command.Parameters.AddWithValue("@encoding", filtered.AcceptEncoding2);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFilteredALPN, connection);
command.Parameters.AddWithValue("@alpnValue", filtered.ALPN);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFilteredConnection, connection);
command.Parameters.AddWithValue("@connectionValue", filtered.Connection1);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFilteredConnection, connection);
command.Parameters.AddWithValue("@connectionValue", filtered.Connection2);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFiltered, connection);
command.Parameters.AddWithValue("@ip1", filtered.Ip.Ip1); command.Parameters.AddWithValue("@ip1", filtered.Ip.Ip1);
command.Parameters.AddWithValue("@ip2", filtered.Ip.Ip2); command.Parameters.AddWithValue("@ip2", filtered.Ip.Ip2);
command.Parameters.AddWithValue("@ip3", filtered.Ip.Ip3); command.Parameters.AddWithValue("@ip3", filtered.Ip.Ip3);
@@ -304,8 +399,9 @@ public class DbHandler
command.Parameters.AddWithValue("@aLPN", filtered.ALPN); command.Parameters.AddWithValue("@aLPN", filtered.ALPN);
command.Parameters.AddWithValue("@connection1", filtered.Connection1); command.Parameters.AddWithValue("@connection1", filtered.Connection1);
command.Parameters.AddWithValue("@connection2", filtered.Connection2); command.Parameters.AddWithValue("@connection2", filtered.Connection2);
_ = command.ExecuteNonQuery(); _ = command.ExecuteNonQuery();
command.Dispose();
connection.Close(); connection.Close();
} }
@@ -372,10 +468,8 @@ public class DbHandler
return unfiltered; return unfiltered;
} }
public long GetUnfilteredIndexes() public List<long> GetUnfilteredIndexes()
{ {
long rowId = 0;
using SqliteConnection connection = new(_unfilteredConnectionString); using SqliteConnection connection = new(_unfilteredConnectionString);
connection.Open(); connection.Open();
@@ -384,15 +478,17 @@ public class DbHandler
if (!reader.HasRows) if (!reader.HasRows)
{ {
return 0; return [];
} }
List<long> ids = [];
while (reader.Read()) while (reader.Read())
{ {
rowId = reader.GetInt64(0); ids.Add(reader.GetInt64(0));
} }
return rowId; return ids;
} }
public long GetFilteredIndexes() public long GetFilteredIndexes()
@@ -640,7 +736,7 @@ public class DbHandler
{ {
string databaseName = $"Data Source={_basePath}/Models/Discarded{threadNumber}.db"; string databaseName = $"Data Source={_basePath}/Models/Discarded{threadNumber}.db";
const string createStatement = "CREATE TABLE IF NOT EXISTS Discarded (Id INTEGER NOT NULL, Ip1 TEXT NOT NULL, Ip2 TEXT NOT NULL, Ip3 TEXT NOT NULL, Ip4 TEXT NOT NULL, ResponseCode INTEGER NOT NULL, PRIMARY KEY(Id AUTOINCREMENT))"; const string createStatement = "CREATE TABLE IF NOT EXISTS Discarded (Id INTEGER NOT NULL, Ip1 INTEGER NOT NULL, Ip2 INTEGER NOT NULL, Ip3 INTEGER NOT NULL, Ip4 INTEGER NOT NULL, ResponseCode INTEGER NOT NULL, PRIMARY KEY(Id AUTOINCREMENT))";
_discardedConnectionStrings.Add(databaseName); _discardedConnectionStrings.Add(databaseName);
-1
View File
@@ -8,6 +8,5 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Data.Sqlite" Version="8.0.10" /> <PackageReference Include="Microsoft.Data.Sqlite" Version="8.0.10" />
<PackageReference Include="SQLite" Version="3.13.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>
-3
View File
@@ -1,3 +0,0 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cbackend/@EntryIndexedValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cinternal/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
+94 -19
View File
@@ -1,10 +1,68 @@
VACUUM; VACUUM;
CREATE TABLE IF NOT EXISTS "ServerType" (
"ServerId" INTEGER PRIMARY KEY AUTOINCREMENT,
"Type" TEXT NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS "HttpVersion" (
"HttpId" INTEGER PRIMARY KEY AUTOINCREMENT,
"Version" TEXT NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS "CertificateIssuerCountry" (
"CertificateIssuerId" INTEGER PRIMARY KEY AUTOINCREMENT,
"Country" TEXT NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS "CertificateOrganizationName" (
"CertificateOrganizationId" INTEGER PRIMARY KEY AUTOINCREMENT,
"Name" TEXT NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS "TlsVersion" (
"TlsId" INTEGER PRIMARY KEY AUTOINCREMENT,
"Version" TEXT NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS "CipherSuite" (
"CipherId" INTEGER PRIMARY KEY AUTOINCREMENT,
"Suite" TEXT NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS "KeyExchangeAlgorithm" (
"KeyExchangeId" INTEGER PRIMARY KEY AUTOINCREMENT,
"Algorithm" TEXT NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS "PublicKeyType" (
"PublicKeyId" INTEGER PRIMARY KEY AUTOINCREMENT,
"Type" TEXT NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS "AcceptEncoding" (
"AcceptId" INTEGER PRIMARY KEY AUTOINCREMENT,
"Encoding" TEXT NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS "ALPN" (
"ALPNId" INTEGER PRIMARY KEY AUTOINCREMENT,
"ALPNValue" TEXT NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS "Connection" (
"ConnectionId" INTEGER PRIMARY KEY AUTOINCREMENT,
"ConnectionValue" TEXT NOT NULL UNIQUE
);
DROP TABLE Filtered; DROP TABLE Filtered;
CREATE TABLE "Filtered" ( CREATE TABLE "Filtered" (
"Id" INTEGER NOT NULL, "Id" INTEGER NOT NULL,
"Ip" TEXT NOT NULL, "Ip1" INTEGER NOT NULL,
"Ip2" INTEGER NOT NULL,
"Ip3" INTEGER NOT NULL,
"Ip4" INTEGER NOT NULL,
"Port1" INTEGER NOT NULL, "Port1" INTEGER NOT NULL,
"Port2" INTEGER NOT NULL, "Port2" INTEGER NOT NULL,
"Title1" TEXT NOT NULL, "Title1" TEXT NOT NULL,
@@ -13,25 +71,42 @@ CREATE TABLE "Filtered" (
"Description2" TEXT NOT NULL, "Description2" TEXT NOT NULL,
"Url1" TEXT NOT NULL, "Url1" TEXT NOT NULL,
"Url2" TEXT NOT NULL, "Url2" TEXT NOT NULL,
"ServerType1" TEXT NOT NULL, "ServerType1" INTEGER NOT NULL,
"ServerType2" TEXT NOT NULL, "ServerType2" INTEGER NOT NULL,
"RobotsTXT1" TEXT NOT NULL, "RobotsTXT1" TEXT NOT NULL,
"RobotsTXT2" TEXT NOT NULL, "RobotsTXT2" TEXT NOT NULL,
"HttpVersion1" TEXT NOT NULL, "HttpVersion1" INTEGER NOT NULL,
"HttpVersion2" TEXT NOT NULL, "HttpVersion2" INTEGER NOT NULL,
"CertificateIssuerCountry" TEXT NOT NULL, "CertificateIssuerCountry" INTEGER NOT NULL,
"CertificateOrganizationName" TEXT NOT NULL, "CertificateOrganizationName" INTEGER NOT NULL,
"IpV6" TEXT NOT NULL, "IpV6" TEXT NOT NULL,
"TlsVersion" TEXT NOT NULL, "TlsVersion" INTEGER NOT NULL,
"CipherSuite" TEXT NOT NULL, "CipherSuite" INTEGER NOT NULL,
"KeyExchangeAlgorithm" TEXT NOT NULL, "KeyExchangeAlgorithm" INTEGER NOT NULL,
"PublicKeyType1" TEXT NOT NULL, "PublicKeyType1" INTEGER NOT NULL,
"PublicKeyType2" TEXT NOT NULL, "PublicKeyType2" INTEGER NOT NULL,
"PublicKeyType3" TEXT NOT NULL, "PublicKeyType3" INTEGER NOT NULL,
"AcceptEncoding1" TEXT NOT NULL, "AcceptEncoding1" INTEGER NOT NULL,
"AcceptEncoding2" TEXT NOT NULL, "AcceptEncoding2" INTEGER NOT NULL,
"ALPN" TEXT NOT NULL, "ALPN" INTEGER NOT NULL,
"Connection1" TEXT NOT NULL, "Connection1" INTEGER NOT NULL,
"Connection2" TEXT NOT NULL, "Connection2" INTEGER NOT NULL,
PRIMARY KEY("Id" AUTOINCREMENT) PRIMARY KEY("Id" AUTOINCREMENT),
FOREIGN KEY("ALPN") REFERENCES "ALPN"("ALPNId"),
FOREIGN KEY("AcceptEncoding1") REFERENCES "AcceptEncoding"("AcceptId"),
FOREIGN KEY("AcceptEncoding2") REFERENCES "AcceptEncoding"("AcceptId"),
FOREIGN KEY("CertificateIssuerCountry") REFERENCES "CertificateIssuerCountry"("CertificateIssuerId"),
FOREIGN KEY("CertificateOrganizationName") REFERENCES "CertificateOrganizationName"("CertificateOrganizationId"),
FOREIGN KEY("CipherSuite") REFERENCES "CipherSuite"("CipherId"),
FOREIGN KEY("Connection1") REFERENCES "Connection"("ConnectionId"),
FOREIGN KEY("Connection2") REFERENCES "Connection"("ConnectionId"),
FOREIGN KEY("HttpVersion1") REFERENCES "HttpVersion"("HttpId"),
FOREIGN KEY("HttpVersion2") REFERENCES "HttpVersion"("HttpId"),
FOREIGN KEY("KeyExchangeAlgorithm") REFERENCES "KeyExchangeAlgorithm"("KeyExchangeId"),
FOREIGN KEY("PublicKeyType1") REFERENCES "PublicKeyType"("PublicKeyId"),
FOREIGN KEY("PublicKeyType2") REFERENCES "PublicKeyType"("PublicKeyId"),
FOREIGN KEY("PublicKeyType3") REFERENCES "PublicKeyType"("PublicKeyId"),
FOREIGN KEY("ServerType1") REFERENCES "ServerType"("ServerId"),
FOREIGN KEY("ServerType2") REFERENCES "ServerType"("ServerId"),
FOREIGN KEY("TlsVersion") REFERENCES "TlsVersion"("TlsId")
) )
+34 -9
View File
@@ -1,10 +1,11 @@
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using MessagePack; using AspNetCoreRateLimit;
using Microsoft.AspNetCore.Cors.Infrastructure; using Microsoft.AspNetCore.HttpOverrides;
using Models.Model.External; using Models.Model.External;
using NetMQ; using NetMQ;
using NetMQ.Sockets; using NetMQ.Sockets;
const string myAllowSpecificOrigins = "_myAllowSpecificOrigins";
WebApplicationBuilder builder = WebApplication.CreateSlimBuilder(args); WebApplicationBuilder builder = WebApplication.CreateSlimBuilder(args);
@@ -15,16 +16,40 @@ builder.Services.ConfigureHttpJsonOptions(options =>
builder.Services.AddCors(options => builder.Services.AddCors(options =>
{ {
options.AddPolicy("CorsPolicy", x => x.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader().Build()); options.AddPolicy(name: myAllowSpecificOrigins, x => x.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
}); });
// Add memory cache and rate limiting services
builder.Services.AddMemoryCache();
builder.Services.Configure<IpRateLimitOptions>(options =>
{
options.GeneralRules =
[
new()
{
Endpoint = "*", // Apply to all endpoints
Period = "10s", // Rate limiting window of 10 second
Limit = 5 // Maximum 5 requests per 10 seconds
}
];
});
builder.Services.AddInMemoryRateLimiting();
builder.Services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
WebApplication app = builder.Build(); WebApplication app = builder.Build();
app.UseCors(); app.UseForwardedHeaders(new()
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
app.UseIpRateLimiting(); // Apply IP-based rate limiting middleware
app.UseCors(myAllowSpecificOrigins);
RouteGroupBuilder progressApi = app.MapGroup("/progress"); RouteGroupBuilder progressApi = app.MapGroup("/progress");
progressApi.AllowAnonymous();
progressApi.DisableAntiforgery();
progressApi.MapGet("/", () => progressApi.MapGet("/", () =>
{ {
CommunicationObject communicationObject = new() CommunicationObject communicationObject = new()
@@ -43,8 +68,8 @@ progressApi.MapGet("/", () =>
return JsonSerializer.Deserialize<ScanningStatus>(msg); return JsonSerializer.Deserialize<ScanningStatus>(msg);
}); });
/*
RouteGroupBuilder searchApi = app.MapGroup("/search"); RouteGroupBuilder searchApi = app.MapGroup("/search");
progressApi.AllowAnonymous();
searchApi.MapGet("/{term}", (string term) => searchApi.MapGet("/{term}", (string term) =>
{ {
CommunicationObject communicationObject = new(); CommunicationObject communicationObject = new();
@@ -61,11 +86,11 @@ searchApi.MapGet("/{term}", (string term) =>
return JsonSerializer.Deserialize<SearchResults?>(msg); return JsonSerializer.Deserialize<SearchResults?>(msg);
}); });
*/
app.Run(); app.Run();
[JsonSerializable(typeof(ScanningStatus))] [JsonSerializable(typeof(ScanningStatus))]
[JsonSerializable(typeof(SearchResults))] //[JsonSerializable(typeof(SearchResults))]
[JsonSerializable(typeof(CommunicationObject))] [JsonSerializable(typeof(CommunicationObject))]
internal partial class AppJsonSerializerContext : JsonSerializerContext internal partial class AppJsonSerializerContext : JsonSerializerContext
{ {
+1
View File
@@ -9,6 +9,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
<PackageReference Include="NetMQ" Version="4.0.1.13" /> <PackageReference Include="NetMQ" Version="4.0.1.13" />
</ItemGroup> </ItemGroup>
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"Logging": { "Logging": {
"LogLevel": { "LogLevel": {
"Default": "Information", "Default": "Warning",
"Microsoft.AspNetCore": "Warning" "Microsoft.AspNetCore": "Warning"
} }
}, },
+6 -31
View File
@@ -1,32 +1,7 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> <wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003A02000006pdb6Low_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003FILViewer_003Fd17d4b69379a42eb90f15b17ef6c846a5400_003F39_003F1eeed291_003F02000006pdb6Low_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003A0200000Cpdb6Low_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003FILViewer_003Fb53c196a821648e4ae3b142a6ae58d7b9400_003Fa8_003F21a43479_003F0200000Cpdb6Low_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003A02000007pdb1Low_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003FILViewer_003F096da63313a8436fb75089601a728c765200_003Fbb_003Ff6383783_003F02000007pdb1Low_002Ecs_002Fz_003A2_002D1/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003A02000011pdb3Low_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003FILViewer_003F7c3ed02c2ce44598b7f304f8ac45e58f8600_003F6d_003F99b875d1_003F02000011pdb3Low_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003A02000007pdb1Low_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003FILViewer_003F357247e747614c8297021dd08d79da3d5200_003Ff2_003Fc4ae8c87_003F02000007pdb1Low_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADirectoryInfo_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003Fe4ec446cfe0489bc3ef68a45c6766d183e999ebdc657e94fb1ad059de2bb9_003FDirectoryInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003A0200000Fpdb2Low_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003FILViewer_003F069d64e89a7540319e3e5355db9fd8fa8600_003Fac_003F604d330e_003F0200000Fpdb2Low_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AHttpResponseMessage_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F85e97f467d698c9e98eae9e3a1b39d58541173e57992d8f7111eabdd3db3526_003FHttpResponseMessage_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003A02000010pdb3Low_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003FILViewer_003F80cf8253b0c2409096d0c0e368300af28200_003Fdd_003F8098fc19_003F02000010pdb3Low_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ARateLimitRule_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F8fbca8b1bca27d45830c443b2c773d979015ea216430366f285514a39fc0b9_003FRateLimitRule_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003A02000011pdb4Low_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003FILViewer_003F1f6cfdd1e3a14f6390237f6ab98b06af8000_003F0d_003Febdca535_003F02000011pdb4Low_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AThread_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F693e634d7742afaf486acd69d84fe2a9e1ee1b11ba84f29cd1d67668d20dd59_003FThread_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003A02000013pdb13Low_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003FILViewer_003F8d5d3174bfdc4554bbaac3d5e7c564a29800_003F64_003F42d93916_003F02000013pdb13Low_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AAttributes_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F9a4cb3a98df697f884fa5f45bc79e4291fa3e948c7f42560e14678e12055e_003FAttributes_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AAttribute_002ECoreCLR_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003Fbb9be2cb8efb72a7d2286fbdd10a293b55b3e2a912f49fac6a7719673268e4b_003FAttribute_002ECoreCLR_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AConcurrentQueue_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003Fb049a159646b52d2dd6ced21de315f79dff86421243e94ffd4f29c6f7e4df25_003FConcurrentQueue_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AConsole_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F2ccd2056ec55b7b67558d52e32a887ed5ac7e346fc429b218c188d0a99cb5be_003FConsole_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AFormatters_002EMessagePack_002EGeneratedMessagePackResolver_002EModels_002EModel_002EExternal_002ECommunicationObjectFormatter_002Eg_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F5029ca69753a60cb407b1053f5834320dadee066_003FFormatters_002EMessagePack_002EGeneratedMessagePackResolver_002EModels_002EModel_002EExternal_002ECommunicationObjectFormatter_002Eg_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AFormatters_002EMessagePack_002EGeneratedMessagePackResolver_002EModels_002EModel_002EExternal_002ESearchResultsFormatter_002Eg_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F99b5d033f8bfb58a6a753ca88a3d956f2228bd48_003FFormatters_002EMessagePack_002EGeneratedMessagePackResolver_002EModels_002EModel_002EExternal_002ESearchResultsFormatter_002Eg_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AFuture_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F13cbfe6856867dd1ed4e39575e46d816dae2a146a8ceec8f76b5897f5e0fe_003FFuture_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AHttpClient_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F60038225224a9318597b3232280390933d3c3fe85d9ed859a7e4825915eb1c_003FHttpClient_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AHttpContent_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F5a55e5df9328b51021ba85b8f12ff49eca8772dba9772c0d61d5e28edf255c_003FHttpContent_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AHttpMethodAttribute_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F2e4732e712a98f9ac0d080ac68669b3db6d98781e0d5ad89886cb6bcc890b18_003FHttpMethodAttribute_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIFormatterResolver_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003Fc7d856f45ddf907f9face6c2bdba7836cc70fed4bb2b8ebd83ee6917584af3_003FIFormatterResolver_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIOThread_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F125fae6d49819da7be4fb21fbb4a936a7ec325971cf9264a24af55bf7111ad8_003FIOThread_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIPStatus_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F8fe420eaf60c4dfca87ce1d5f1cdfa4816200_003Fbd_003F71bcce16_003FIPStatus_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AMessagePackReader_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F5cffb8c94881849b6aa8abe7ba5e7cafe05d991f859903020362d6aac371_003FMessagePackReader_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AMessagePackSerializer_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003Fe5f8b0187e62d74a4b9fefd657c192dab367bb342ef5ffbd90a4ed2ea428ec7a_003FMessagePackSerializer_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AOutgoingSocketExtensions_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003Fc4824d483bf85fa615ad2125f13f6d75788d45d1510ec1cfb8226831da54f_003FOutgoingSocketExtensions_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APingOptions_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F77bf2fbffc5491eadd62f1dbebc233798cd7fcb9b39ab7ee3bb35519f4d94ecc_003FPingOptions_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APing_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F3080b18e3637ea741b5b65abd6aee06e41494a82a58b3e2ed87d4ddb5cc62_003FPing_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APing_002ERawSocket_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F2f645da43e51b8be94c9217511b45c23384f041ffa9aad041f0ddc158d732f0_003FPing_002ERawSocket_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APing_002EUnix_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F8d57f5f5fd3290d6a89a5b767ad89988dd893c988eba430cd461b8b88d7ad9d_003FPing_002EUnix_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ARep_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003Feea8e921c916164ccc376e162da148b8215450dfae96e08bdd29119165c67f_003FRep_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AReq_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F33fafcc2bb6e91ae8abb5a52936d39cd93951ad9208861e758ca93efa619eaf3_003FReq_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATask_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F35f3a54f5acb408a3e219b2de039f1a39557b7e4515f11238cba07b60c0ce_003FTask_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATextWriter_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003Fdda89b2ed0975050b6847325357a756a5866a5435e3ddb4feff535ba36facb7_003FTextWriter_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>
+24
View File
@@ -0,0 +1,24 @@
# Nuxt dev/build outputs
.output
.data
.nuxt
.nitro
.cache
dist
# Node dependencies
node_modules
# Logs
logs
*.log
# Misc
.DS_Store
.fleet
.idea
# Local env files
.env
.env.*
!.env.example
+75
View File
@@ -0,0 +1,75 @@
# Nuxt Minimal Starter
Look at the [Nuxt documentation](https://nuxt.com/docs/getting-started/introduction) to learn more.
## Setup
Make sure to install dependencies:
```bash
# npm
npm install
# pnpm
pnpm install
# yarn
yarn install
# bun
bun install
```
## Development Server
Start the development server on `http://localhost:3000`:
```bash
# npm
npm run dev
# pnpm
pnpm dev
# yarn
yarn dev
# bun
bun run dev
```
## Production
Build the application for production:
```bash
# npm
npm run build
# pnpm
pnpm build
# yarn
yarn build
# bun
bun run build
```
Locally preview production build:
```bash
# npm
npm run preview
# pnpm
pnpm preview
# yarn
yarn preview
# bun
bun run preview
```
Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.
+20
View File
@@ -0,0 +1,20 @@
<script setup lang="ts">
useHead({
title: 'Rasmus Search Engine',
meta: [
{ name: 'description', content: 'Just a search engine for fun' },
{ name: 'lang', content: 'en'}
],
link: [
{ rel: 'icon', type: 'image/jpeg', href: '/favicon.jpg' }
],
})
</script>
<template>
<NuxtLayout>
<NuxtPage page-key="static" />
</NuxtLayout>
</template>
+3
View File
@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
+17
View File
@@ -0,0 +1,17 @@
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
compatibilityDate: '2024-12-16',
ssr: true,
devtools: { enabled: true },
css: ['@/assets/css/main.css'],
postcss: {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
},
modules: ['@nuxtjs/tailwindcss', 'nuxt-purgecss'],
});
+11204
View File
File diff suppressed because it is too large Load Diff
+25
View File
@@ -0,0 +1,25 @@
{
"name": "nuxt-app",
"private": true,
"type": "module",
"scripts": {
"build": "nuxt build",
"dev": "nuxt dev",
"generate": "nuxt generate",
"preview": "nuxt preview",
"postinstall": "nuxt prepare"
},
"dependencies": {
"@nuxtjs/partytown": "^1.5.0",
"nuxt": "^3.14.1592",
"vue": "latest",
"vue-router": "latest"
},
"devDependencies": {
"@nuxtjs/tailwindcss": "^6.12.2",
"autoprefixer": "^10.4.20",
"nuxt-purgecss": "^2.0.0",
"postcss": "^8.4.49",
"tailwindcss": "^3.4.16"
}
}
+11
View File
@@ -0,0 +1,11 @@
<script setup lang="ts">
const route = useRoute()
</script>
<template>
<div>
<h1>Nuxt Routing set up successfully!</h1>
<p>Current route: {{ route.path }}</p>
<a href="https://nuxt.com/docs/getting-started/routing" target="_blank">Learn more about Nuxt Routing</a>
</div>
</template>
+63
View File
@@ -0,0 +1,63 @@
<script setup lang="ts">
import { fetchWithCache } from '~/utils/cacheUtil';
import { progressTypeToDictionary } from '~/utils/convertProgressTypeToDictionary';
const data = ref<ProgressType | null>(null);
const loading = ref<boolean>(true);
const error = ref<string | null>(null);
let dict = ref<ProgressDictionary[] | null>(null);
const fetchMyData = async () => {
try {
loading.value = true;
// Use the caching utility
data.value = await fetchWithCache<ProgressType>(
'Progress',
async () => {
const response = await fetch('https://proxy.rbwr.dk/progress');
if (!response.ok) throw new Error('API fetch failed');
return (await response.json()) as ProgressType;
},
5 // Cache max age in seconds
);
} catch (err) {
error.value = (err as Error).message;
} finally {
loading.value = false;
if (data.value !== null) {
dict.value = progressTypeToDictionary(data.value);
}
}
};
fetchMyData();
</script>
<template>
<div class="h-screen grid place-items-center">
<div v-if="dict">
<table class="table-auto border-gray-300">
<thead>
<tr>
<th class="px-4 py-2">Metric</th>
<th class="px-4 py-2">Value</th>
</tr>
</thead>
<tbody>
<tr v-for="d in dict">
<td class="px-4 py-2">{{d.description}}</td>
<td class="px-4 py-2">{{d.value}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
<style scoped>
</style>
Binary file not shown.

After

Width:  |  Height:  |  Size: 885 B

+1
View File
@@ -0,0 +1 @@
+3
View File
@@ -0,0 +1,3 @@
{
"extends": "../.nuxt/tsconfig.server.json"
}
+16
View File
@@ -0,0 +1,16 @@
/** @type {import('tailwindcss').Config} */
export default {
content: [
"./components/**/*.{js,vue,ts}",
"./layouts/**/*.vue",
"./pages/**/*.vue",
"./plugins/**/*.{js,ts}",
"./app.vue",
"./error.vue",
],
theme: {
extend: {},
},
plugins: [],
}
+4
View File
@@ -0,0 +1,4 @@
{
// https://nuxt.com/docs/guide/concepts/typescript
"extends": "./.nuxt/tsconfig.json"
}
+19
View File
@@ -0,0 +1,19 @@
interface ProgressType {
percentageOfIpv4Scanned: number; // assuming this is a number
totalFiltered: bigint;
amountOfIpv4Left: bigint;
totalDiscarded: bigint;
discardedDbSize: bigint;
filteredDbSize: bigint;
myDbSize: bigint;
}
interface ProgressDictionary {
description: string;
value: string;
}
type CacheEntry<T> = {
data: T;
timestamp: number;
};
+34
View File
@@ -0,0 +1,34 @@
export function fetchWithCache<Type>(
cacheKey: string,
fetchFunction: () => Promise<Type>,
maxAge: number = 5 // 30 seconds
): Promise<Type> {
return new Promise(async (resolve, reject) => {
try {
const cachedData = localStorage.getItem(cacheKey);
if (cachedData) {
const { data, timestamp } = JSON.parse(cachedData) as CacheEntry<Type>;
const now = Date.now();
const ageInSeconds = (now - timestamp) / 1000;
// Check if cache is still valid
if (ageInSeconds < maxAge) {
return resolve(data);
}
}
// Cache is missing or expired, fetch fresh data
const freshData = await fetchFunction();
const cacheEntry: CacheEntry<Type> = {
data: freshData,
timestamp: Date.now(),
};
localStorage.setItem(cacheKey, JSON.stringify(cacheEntry));
resolve(freshData);
} catch (error) {
reject(error);
}
});
}
@@ -0,0 +1,11 @@
export function progressTypeToDictionary(progress: ProgressType) {
return [
{ description: "Percentage of Ipv4 scanned", value: progress.percentageOfIpv4Scanned.toString() },
{ description: "Total filtered", value: progress.totalFiltered.toString() },
{ description: "Total Discarded", value: progress.totalDiscarded.toString() },
{ description: "Amount of Ipv4 left", value: progress.amountOfIpv4Left.toString() },
{ description: "Discarded db size", value: progress.discardedDbSize.toString() },
{ description: "Filtered db size", value: progress.filteredDbSize.toString() },
{ description: "Unfiltered db size", value: progress.myDbSize.toString() },
]
}