initial commit
This commit is contained in:
commit
01ce8dad3f
15 changed files with 267 additions and 0 deletions
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
*.cs eol=crlf
|
||||
*.txt eol=lf
|
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
.vs
|
||||
.vscode
|
||||
bin
|
||||
obj
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
[submodule "MiniHTTP"]
|
||||
path = MiniHTTP
|
||||
url = https://git.rape.pet/uwaa/MiniHTTP
|
26
Example.sln
Normal file
26
Example.sln
Normal file
|
@ -0,0 +1,26 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.10.35027.167
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Example", "Example\Example.csproj", "{7EAF8960-ABA7-4E12-B9AC-5FE3D0BAB0F6}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MiniHTTP", "MiniHTTP\MiniHTTP\MiniHTTP.csproj", "{12E5EAE8-2A60-4DC6-9D97-36CC54EDDBA6}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{7EAF8960-ABA7-4E12-B9AC-5FE3D0BAB0F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7EAF8960-ABA7-4E12-B9AC-5FE3D0BAB0F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{12E5EAE8-2A60-4DC6-9D97-36CC54EDDBA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{12E5EAE8-2A60-4DC6-9D97-36CC54EDDBA6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {85D6E851-88E0-4C85-9B4F-AF0CB2005BDB}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
20
Example/Example.csproj
Normal file
20
Example/Example.csproj
Normal file
|
@ -0,0 +1,20 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>false</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Configurations>Debug</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\MiniHTTP\MiniHTTP\MiniHTTP.csproj" />
|
||||
|
||||
<None Update="certs\*">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="www-static\**\*">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
87
Example/Program.cs
Normal file
87
Example/Program.cs
Normal file
|
@ -0,0 +1,87 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Threading.Tasks;
|
||||
using MiniHTTP.Websockets;
|
||||
using MiniHTTP.Responses;
|
||||
using MiniHTTP.Routing;
|
||||
|
||||
namespace MiniHTTP.Example;
|
||||
|
||||
internal partial class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
Console.WriteLine("Loading certificate");
|
||||
X509Certificate2 cert = X509Certificate2.CreateFromPemFile("certs/example.net.crt", "certs/example.net.key");
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
//Hack because SslStream is stupid on windows
|
||||
using X509Certificate2 oldCert = cert;
|
||||
cert = new X509Certificate2(oldCert.Export(X509ContentType.Pfx));
|
||||
}
|
||||
|
||||
Console.WriteLine("Preparing listeners");
|
||||
Router router = CreateRouter();
|
||||
HttpServer httpServer = new HttpServer(80, null, router);
|
||||
HttpServer httpsServer = new HttpServer(443, cert, router);
|
||||
|
||||
Console.WriteLine("Ready on ports " + httpServer.Port + " and " +httpsServer.Port);
|
||||
Task.WaitAll(httpServer.Start(), httpsServer.Start());
|
||||
}
|
||||
|
||||
static Router CreateRouter()
|
||||
{
|
||||
Router router = new Router(NotFound);
|
||||
router.Use("*", new CORS());
|
||||
router.Add(HttpMethod.GET, "test", Test);
|
||||
router.Static("www-static");
|
||||
router.Static("www-dynamic");
|
||||
router.Add(HttpMethod.GET, "", Root);
|
||||
|
||||
return router;
|
||||
}
|
||||
|
||||
static async Task<HttpResponse?> Root(HttpRequest client, ParameterCollection parameters)
|
||||
{
|
||||
if (client.Headers.TryGetValue("Upgrade", out string? connection) && connection.Equals("websocket", StringComparison.OrdinalIgnoreCase))
|
||||
return await Websocket(client);
|
||||
else
|
||||
return new HttpContent("text/html", await File.ReadAllBytesAsync("www-static/index.htm"));
|
||||
}
|
||||
|
||||
static HttpResponse? Test(HttpRequest client, ParameterCollection parameters)
|
||||
{
|
||||
return new Redirect("/");
|
||||
}
|
||||
|
||||
static HttpResponse? Test2(HttpRequest client, ParameterCollection parameters)
|
||||
{
|
||||
return new OK("Hello");
|
||||
}
|
||||
|
||||
static HttpResponse NotFound(HttpRequest client, ParameterCollection parameters)
|
||||
{
|
||||
return new NotFound("File not found");
|
||||
}
|
||||
|
||||
static async Task<HttpResponse?> Websocket(HttpRequest client)
|
||||
{
|
||||
Websocket? ws = await client.UpgradeToWebsocket("test");
|
||||
if (ws == null)
|
||||
return null;
|
||||
|
||||
DataFrame payload = await ws.Read();
|
||||
|
||||
string result = payload.AsString();
|
||||
|
||||
if (payload.Opcode != WSOpcode.Close)
|
||||
{
|
||||
await ws.Write(true, $"Echoing message: \"{result}\"");
|
||||
}
|
||||
|
||||
ws.Close(CloseStatus.NormalClosure);
|
||||
|
||||
return new Empty();
|
||||
}
|
||||
}
|
19
Example/certs/Test Root.crt
Normal file
19
Example/certs/Test Root.crt
Normal file
|
@ -0,0 +1,19 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDBjCCAe6gAwIBAgIUG0ArzoB2Hz1DO7wFbUvIqogXhkEwDQYJKoZIhvcNAQEL
|
||||
BQAwFDESMBAGA1UEAwwJVGVzdCBSb290MB4XDTI0MTAyNTAwNDYxMFoXDTI0MTEy
|
||||
NDAwNDYxMFowFDESMBAGA1UEAwwJVGVzdCBSb290MIIBIjANBgkqhkiG9w0BAQEF
|
||||
AAOCAQ8AMIIBCgKCAQEAtc6B5D3X/RB+9BSVvnxkJ5ZV4uh8ZQn/8MykL9ILYPOr
|
||||
WA3uCt6bCt07+6FSww1ii0fFwpEC8tCXel+ZaU4ds9MlVYfdp3d78TKt9rCy/cdr
|
||||
YWK69KiawoPjynR+8B4d8ifztHsN+xYCl4zoZUW0O911RUGeV9aVFgtBN4a2dUbq
|
||||
KUGEUkaj5rFMQWxPzdjtH8uCoBrVVBPLQ99qsiGC348ts0zvmb7MxN/nxgnnr9Sp
|
||||
Fsloed32Yg8+sG9UxhHIF+ledlPaZtk8yAgsdCidy9bzBCpij684YuCIqVootZ5P
|
||||
Wv0nkoIme8do71n4/sRqINxWwptbhx3rXRJqfkFDmwIDAQABo1AwTjAdBgNVHQ4E
|
||||
FgQUfnn0b6tLeUyFPMUyKvclzlTeK20wHwYDVR0jBBgwFoAUfnn0b6tLeUyFPMUy
|
||||
KvclzlTeK20wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAgjat+GIr
|
||||
UVmJvK0BljojefmEL0oHILYm2xh8Tcd7otuQnKLFYBPNh1WizQiMPZvx8/Q1oH33
|
||||
qMjpqmwGglQc5xbm/kWhmmEp1Hvi37FeZk90e+qSgWUTH13OpTp7UcfmTEem4owb
|
||||
BHEy3HrZrz2W1MSUQ3R4SnKGauOiYdwTbKoUHZGjEQ5o3kZVj8oLADx81XwvrM2n
|
||||
x43T/n82rq8ufu20SV437VktYjfe5SCSiYS3wsohM5ZUEgLewyLVBHcQ5flHzAM6
|
||||
jSdjcxgvKVrxH0EyHsLLsnCWIe87CFOnmrN1YVJEf/8ag9iNybWdcg71/BiBeQko
|
||||
hsqEFfiBjMd4Jg==
|
||||
-----END CERTIFICATE-----
|
28
Example/certs/Test Root.key
Normal file
28
Example/certs/Test Root.key
Normal file
|
@ -0,0 +1,28 @@
|
|||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC1zoHkPdf9EH70
|
||||
FJW+fGQnllXi6HxlCf/wzKQv0gtg86tYDe4K3psK3Tv7oVLDDWKLR8XCkQLy0Jd6
|
||||
X5lpTh2z0yVVh92nd3vxMq32sLL9x2thYrr0qJrCg+PKdH7wHh3yJ/O0ew37FgKX
|
||||
jOhlRbQ73XVFQZ5X1pUWC0E3hrZ1RuopQYRSRqPmsUxBbE/N2O0fy4KgGtVUE8tD
|
||||
32qyIYLfjy2zTO+ZvszE3+fGCeev1KkWyWh53fZiDz6wb1TGEcgX6V52U9pm2TzI
|
||||
CCx0KJ3L1vMEKmKPrzhi4IipWii1nk9a/SeSgiZ7x2jvWfj+xGog3FbCm1uHHetd
|
||||
Emp+QUObAgMBAAECggEABFyIFZXXBaImRlK45beN0e+ziPYzOo7kp4rK1/IKn3CZ
|
||||
CEuLp16zV3phNjMmwIXxeqfl7aBiJeytHzY5GiNrZ2UsVk+KslOVrJg4cvX50hUj
|
||||
oiCm0Lgh8xw/R08UihjrqcodkmA7wKDeWD/87Aw7bttsNPu5aCALHMFEw9rYEhrv
|
||||
KXlyVJ+Ccp3htIRn0Ox10yFdHN5Jb9Io39970QUPi8XPP7v3RTblwa3cxSepchEa
|
||||
j/w+pcBkQA/EMZR8yjYqahfKpmH2rQGK+wus1YqZE4WIbLyFdCW8qSJWlm3eH9kr
|
||||
0v/B2TtCjdDmxGoh+gqQYFY59eA0b8fy1gvf3vtXoQKBgQD3fBL5MMJTwieacKS6
|
||||
iiGp09R2bv1EbzGqI1qcWvW11bAKQ9EpxhhKtJfxZNgIp9OD7fSMjRf9BQDNJ/V5
|
||||
4juUXvDregp/CaGEfrp3r2+5sph90pjYwVILQNdE+cvCKZKG2Bz5BInpg4dkBGXO
|
||||
NWAEgydRaNoXEpYYDDdvKc2PkQKBgQC8D+uFrluHc5YuFkHQQLUW4OP0//DvBjs2
|
||||
xyo50s+c1e+1/anaSANsUDzAcqUWy6sRo1fNCvzx5bMvXjmTMkuIUauzZ6dlwfDT
|
||||
g2RTjocHpBpqiIcvGV1WeuA+g1r8l22yZ2Sm4xyVgPwnnTPutPupkIR7YpYAbW8B
|
||||
6xoK63UiawKBgBg6fWEH9P5eM6JbBMV+YG1P36z4kLLyb9pIO8ay4Ps8QE/A8+kz
|
||||
C43EwFtRlBTE2WBBG3/nEEIlCz8Kem3ESDDuWoezGvP07WsbPQYalsWHRoaK54vQ
|
||||
4UdYwbpu+hO4HjA1WCDI4PeLeOXByHW3o/7NGDxQF4nKuAcCqyqm3QkBAoGAboVg
|
||||
ocCVM+ZfBRi5dt0AT8C81zgu7RoZZJjpnO/iaUZlSOwZjRmzQU1qVqNJmDr7fzMi
|
||||
n3LssnCOvLDAX1w4fZWZtaad/zRaBsP6Cw0BGCF+EMvJvolGjFNMRBDIQRfxNN6E
|
||||
jXt9SfNyvQkrAwdDuyQeZ7DJfNjTWypCtNYpkZ8CgYEA01vGWqOfNm6JwWpG16bk
|
||||
xJnnWsfMg1BdNLGEZzK+myf/cnxcUnTJIVLrSfJ6rDD5bVqviB09Zbs57l7k/e+C
|
||||
f6X6ZazOQfr8dx9Qr+Z3rytehqKL+zWuSyaAyeyiuQF5Dcw5touWlJsBtjGveaW2
|
||||
yw079ym/DRE52zY5IMBUFNM=
|
||||
-----END PRIVATE KEY-----
|
19
Example/certs/example.net.crt
Normal file
19
Example/certs/example.net.crt
Normal file
|
@ -0,0 +1,19 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDHTCCAgWgAwIBAgIUDBt289LdXev6twhyC/LYmr/YLSswDQYJKoZIhvcNAQEL
|
||||
BQAwFDESMBAGA1UEAwwJVGVzdCBSb290MB4XDTI0MTAyNTAwNDcwNloXDTI0MTEy
|
||||
NDAwNDcwNlowFjEUMBIGA1UEAwwLZXhhbXBsZS5uZXQwggEiMA0GCSqGSIb3DQEB
|
||||
AQUAA4IBDwAwggEKAoIBAQCObaYcmizussr1oXDwqJvb9ecSs0yN5LtT/6x5h7IV
|
||||
xnuq5R+In9H0/PLA6jL7QAwbtJUHt75l6stUXTJ5zoQpOjoxx62chouCgWZ9+dMd
|
||||
+XhznwQLgnfB1UyJM0wIbNRatoWVK/BGZjCoeODWntR+urIqPXBQhsn1TIDbBoiV
|
||||
lrjjTqDe1058bH1qd0WGTgpbJx1h2+w6vMvqSox3YEblF0QWOKTGhRRlC4umQHZm
|
||||
DPY/he4AvnP8oHg6YdMw8Zhca3K91k73avbV6JxpKPOwo7XcRoTkAzZZpMzuA2zy
|
||||
XvFjrOeCVhihkrGZWL/JKFT3F+860GDdWErkb5SUlyRzAgMBAAGjZTBjMB0GA1Ud
|
||||
DgQWBBRSOoNBR4F0nBoZTlsEa2kno+KpbjAfBgNVHSMEGDAWgBR+efRvq0t5TIU8
|
||||
xTIq9yXOVN4rbTAWBgNVHREEDzANggtleGFtcGxlLm5ldDAJBgNVHRMEAjAAMA0G
|
||||
CSqGSIb3DQEBCwUAA4IBAQBctQWE8qm9htwgUVwxbydg14YkUgCv9QPTCURQe2fP
|
||||
1ecK8L5j5HfYCgB7ZdKdZfpUs89kCZNUBNn4GTCB1NnA3BoYxnAxELsYis2lI+TT
|
||||
Jub0/oujh3dMrQZvI/0dcsmfyDvB7XzqDYuJo4tvsqUD7m5V6kqv6TdPK+YCnQ5F
|
||||
AgAectokQvcWUdxvtVThScPXhHXyJsHJATfcmfpNCf1Tr4L+ePeB0dfrYRF+RVaV
|
||||
hN0X+dVdWI8rL+wP2R/CjsSsqGoapth3vPIueSbBnaKj1buvDo+nvw1fCDcBQA9n
|
||||
nOM/qlfeoZZIUK1wDOq5aO72bJdJ1byukYAGzWI4VvaQ
|
||||
-----END CERTIFICATE-----
|
28
Example/certs/example.net.key
Normal file
28
Example/certs/example.net.key
Normal file
|
@ -0,0 +1,28 @@
|
|||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCObaYcmizussr1
|
||||
oXDwqJvb9ecSs0yN5LtT/6x5h7IVxnuq5R+In9H0/PLA6jL7QAwbtJUHt75l6stU
|
||||
XTJ5zoQpOjoxx62chouCgWZ9+dMd+XhznwQLgnfB1UyJM0wIbNRatoWVK/BGZjCo
|
||||
eODWntR+urIqPXBQhsn1TIDbBoiVlrjjTqDe1058bH1qd0WGTgpbJx1h2+w6vMvq
|
||||
Sox3YEblF0QWOKTGhRRlC4umQHZmDPY/he4AvnP8oHg6YdMw8Zhca3K91k73avbV
|
||||
6JxpKPOwo7XcRoTkAzZZpMzuA2zyXvFjrOeCVhihkrGZWL/JKFT3F+860GDdWErk
|
||||
b5SUlyRzAgMBAAECggEAGVDyIslgzTjojIqaqZw+v/VQkmleZSZQCdk7TgrJo8c4
|
||||
+iJp3X4S8sn3WEUItNIolNAfYVTOugznAWLjcvU7Vpyr9Wc5u8XKjHL1xdSfKwfJ
|
||||
2jtcm7MgGEsSpJyCmkjF4i3pRp+dwNWvNnLt/BgVS0ViH9H14cpjoX9stAHQS05Q
|
||||
PwsOClsqlRaC/jEwBQ3nR1sNzA90Sop/cH7VEnS8i7WZhyGFKcLWL3uuCatkDvn4
|
||||
PodnB4JFg4fwq2pn9749ohUt0JJquRK1Oa4epnZt2U6CDMIbFNUS3r17R8YFy3yV
|
||||
C7EOb4yLLk38ind4Pm1YK998Q+Ia4R8MBjEoxAwsEQKBgQDDB5du/BQcTyET4znF
|
||||
uVn8vUeiVaClW9oitts3bSa5Gcdf3WQwFRQAQ/qSk9LIz+ehO/qmHKggUStXREYu
|
||||
KTGT/YPHNzXwSdDPey0tYP8MqO7HiNx/hox3cELUolopCCj0OZ8WOqo61cDeWF7O
|
||||
UQ9vTmGHJf7i+to034j1nu05qQKBgQC69FJ/lZmH1ZX0GCWbQ/Su5NOcNQ7EduCB
|
||||
+UISI2RGhApPUU9thdGv2FQIXBVAiGj947VaVLVS3GkPOANDwrfr7Rg9Ui+xE++A
|
||||
oornNOIkvrG28KwE0Sov+6MbUeVQRrjd+V/lQ9Nzi33m2Liok5kz3gi/hCnMDIM0
|
||||
CIXcZn2WuwKBgDKT8W3S6dQ9oTJrJzxjyTaGT+GFm1fG7lc6XLePEw/F47K005q0
|
||||
nK9E8eK5e1ygrk1eJK6Xl/JpmnfTOPAXtsfOYzJy2wYp3oEwTJMMKJi75tDQaX6Z
|
||||
AiynbG2AfSlO+G/90YgORr9jV9VRzaRr2TjgduJ5tBRhQd2cawRn5tWhAoGABeet
|
||||
q2X4QXgXkmwo0+yjj9qebHKoksAGe1R6J8SCaE/HW5X/4j+1zc4RaWovKailWE+W
|
||||
7NF8IK/hiZ+FSuCdmpAUketEol001WVM6dybv/ld959Gb6iDopxaHITLr2tsb2Zv
|
||||
BvjLdvzS7zWtL3XqAt9ie1obT9ydUElsoPeDw/0CgYACKO+8BXqLlOggq/ETpIDx
|
||||
KmCe/oo2aGqOpbHHHjy/MIXJFX3dMfzinbcM2iZxehOobIRX1UEbnxm5rqYcM/Eo
|
||||
8lHqDAxm92JVqDQlw0g3H8OKMcqWc7gz8cPlgWVQO7kwmEJ9pM22gox6nSknHmC4
|
||||
oSWd5f1f7u8k8TX0L9HjLQ==
|
||||
-----END PRIVATE KEY-----
|
BIN
Example/www-static/favicon.ico
Normal file
BIN
Example/www-static/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
10
Example/www-static/index.htm
Normal file
10
Example/www-static/index.htm
Normal file
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>MiniHTTP Test</title>
|
||||
</head>
|
||||
<body>
|
||||
Websocket test
|
||||
<script src="./websocket.js"></script>
|
||||
</body>
|
||||
</html>
|
10
Example/www-static/test.htm
Normal file
10
Example/www-static/test.htm
Normal file
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test</title>
|
||||
<link rel="icon" id="icon" href="data:;base64,iVBORw0KGgo=">
|
||||
</head>
|
||||
<body>
|
||||
Test
|
||||
</body>
|
||||
</html>
|
10
Example/www-static/websocket.js
Normal file
10
Example/www-static/websocket.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
const ws = new WebSocket(`wss://${location.host}/`, "test");
|
||||
ws.onerror = (e) => {
|
||||
throw e;
|
||||
};
|
||||
ws.onopen = (event) => {
|
||||
ws.send("Hello world");
|
||||
};
|
||||
ws.onmessage = (event) => {
|
||||
console.log(event.data);
|
||||
};
|
1
MiniHTTP
Submodule
1
MiniHTTP
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 8b290446717992a04a2a2cd26e1dfef125160d34
|
Loading…
Reference in a new issue