Several massive changes and additions
parent
e7ed29d78d
commit
a0ca936554
|
@ -0,0 +1,291 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using ln.http.route;
|
||||
using ln.json;
|
||||
using ln.json.mapping;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.Drawing;
|
||||
using SixLabors.ImageSharp.Drawing.Processing;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
|
||||
namespace ln.http.helpers
|
||||
{
|
||||
|
||||
public class HttpCaptcha : HttpRoute
|
||||
{
|
||||
private Dictionary<Guid, CaptchaInstance> _captchaInstances = new Dictionary<Guid, CaptchaInstance>();
|
||||
private CaptchaEndpoints _captchaEndpoints;
|
||||
|
||||
public HtmlColor[] CaptchaColors { get; } = new HtmlColor[]
|
||||
{
|
||||
HtmlColor.Red, HtmlColor.Green, HtmlColor.Blue, HtmlColor.Yellow, HtmlColor.Violett, HtmlColor.turquoise
|
||||
};
|
||||
|
||||
public Random _random = new Random(Environment.TickCount + Thread.CurrentThread.GetHashCode());
|
||||
|
||||
public TimeSpan Timeout { get; set; } = TimeSpan.FromMinutes(10);
|
||||
public int SolutionLength { get; set; }
|
||||
public int GroupLength { get; set; }
|
||||
|
||||
public HttpCaptcha(HttpRouter httpRouter, string mapPath)
|
||||
:this(httpRouter, mapPath, 25, 5)
|
||||
{}
|
||||
public HttpCaptcha(HttpRouter httpRouter, string mapPath, int groupLength, int solutionLength)
|
||||
: base(HttpMethod.ANY, mapPath)
|
||||
{
|
||||
_captchaEndpoints = new CaptchaEndpoints(this);
|
||||
_routerDelegate = _captchaEndpoints.RouteRequest;
|
||||
|
||||
GroupLength = groupLength;
|
||||
SolutionLength = solutionLength;
|
||||
|
||||
httpRouter.Map(this);
|
||||
}
|
||||
|
||||
public CaptchaInstance CreateInstance() => new CaptchaInstance(this);
|
||||
|
||||
public bool Authorize(HttpRequest httpRequest)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
class CaptchaEndpoints : HttpEndpointController
|
||||
{
|
||||
private HttpCaptcha _httpCaptcha;
|
||||
|
||||
public CaptchaEndpoints(HttpCaptcha httpCaptcha)
|
||||
{
|
||||
_httpCaptcha = httpCaptcha;
|
||||
}
|
||||
|
||||
[Map(HttpMethod.GET,"")]
|
||||
public HttpResponse GetCaptcha()
|
||||
{
|
||||
return HttpResponse
|
||||
.OK()
|
||||
.Content(
|
||||
_httpCaptcha
|
||||
.CreateInstance()
|
||||
.Json()
|
||||
);
|
||||
}
|
||||
|
||||
[Map(HttpMethod.GET, "/:instance/:combination")]
|
||||
public HttpResponse DrawCombination(Guid instance, int combination)
|
||||
{
|
||||
int imageSize = 48;
|
||||
|
||||
if (!_httpCaptcha._captchaInstances.TryGetValue(instance, out CaptchaInstance captchaInstance) ||
|
||||
((combination < 0) || (combination >= captchaInstance.Combinations.Length)))
|
||||
return HttpResponse.NotFound();
|
||||
|
||||
CaptchaCombination captchaCombination = captchaInstance.Combinations[combination];
|
||||
|
||||
Image<Rgb24> combinationImage = new Image<Rgb24>(imageSize, imageSize, new Rgb24(255,255,255));
|
||||
IPath combinationPath = null;
|
||||
|
||||
switch (captchaCombination.Form)
|
||||
{
|
||||
case CaptchaForm.Stern:
|
||||
combinationPath = new Star((float)(imageSize / 2.0),
|
||||
(float)(imageSize / 2.0), captchaCombination.Corners,
|
||||
(float)(imageSize / 6.0), (float)(imageSize / 2.3));
|
||||
break;
|
||||
case CaptchaForm.Vieleck:
|
||||
combinationPath = new RegularPolygon((float)(imageSize / 2.0),
|
||||
(float)(imageSize / 2.0), captchaCombination.Corners,
|
||||
(float)(imageSize / 2.3));
|
||||
break;
|
||||
default:
|
||||
return HttpResponse.InternalServerError();
|
||||
}
|
||||
|
||||
combinationImage.Mutate(x => x.Fill(captchaCombination.Color, combinationPath.RotateDegree(_httpCaptcha._random.Next(360))));
|
||||
|
||||
StreamedContent streamedContent = new StreamedContent("image/png");
|
||||
combinationImage.SaveAsPng(streamedContent.ContentStream);
|
||||
|
||||
HttpResponse httpResponse = HttpResponse.OK().Content(streamedContent);
|
||||
return httpResponse;
|
||||
}
|
||||
|
||||
[Map(HttpMethod.POST, "/:instance")]
|
||||
public HttpResponse Solve(Guid instance, [HttpArgumentSource(HttpArgumentSource.CONTENT)] JSONValue body)
|
||||
{
|
||||
if (!_httpCaptcha._captchaInstances.TryGetValue(instance, out CaptchaInstance captchaInstance))
|
||||
return HttpResponse.NotFound();
|
||||
|
||||
if (body is JSONArray jsonSolution)
|
||||
{
|
||||
int[] solution = JSONMapper.DefaultMapper.FromJson<int[]>(jsonSolution);
|
||||
|
||||
if (captchaInstance.Solve(solution))
|
||||
{
|
||||
return HttpResponse.NoContent();
|
||||
}
|
||||
return HttpResponse.Forbidden();
|
||||
}
|
||||
else
|
||||
{
|
||||
return HttpResponse.BadRequest();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class CaptchaInstance : IDisposable
|
||||
{
|
||||
public Guid Guid { get; }
|
||||
|
||||
public CaptchaCombination[] Combinations { get; private set; }
|
||||
public int[] Solution { get; private set; }
|
||||
|
||||
|
||||
private HttpCaptcha _httpCaptcha;
|
||||
private Timer _timer;
|
||||
|
||||
public CaptchaInstance(HttpCaptcha httpCaptcha)
|
||||
{
|
||||
_httpCaptcha = httpCaptcha;
|
||||
Guid = Guid.NewGuid();
|
||||
|
||||
_httpCaptcha._captchaInstances.Add(Guid, this);
|
||||
_timer = new Timer((state) => Dispose(), null, _httpCaptcha.Timeout, TimeSpan.Zero);
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
HashSet<CaptchaCombination> hashSet = new HashSet<CaptchaCombination>();
|
||||
while (hashSet.Count < _httpCaptcha.GroupLength)
|
||||
hashSet.Add(new CaptchaCombination(this._httpCaptcha));
|
||||
|
||||
List<CaptchaCombination> combinationPool = hashSet.ToList();
|
||||
|
||||
Combinations = new CaptchaCombination[combinationPool.Count];
|
||||
for (int n = 0; n < Combinations.Length; n++)
|
||||
{
|
||||
Combinations[n] = combinationPool[_httpCaptcha._random.Next(combinationPool.Count)];
|
||||
combinationPool.Remove(Combinations[n]);
|
||||
}
|
||||
|
||||
hashSet.Clear();
|
||||
|
||||
while (hashSet.Count < _httpCaptcha.SolutionLength)
|
||||
hashSet.Add(Combinations[_httpCaptcha._random.Next(Combinations.Length)]);
|
||||
|
||||
Solution = hashSet.Select(cs => Array.IndexOf(Combinations, cs)).ToArray();
|
||||
Console.WriteLine(String.Join('-', Solution));
|
||||
Array.Sort(Solution);
|
||||
Console.WriteLine(String.Join('-', Solution));
|
||||
}
|
||||
|
||||
public bool Solve(int[] possibleSolution)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
try
|
||||
{
|
||||
possibleSolution = possibleSolution.Distinct().ToArray();
|
||||
Array.Sort(possibleSolution);
|
||||
|
||||
return Solution.SequenceEqual(possibleSolution);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public JSONObject Json()
|
||||
{
|
||||
JSONObject json = new JSONObject()
|
||||
.Add("uuid", Guid)
|
||||
.Add("questions", Solution.Select(n => Combinations[n].ToString()).ToArray())
|
||||
.Add("group", Combinations.Length);
|
||||
;
|
||||
return json;
|
||||
}
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
_timer.Dispose();
|
||||
_httpCaptcha?._captchaInstances.Remove(Guid);
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString() => String.Join(", ", Solution.Select(n => Combinations[n].ToString()));
|
||||
}
|
||||
|
||||
public class CaptchaCombination
|
||||
{
|
||||
public HtmlColor Color { get; }
|
||||
public int Corners { get; }
|
||||
public CaptchaForm Form { get; }
|
||||
|
||||
public CaptchaCombination(HttpCaptcha httpCaptcha)
|
||||
{
|
||||
Color = httpCaptcha.CaptchaColors[httpCaptcha._random.Next(httpCaptcha.CaptchaColors.Length)];
|
||||
Corners = 4 + httpCaptcha._random.Next(4);
|
||||
|
||||
CaptchaForm[] captchaForms = Enum.GetValues<CaptchaForm>();
|
||||
Form = captchaForms[httpCaptcha._random.Next(captchaForms.Length)];
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj) => obj is CaptchaCombination other && Color.Equals(other.Color) &&
|
||||
Corners.Equals(other.Corners) && Form.Equals(other.Form);
|
||||
|
||||
public override int GetHashCode() => Color.GetHashCode() ^ Corners ^ Form.GetHashCode();
|
||||
|
||||
public override string ToString() => $"ein {Form} mit {Corners} {(Form == CaptchaForm.Stern ? "Strahlen" : "Ecken")} in {Color.Name}";
|
||||
}
|
||||
|
||||
public enum CaptchaForm
|
||||
{
|
||||
Stern,
|
||||
Vieleck
|
||||
}
|
||||
|
||||
public class HtmlColor
|
||||
{
|
||||
public static readonly HtmlColor Red = new HtmlColor(255, 0, 0, "Rot");
|
||||
public static readonly HtmlColor Green = new HtmlColor(0, 255, 0, "Grün");
|
||||
public static readonly HtmlColor Blue = new HtmlColor(0, 0, 255, "Blau");
|
||||
public static readonly HtmlColor Yellow = new HtmlColor(240, 240, 0, "Gelb");
|
||||
public static readonly HtmlColor Violett = new HtmlColor(255, 0, 255, "Lila");
|
||||
public static readonly HtmlColor turquoise = new HtmlColor(0, 255, 255, "Türkis");
|
||||
|
||||
|
||||
public byte R { get; }
|
||||
public byte G { get; }
|
||||
public byte B { get; }
|
||||
|
||||
public string Name { get; }
|
||||
|
||||
public HtmlColor(byte r, byte g, byte b) : this(r, g, b, null)
|
||||
{
|
||||
}
|
||||
|
||||
public HtmlColor(byte r, byte g, byte b, string name)
|
||||
{
|
||||
R = r;
|
||||
G = g;
|
||||
B = b;
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public override string ToString() => $"#{Red:X2}{Green:X2}{Blue:X2}";
|
||||
|
||||
public static implicit operator Color(HtmlColor htmlColor) =>
|
||||
new Rgb24(htmlColor.R, htmlColor.G, htmlColor.B);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using ln.http.route;
|
||||
using MimeKit;
|
||||
|
||||
namespace ln.http.helpers
|
||||
{
|
||||
|
||||
public class HttpMailer : HttpRoute, IDisposable
|
||||
{
|
||||
private HttpRouter _httpRouter;
|
||||
private HttpCaptcha _httpCaptcha;
|
||||
private HttpMailerOptions _httpMailerOptions;
|
||||
private HttpMailerEndpoints _httpMailerEndpoints;
|
||||
|
||||
public HttpMailer(HttpRouter httpRouter, string mapPath, HttpMailerOptions mailerOptions)
|
||||
: this(httpRouter, mapPath, mailerOptions, null)
|
||||
{
|
||||
}
|
||||
|
||||
public HttpMailer(HttpRouter httpRouter, string mapPath, HttpMailerOptions mailerOptions,
|
||||
HttpCaptcha httpCaptcha)
|
||||
: base(HttpMethod.ANY, mapPath)
|
||||
{
|
||||
_httpRouter = httpRouter;
|
||||
_httpCaptcha = httpCaptcha;
|
||||
_httpMailerOptions = mailerOptions;
|
||||
_httpMailerEndpoints = new HttpMailerEndpoints(this);
|
||||
_routerDelegate = _httpMailerEndpoints.RouteRequest;
|
||||
|
||||
httpRouter.Map(this);
|
||||
}
|
||||
|
||||
public class HttpMailerOptions
|
||||
{
|
||||
public string Hostname { get; set; } = "localhost";
|
||||
public int Port { get; set; } = 25;
|
||||
|
||||
public string? Username { get; set; }
|
||||
public string? Password { get; set; }
|
||||
|
||||
public SmtpEncryption Encryption { get; set; } = SmtpEncryption.None;
|
||||
}
|
||||
|
||||
class HttpMailerEndpoints : HttpEndpointController
|
||||
{
|
||||
private HttpMailer _httpMailer;
|
||||
|
||||
public HttpMailerEndpoints(HttpMailer httpMailer)
|
||||
{
|
||||
_httpMailer = httpMailer;
|
||||
}
|
||||
|
||||
|
||||
[Map(HttpMethod.POST, "/mail")]
|
||||
public HttpResponse PostMail(HttpRequest httpRequest)
|
||||
{
|
||||
using (FileStream fs = new FileStream("/tmp/post.txt", FileMode.Create, FileAccess.Write))
|
||||
httpRequest.ContentStream.CopyTo(fs);
|
||||
|
||||
return HttpResponse.NoContent();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_httpRouter?.UnMap(this);
|
||||
_httpMailerEndpoints.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public enum SmtpEncryption
|
||||
{
|
||||
None,
|
||||
Tls,
|
||||
StartTls
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Nullable>enable</Nullable>
|
||||
<TargetFrameworks>net5.0;net6.0</TargetFrameworks>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<PackageVersion>0.9.0-test1</PackageVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ln.http\ln.http.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MailKit" Version="3.3.0" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.3" />
|
||||
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta14" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -1,8 +1,7 @@
|
|||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using ln.bootstrap;
|
||||
using ln.http.router;
|
||||
using ln.templates;
|
||||
using ln.templates.html;
|
||||
|
||||
namespace ln.http.service
|
||||
|
@ -13,19 +12,18 @@ namespace ln.http.service
|
|||
{
|
||||
Bootstrap
|
||||
.DefaultInstance
|
||||
.ServiceContainer.RegisterService<HttpServiceHelper>();
|
||||
Bootstrap
|
||||
.DefaultInstance
|
||||
//.AddService<HttpServiceHelper>()
|
||||
.Start();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
class HttpServiceHelper : HttpRouter
|
||||
{
|
||||
private TemplateDocument _templateDocument;
|
||||
public HttpServiceHelper(HttpServer httpServer)
|
||||
:base(httpServer)
|
||||
public HttpServiceHelper(HttpRouter httpRouter)
|
||||
:base()
|
||||
{
|
||||
using (StreamReader reader = new StreamReader(
|
||||
Assembly
|
||||
|
@ -44,7 +42,7 @@ namespace ln.http.service
|
|||
{
|
||||
HttpResponse httpResponse =
|
||||
new HttpResponse(httpContext.HttpException?.HttpStatusCode ?? HttpStatusCode.InternalServerError);
|
||||
|
||||
|
||||
RenderContext renderContext = new RenderContext(httpResponse.ContentWriter);
|
||||
renderContext
|
||||
.GetEngine()
|
||||
|
@ -56,4 +54,5 @@ namespace ln.http.service
|
|||
}
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -1,31 +1,50 @@
|
|||
{
|
||||
"ln.http.HttpServer, ln.http": {
|
||||
"services": [
|
||||
],
|
||||
"properties": {
|
||||
"System.IO.StreamWriter, System.Runtime": {
|
||||
"domain": "log.http",
|
||||
"set": {
|
||||
"parameters": {
|
||||
"path": "http.access.log"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ln.http.HttpListener, ln.http": {
|
||||
"services": [
|
||||
|
||||
],
|
||||
"properties": {
|
||||
"DefaultPort": 8180
|
||||
"ln.http.HttpServer": {
|
||||
"resolve": {
|
||||
"parameters": {
|
||||
"accessLogWriter": "(log.http) System.IO.StreamWriter, System.Runtime",
|
||||
"logWriter": "(log.console) ln.logging.LogWriter"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ln.http.HttpsListener, ln.http": {
|
||||
"services": [
|
||||
|
||||
],
|
||||
"properties": {
|
||||
"DefaultPort": 8443
|
||||
"ln.http.HttpListener": {
|
||||
"set": {
|
||||
"properties": {
|
||||
"DefaultPort": 8180
|
||||
}
|
||||
}
|
||||
},
|
||||
"ln.http.FileSystemRouter, ln.http": {
|
||||
"services": [
|
||||
],
|
||||
"parameters": {
|
||||
"path": "."
|
||||
"ln.http.HttpsListener": {
|
||||
"set": {
|
||||
"properties": {
|
||||
"DefaultPort": 8443
|
||||
}
|
||||
}
|
||||
},
|
||||
"ln.logging.ConsoleLogSink": {
|
||||
"domain": "log.console"
|
||||
},
|
||||
"ln.logging.LogWriter": {
|
||||
"domain": "log.console",
|
||||
"resolve": {
|
||||
"parameter": {
|
||||
"logSink": "(log.console) ln.logging.ILogSink"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ln.logging.ConsoleWrapper": {
|
||||
"resolve": {
|
||||
"parameters": {
|
||||
"logSink": "(log.console) ln.logging.ILogSink"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
{
|
||||
"ln.http.HttpRouter, ln.http": {
|
||||
"resolve": {
|
||||
"parameters": {
|
||||
"httpServer": "ln.http.HttpServer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ln.http.templates.FileSystemTemplateRouter, ln.http.templates": {
|
||||
"set": {
|
||||
"parameters": {
|
||||
"path": "/home/haraldwolff/src/www/dambacher",
|
||||
"mappingPath": "/*"
|
||||
}
|
||||
},
|
||||
"resolve": {
|
||||
"parameters": {
|
||||
"httpRouter" : "ln.http.HttpRouter"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ln.http.FileSystemRouter, ln.http": {
|
||||
"set": {
|
||||
"parameters": {
|
||||
"path": "/home/haraldwolff/src/www/dambacher",
|
||||
"mappingPath": "/*"
|
||||
}
|
||||
},
|
||||
"resolve": {
|
||||
"parameters": {
|
||||
"httpRouter" : "ln.http.HttpRouter"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ln.http.helpers.HttpCaptcha": {
|
||||
"resolve": {
|
||||
"parameters": {
|
||||
"httpRouter": "ln.http.HttpRouter"
|
||||
}
|
||||
},
|
||||
"set": {
|
||||
"parameters": {
|
||||
"mapPath": "/captcha/*"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ln.http.helpers.HttpMailer": {
|
||||
"resolve": {
|
||||
"parameters": {
|
||||
"httpRouter": "ln.http.HttpRouter"
|
||||
}
|
||||
},
|
||||
"set": {
|
||||
"parameters": {
|
||||
"mapPath": "/mailer/*",
|
||||
"mailerOptions": {
|
||||
"HostName": "smtp.l--n.de",
|
||||
"Port": 465
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,23 +4,29 @@
|
|||
<OutputType>Exe</OutputType>
|
||||
<LangVersion>9</LangVersion>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<PackageVersion>1.0.1</PackageVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="../ln.http/ln.http.csproj" />
|
||||
<ProjectReference Include="..\..\ln.templates\ln.http.templates\ln.http.templates.csproj" />
|
||||
<ProjectReference Include="..\ln.http.helpers\ln.http.helpers.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ln.bootstrap" Version="1.2.4" />
|
||||
<PackageReference Include="ln.http" Version="0.6.5" />
|
||||
<PackageReference Include="ln.http.templates" Version="0.1.0" />
|
||||
<PackageReference Include="ln.templates" Version="0.3.0" />
|
||||
<PackageReference Include="ln.bootstrap" Version="1.4.0" />
|
||||
<PackageReference Include="ln.http" Version="0.9.1-test01" />
|
||||
<!--PackageReference Include="ln.http.templates" Version="0.1.1" /-->
|
||||
<!--PackageReference Include="ln.templates" Version="0.3.0" /-->
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="bootstrap.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="ln.http.HttpServer.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
Binary file not shown.
18
ln.http.sln
18
ln.http.sln
|
@ -11,6 +11,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.http.service", "ln.http.
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.protocols.helper", "..\ln.protocols.helper\ln.protocols.helper.csproj", "{1C1D3A17-A615-4686-90BD-F0E221EAC89C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.http.templates", "..\ln.templates\ln.http.templates\ln.http.templates.csproj", "{45709176-EA57-4BB3-815B-91D161CEB7A6}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.templates", "..\ln.templates\ln.templates\ln.templates.csproj", "{D6BA640C-352F-41BF-85EF-4B76FD928BEC}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.http.helpers", "ln.http.helpers\ln.http.helpers.csproj", "{FAC3F9BE-6C09-4523-8584-2BD5B08BB70D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -69,5 +75,17 @@ Global
|
|||
{1C1D3A17-A615-4686-90BD-F0E221EAC89C}.Release|x64.Build.0 = Release|Any CPU
|
||||
{1C1D3A17-A615-4686-90BD-F0E221EAC89C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{1C1D3A17-A615-4686-90BD-F0E221EAC89C}.Release|x86.Build.0 = Release|Any CPU
|
||||
{45709176-EA57-4BB3-815B-91D161CEB7A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{45709176-EA57-4BB3-815B-91D161CEB7A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{45709176-EA57-4BB3-815B-91D161CEB7A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{45709176-EA57-4BB3-815B-91D161CEB7A6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D6BA640C-352F-41BF-85EF-4B76FD928BEC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D6BA640C-352F-41BF-85EF-4B76FD928BEC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D6BA640C-352F-41BF-85EF-4B76FD928BEC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D6BA640C-352F-41BF-85EF-4B76FD928BEC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{FAC3F9BE-6C09-4523-8584-2BD5B08BB70D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FAC3F9BE-6C09-4523-8584-2BD5B08BB70D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FAC3F9BE-6C09-4523-8584-2BD5B08BB70D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FAC3F9BE-6C09-4523-8584-2BD5B08BB70D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
using System;
|
||||
using ln.http.helpers;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace ln.http.tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class CaptchaTests
|
||||
{
|
||||
|
||||
|
||||
[Test]
|
||||
public void TestCaptcha()
|
||||
{
|
||||
HttpCaptcha httpCaptcha = new HttpCaptcha(null, null);
|
||||
|
||||
for (int n = 0; n < 1024; n++)
|
||||
{
|
||||
HttpCaptcha.CaptchaInstance captchaInstance = httpCaptcha.CreateInstance();
|
||||
Console.WriteLine(captchaInstance.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -3,44 +3,42 @@ using System.IO;
|
|||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using ln.http.router;
|
||||
using ln.json;
|
||||
using ln.type;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace ln.http.tests
|
||||
{
|
||||
public class Tests
|
||||
{
|
||||
HttpServer server;
|
||||
int testPort;
|
||||
private HttpRouter TestRouter;
|
||||
private int TestPort;
|
||||
private Listener _httpListener;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
if (server != null)
|
||||
return;
|
||||
TestRouter = new HttpRouter();
|
||||
TestRouter.Map(new TestApiController());
|
||||
FileSystemRouter fileSystemRouter = new FileSystemRouter("/static/", AppContext.BaseDirectory);
|
||||
TestRouter.Map(fileSystemRouter);
|
||||
|
||||
server = new HttpServer();
|
||||
|
||||
HttpRouter testRouter = new HttpRouter(server);
|
||||
testRouter.Map(HttpMethod.ANY, "/controller/*", HttpRoutePriority.NORMAL, new TestApiController().Route);
|
||||
_httpListener = new Listener(TestRouter, IPAddress.Any, 0);
|
||||
TestPort = _httpListener.LocalEndpoint.Port;
|
||||
TestContext.Error.WriteLine("Using Port {0}", TestPort);
|
||||
}
|
||||
|
||||
FileSystemRouter fileSystemRouter = new FileSystemRouter(AppContext.BaseDirectory);
|
||||
testRouter.Map(HttpMethod.ANY, "/static/*", fileSystemRouter.Route);
|
||||
|
||||
HttpListener.DefaultPort = 0;
|
||||
HttpListener httpListener = new HttpListener(server);
|
||||
|
||||
testPort = httpListener.LocalEndpoint.Port;
|
||||
TestContext.Error.WriteLine("Using Port {0}", testPort);
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
_httpListener?.Dispose();
|
||||
TestRouter?.Dispose();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test1()
|
||||
{
|
||||
HttpClient client = new HttpClient();
|
||||
HttpResponseMessage response = client.GetAsync(String.Format("http://localhost:{0}/static/test.txt", testPort)).Result;
|
||||
HttpResponseMessage response = client.GetAsync(String.Format("http://localhost:{0}/static/test.txt", TestPort)).Result;
|
||||
|
||||
Assert.AreEqual(System.Net.HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
|
@ -49,8 +47,6 @@ namespace ln.http.tests
|
|||
|
||||
CollectionAssert.AreEqual(fileBytes, contentBytes);
|
||||
|
||||
//server.Stop();
|
||||
|
||||
Assert.Pass();
|
||||
}
|
||||
|
||||
|
@ -59,17 +55,18 @@ namespace ln.http.tests
|
|||
{
|
||||
JSONObject jsonPutObject = new JSONObject();
|
||||
jsonPutObject["PutTest"] = JSONTrue.Instance;
|
||||
StringContent jsonStringContent = new StringContent(jsonPutObject.ToString());
|
||||
System.Net.Http.StringContent jsonStringContent = new System.Net.Http.StringContent(jsonPutObject.ToString());
|
||||
jsonStringContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
|
||||
|
||||
HttpClient client = new HttpClient();
|
||||
HttpResponseMessage response = client.PutAsync(String.Format("http://localhost:{0}/controller/put", testPort), jsonStringContent).Result;
|
||||
HttpResponseMessage response = client.PutAsync(String.Format("http://localhost:{0}/controller/put", TestPort), jsonStringContent).Result;
|
||||
|
||||
Assert.AreEqual(System.Net.HttpStatusCode.OK, response.StatusCode);
|
||||
Assert.Pass();
|
||||
}
|
||||
}
|
||||
|
||||
[Map(HttpMethod.ANY, "/controller")]
|
||||
class TestApiController : HttpEndpointController
|
||||
{
|
||||
[Map(HttpMethod.PUT, "/put")]
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
|
||||
<LangVersion>9</LangVersion>
|
||||
|
||||
<TargetFrameworks>net5.0;net6.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -14,11 +15,13 @@
|
|||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
|
||||
|
||||
<ProjectReference Include="../ln.http/ln.http.csproj" />
|
||||
<PackageReference Include="ln.type" Version="0.1.7" />
|
||||
<PackageReference Include="ln.type" Version="0.1.9" />
|
||||
|
||||
<Content Include="test.txt">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
|
||||
<ProjectReference Include="..\ln.http.helpers\ln.http.helpers.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
Loading…
Reference in New Issue