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.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading;
|
|
||||||
using ln.bootstrap;
|
using ln.bootstrap;
|
||||||
using ln.http.router;
|
using ln.templates;
|
||||||
using ln.templates.html;
|
using ln.templates.html;
|
||||||
|
|
||||||
namespace ln.http.service
|
namespace ln.http.service
|
||||||
|
@ -13,19 +12,18 @@ namespace ln.http.service
|
||||||
{
|
{
|
||||||
Bootstrap
|
Bootstrap
|
||||||
.DefaultInstance
|
.DefaultInstance
|
||||||
.ServiceContainer.RegisterService<HttpServiceHelper>();
|
//.AddService<HttpServiceHelper>()
|
||||||
Bootstrap
|
|
||||||
.DefaultInstance
|
|
||||||
.Start();
|
.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
class HttpServiceHelper : HttpRouter
|
class HttpServiceHelper : HttpRouter
|
||||||
{
|
{
|
||||||
private TemplateDocument _templateDocument;
|
private TemplateDocument _templateDocument;
|
||||||
public HttpServiceHelper(HttpServer httpServer)
|
public HttpServiceHelper(HttpRouter httpRouter)
|
||||||
:base(httpServer)
|
:base()
|
||||||
{
|
{
|
||||||
using (StreamReader reader = new StreamReader(
|
using (StreamReader reader = new StreamReader(
|
||||||
Assembly
|
Assembly
|
||||||
|
@ -44,7 +42,7 @@ namespace ln.http.service
|
||||||
{
|
{
|
||||||
HttpResponse httpResponse =
|
HttpResponse httpResponse =
|
||||||
new HttpResponse(httpContext.HttpException?.HttpStatusCode ?? HttpStatusCode.InternalServerError);
|
new HttpResponse(httpContext.HttpException?.HttpStatusCode ?? HttpStatusCode.InternalServerError);
|
||||||
|
|
||||||
RenderContext renderContext = new RenderContext(httpResponse.ContentWriter);
|
RenderContext renderContext = new RenderContext(httpResponse.ContentWriter);
|
||||||
renderContext
|
renderContext
|
||||||
.GetEngine()
|
.GetEngine()
|
||||||
|
@ -56,4 +54,5 @@ namespace ln.http.service
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,31 +1,50 @@
|
||||||
{
|
{
|
||||||
"ln.http.HttpServer, ln.http": {
|
"System.IO.StreamWriter, System.Runtime": {
|
||||||
"services": [
|
"domain": "log.http",
|
||||||
],
|
"set": {
|
||||||
"properties": {
|
"parameters": {
|
||||||
|
"path": "http.access.log"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ln.http.HttpListener, ln.http": {
|
"ln.http.HttpServer": {
|
||||||
"services": [
|
"resolve": {
|
||||||
|
"parameters": {
|
||||||
],
|
"accessLogWriter": "(log.http) System.IO.StreamWriter, System.Runtime",
|
||||||
"properties": {
|
"logWriter": "(log.console) ln.logging.LogWriter"
|
||||||
"DefaultPort": 8180
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ln.http.HttpsListener, ln.http": {
|
"ln.http.HttpListener": {
|
||||||
"services": [
|
"set": {
|
||||||
|
"properties": {
|
||||||
],
|
"DefaultPort": 8180
|
||||||
"properties": {
|
}
|
||||||
"DefaultPort": 8443
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ln.http.FileSystemRouter, ln.http": {
|
"ln.http.HttpsListener": {
|
||||||
"services": [
|
"set": {
|
||||||
],
|
"properties": {
|
||||||
"parameters": {
|
"DefaultPort": 8443
|
||||||
"path": "."
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"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>
|
<OutputType>Exe</OutputType>
|
||||||
<LangVersion>9</LangVersion>
|
<LangVersion>9</LangVersion>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<PackageVersion>1.0.1</PackageVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="../ln.http/ln.http.csproj" />
|
<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>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ln.bootstrap" Version="1.2.4" />
|
<PackageReference Include="ln.bootstrap" Version="1.4.0" />
|
||||||
<PackageReference Include="ln.http" Version="0.6.5" />
|
<PackageReference Include="ln.http" Version="0.9.1-test01" />
|
||||||
<PackageReference Include="ln.http.templates" Version="0.1.0" />
|
<!--PackageReference Include="ln.http.templates" Version="0.1.1" /-->
|
||||||
<PackageReference Include="ln.templates" Version="0.3.0" />
|
<!--PackageReference Include="ln.templates" Version="0.3.0" /-->
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Update="bootstrap.json">
|
<None Update="bootstrap.json">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
<None Update="ln.http.HttpServer.json">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<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
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.protocols.helper", "..\ln.protocols.helper\ln.protocols.helper.csproj", "{1C1D3A17-A615-4686-90BD-F0E221EAC89C}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.protocols.helper", "..\ln.protocols.helper\ln.protocols.helper.csproj", "{1C1D3A17-A615-4686-90BD-F0E221EAC89C}"
|
||||||
EndProject
|
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
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
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|x64.Build.0 = Release|Any CPU
|
||||||
{1C1D3A17-A615-4686-90BD-F0E221EAC89C}.Release|x86.ActiveCfg = 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
|
{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
|
EndGlobalSection
|
||||||
EndGlobal
|
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;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using ln.http.router;
|
|
||||||
using ln.json;
|
using ln.json;
|
||||||
using ln.type;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace ln.http.tests
|
namespace ln.http.tests
|
||||||
{
|
{
|
||||||
public class Tests
|
public class Tests
|
||||||
{
|
{
|
||||||
HttpServer server;
|
private HttpRouter TestRouter;
|
||||||
int testPort;
|
private int TestPort;
|
||||||
|
private Listener _httpListener;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
if (server != null)
|
TestRouter = new HttpRouter();
|
||||||
return;
|
TestRouter.Map(new TestApiController());
|
||||||
|
FileSystemRouter fileSystemRouter = new FileSystemRouter("/static/", AppContext.BaseDirectory);
|
||||||
|
TestRouter.Map(fileSystemRouter);
|
||||||
|
|
||||||
server = new HttpServer();
|
_httpListener = new Listener(TestRouter, IPAddress.Any, 0);
|
||||||
|
TestPort = _httpListener.LocalEndpoint.Port;
|
||||||
HttpRouter testRouter = new HttpRouter(server);
|
TestContext.Error.WriteLine("Using Port {0}", TestPort);
|
||||||
testRouter.Map(HttpMethod.ANY, "/controller/*", HttpRoutePriority.NORMAL, new TestApiController().Route);
|
}
|
||||||
|
|
||||||
FileSystemRouter fileSystemRouter = new FileSystemRouter(AppContext.BaseDirectory);
|
[TearDown]
|
||||||
testRouter.Map(HttpMethod.ANY, "/static/*", fileSystemRouter.Route);
|
public void TearDown()
|
||||||
|
{
|
||||||
HttpListener.DefaultPort = 0;
|
_httpListener?.Dispose();
|
||||||
HttpListener httpListener = new HttpListener(server);
|
TestRouter?.Dispose();
|
||||||
|
|
||||||
testPort = httpListener.LocalEndpoint.Port;
|
|
||||||
TestContext.Error.WriteLine("Using Port {0}", testPort);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Test1()
|
public void Test1()
|
||||||
{
|
{
|
||||||
HttpClient client = new HttpClient();
|
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);
|
Assert.AreEqual(System.Net.HttpStatusCode.OK, response.StatusCode);
|
||||||
|
|
||||||
|
@ -49,8 +47,6 @@ namespace ln.http.tests
|
||||||
|
|
||||||
CollectionAssert.AreEqual(fileBytes, contentBytes);
|
CollectionAssert.AreEqual(fileBytes, contentBytes);
|
||||||
|
|
||||||
//server.Stop();
|
|
||||||
|
|
||||||
Assert.Pass();
|
Assert.Pass();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,17 +55,18 @@ namespace ln.http.tests
|
||||||
{
|
{
|
||||||
JSONObject jsonPutObject = new JSONObject();
|
JSONObject jsonPutObject = new JSONObject();
|
||||||
jsonPutObject["PutTest"] = JSONTrue.Instance;
|
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");
|
jsonStringContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
|
||||||
|
|
||||||
HttpClient client = new HttpClient();
|
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.AreEqual(System.Net.HttpStatusCode.OK, response.StatusCode);
|
||||||
Assert.Pass();
|
Assert.Pass();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Map(HttpMethod.ANY, "/controller")]
|
||||||
class TestApiController : HttpEndpointController
|
class TestApiController : HttpEndpointController
|
||||||
{
|
{
|
||||||
[Map(HttpMethod.PUT, "/put")]
|
[Map(HttpMethod.PUT, "/put")]
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net5.0</TargetFramework>
|
|
||||||
|
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
|
|
||||||
<LangVersion>9</LangVersion>
|
<LangVersion>9</LangVersion>
|
||||||
|
|
||||||
|
<TargetFrameworks>net5.0;net6.0</TargetFrameworks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -14,11 +15,13 @@
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
|
||||||
|
|
||||||
<ProjectReference Include="../ln.http/ln.http.csproj" />
|
<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">
|
<Content Include="test.txt">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
|
||||||
|
<ProjectReference Include="..\ln.http.helpers\ln.http.helpers.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
Loading…
Reference in New Issue