Browse Source

Merge branch 'master' of http://elivo.cn:3000/apewer/apewer-dotnet into master

master
王厅 1 month ago
parent
commit
551881786c
  1. 43
      Apewer .NET.sln
  2. 42
      Apewer.Source/Apewer.Source.csproj
  3. 36
      Apewer.Web/Apewer.Web.csproj
  4. 12
      Apewer.Web/WebSocket/ChatServer.cs
  5. 66
      Apewer.Web/WebSocket/GenericServer.cs
  6. 126
      Apewer.Windows/Apewer.Windows.csproj
  7. 123
      Apewer.Windows/WinForm/ModifierKey.cs
  8. 135
      Apewer/BytesUtility.cs
  9. 20
      Apewer/Network/HttpHeaders.cs
  10. 18
      Apewer/Web/MiniServer.cs
  11. 4
      Apewer/Web/StaticController.cs

43
Apewer .NET.sln

@ -0,0 +1,43 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.35325.158
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Apewer", "Apewer\Apewer.csproj", "{7C47A362-78F9-4EC2-86F1-B442658D2466}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Apewer.Source", "Apewer.Source\Apewer.Source.csproj", "{AFF499E2-10D0-406B-A563-CE3327D57962}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Apewer.Web", "Apewer.Web\Apewer.Web.csproj", "{0C9CD2F9-E0C2-4BAC-84C1-33A57798D6CC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Apewer.Windows", "Apewer.Windows\Apewer.Windows.csproj", "{5FB935E5-01E8-4CA7-9157-DC58BD731408}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7C47A362-78F9-4EC2-86F1-B442658D2466}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7C47A362-78F9-4EC2-86F1-B442658D2466}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7C47A362-78F9-4EC2-86F1-B442658D2466}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7C47A362-78F9-4EC2-86F1-B442658D2466}.Release|Any CPU.Build.0 = Release|Any CPU
{AFF499E2-10D0-406B-A563-CE3327D57962}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AFF499E2-10D0-406B-A563-CE3327D57962}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AFF499E2-10D0-406B-A563-CE3327D57962}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AFF499E2-10D0-406B-A563-CE3327D57962}.Release|Any CPU.Build.0 = Release|Any CPU
{0C9CD2F9-E0C2-4BAC-84C1-33A57798D6CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0C9CD2F9-E0C2-4BAC-84C1-33A57798D6CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0C9CD2F9-E0C2-4BAC-84C1-33A57798D6CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0C9CD2F9-E0C2-4BAC-84C1-33A57798D6CC}.Release|Any CPU.Build.0 = Release|Any CPU
{5FB935E5-01E8-4CA7-9157-DC58BD731408}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5FB935E5-01E8-4CA7-9157-DC58BD731408}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5FB935E5-01E8-4CA7-9157-DC58BD731408}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5FB935E5-01E8-4CA7-9157-DC58BD731408}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7A4C1E3C-8A0A-4128-A143-627A9F76EF02}
EndGlobalSection
EndGlobal

42
Apewer.Source/Apewer.Source.csproj

@ -1,29 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\Apewer\Apewer.props" />
<Import Project="..\Apewer\Apewer.props" />
<PropertyGroup>
<DefineConstants>SOURCE;$(DefineConstants);</DefineConstants>
<DefineConstants Condition="'$(TargetFramework)'=='netstandard2.0'">MYSQL_6_10;$(DefineConstants);</DefineConstants>
<DefineConstants Condition="'$(TargetFramework)'=='net40'">MYSQL_6_9;$(DefineConstants);</DefineConstants>
<TargetFrameworks>netstandard2.0;net40;net20</TargetFrameworks>
</PropertyGroup>
<PropertyGroup>
<DefineConstants>SOURCE;$(DefineConstants);</DefineConstants>
<DefineConstants Condition="'$(TargetFramework)'=='netstandard2.0'">MYSQL_6_10;$(DefineConstants);</DefineConstants>
<DefineConstants Condition="'$(TargetFramework)'=='net40'">MYSQL_6_9;$(DefineConstants);</DefineConstants>
<TargetFrameworks>netstandard2.0;net40;net20</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Apewer\Apewer.csproj" />
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.110" PrivateAssets="all" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Apewer\Apewer.csproj" />
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.110" PrivateAssets="all" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)'=='netstandard2.0'">
<PackageReference Include="System.Configuration.ConfigurationManager" Version="4.4.1" />
<PackageReference Include="System.Data.SqlClient" Version="4.4.3" />
<PackageReference Include="System.Security.Permissions" Version="4.4.1" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.4.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)'=='netstandard2.0'">
<PackageReference Include="System.Configuration.ConfigurationManager" Version="4.4.1" />
<PackageReference Include="System.Data.SqlClient" Version="4.4.3" />
<PackageReference Include="System.Security.Permissions" Version="4.4.1" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.4.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)'=='net40'">
<Reference Include="System.Configuration" />
<Reference Include="System.Transactions" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)'=='net40'">
<Reference Include="System.Configuration" />
<Reference Include="System.Transactions" />
</ItemGroup>
</Project>

36
Apewer.Web/Apewer.Web.csproj

@ -1,25 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\Apewer\Apewer.props" />
<Import Project="..\Apewer\Apewer.props" />
<PropertyGroup>
<DefineConstants>WEB;$(DefineConstants);</DefineConstants>
<TargetFrameworks>netcoreapp3.1;net40;net20</TargetFrameworks>
</PropertyGroup>
<PropertyGroup>
<DefineConstants>WEB;$(DefineConstants);</DefineConstants>
<TargetFrameworks>netcoreapp3.1;net40;net20</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="FavIcon.ico" />
<EmbeddedResource Include="WebConfig40.xml" />
<EmbeddedResource Include="WebConfigStd.xml" />
<EmbeddedResource Include="WebConfig461.xml" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="FavIcon.ico" />
<EmbeddedResource Include="WebConfig40.xml" />
<EmbeddedResource Include="WebConfigStd.xml" />
<EmbeddedResource Include="WebConfig461.xml" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Apewer\Apewer.csproj" />
<FrameworkReference Condition="'$(TargetFramework)' == 'netcoreapp3.1'" Include="Microsoft.AspNetCore.App" />
<Reference Condition="'$(TargetFramework)' == 'net461'" Include="System.Web" />
<Reference Condition="'$(TargetFramework)' == 'net40'" Include="System.Web" />
<Reference Condition="'$(TargetFramework)' == 'net20'" Include="System.Web" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Apewer\Apewer.csproj" />
<FrameworkReference Condition="'$(TargetFramework)' == 'netcoreapp3.1'" Include="Microsoft.AspNetCore.App" />
<Reference Condition="'$(TargetFramework)' == 'net461'" Include="System.Web" />
<Reference Condition="'$(TargetFramework)' == 'net40'" Include="System.Web" />
<Reference Condition="'$(TargetFramework)' == 'net20'" Include="System.Web" />
</ItemGroup>
</Project>

12
Apewer.Web/WebSocket/ChatServer.cs

@ -4,6 +4,7 @@ using Apewer;
using Apewer.Network;
using System;
using System.Collections.Generic;
using System.Net;
namespace Apewer.WebSocket
{
@ -127,18 +128,19 @@ namespace Apewer.WebSocket
_websocket = new GenericServer();
lock (_websocket)
{
var ws = _websocket.Start(_websocketport, _websocketaddress);
if (ws)
try
{
_websocket.Start(_websocketport, IPAddress.Parse(_websocketaddress));
_websocket.OnMessage += WebSocketReceived;
_websocket.OnOpen += WebsocketOnOpen;
_websocket.OnClose += WebsocketOnClose;
RaiseConsole("WebSocket 服务已启动。");
}
else
catch (Exception ex)
{
_websocket = null;
RaiseError("WebSocket 服务启动失败。");
RaiseError($"WebSocket 服务启动失败:{ex.Message()}");
return;
}
@ -426,7 +428,7 @@ namespace Apewer.WebSocket
{
var input = Console.ReadLine();
if (input == "exit") break;
ws.Send(ws.Address, ":", ws.Port.ToString(), "\n", input);
ws.Send(ws.Address.ToString(), ":", ws.Port.ToString(), "\n", input);
}
ws.Close();

66
Apewer.Web/WebSocket/GenericServer.cs

@ -3,6 +3,7 @@
using Apewer;
using System;
using System.Collections.Generic;
using System.Net;
namespace Apewer.WebSocket
{
@ -11,15 +12,12 @@ namespace Apewer.WebSocket
public sealed class GenericServer : IDisposable
{
const string DefaultAddress = "0.0.0.0";
const ushort DefaultPort = 8000;
private Dictionary<int, Connection> _connections = new Dictionary<int, Connection>();
private WebSocketServer _server = null;
private bool _running = false;
private string _address = null;
private int _port = DefaultPort;
private IPAddress _address = null;
private int _port = 0;
/// <summary></summary>
public event SocketEvent OnOpen;
@ -54,7 +52,7 @@ namespace Apewer.WebSocket
}
/// <summary>监听的地址。</summary>
public string Address
public IPAddress Address
{
get { return _address; }
}
@ -101,28 +99,46 @@ namespace Apewer.WebSocket
_running = false;
}
/// <summary>启动监听,如果监听正在运行则失败。在所有 IPv4 网络接口上自动选择可用的端口号。</summary>
/// <returns>已监听的端口号。</returns>
/// <exception cref="FormatException" />
/// <exception cref="InvalidOperationException" />
public void Start() => Start(0, null);
/// <summary>启动监听,如果监听正在运行则失败。</summary>
public bool Start(int port = DefaultPort, string address = DefaultAddress)
/// <param name="endPoint">要监听的终结点。指定为 NULL 时将在所有 IPv4 网络接口上自动选择可用的端口号。</param>
/// <returns>已监听的端口号。</returns>
/// <exception cref="ArgumentOutOfRangeException" />
/// <exception cref="FormatException" />
/// <exception cref="InvalidOperationException" />
public void Start(IPEndPoint endPoint)
{
if (address == null) return false;
if (_running) return false;
_address = address ?? "";
_port = NumberUtility.Restrict( port, 0, ushort.MaxValue);
if (endPoint == null) Start(0, null);
else Start(endPoint.Port, endPoint.Address);
}
try
{
var location = "ws://" + address + ":" + port.ToString();
_server = new WebSocketServer(location);
_server.Start(Initialize);
_running = true;
return true;
}
catch (Exception exception)
{
RaiseExcepted(exception);
return false;
}
/// <summary>启动监听,如果监听正在运行则失败。</summary>
/// <param name="port">要监听的端口号。指定为 0 时将自动选择可用的端口号。</param>
/// <param name="address">要监听的网络接口。指定为 NULL 时将在所有 IPv4 网络接口监听,等同于 <see cref="IPAddress.Any"/>。</param>
/// <returns>已监听的端口号。</returns>
/// <exception cref="ArgumentOutOfRangeException" />
/// <exception cref="FormatException" />
/// <exception cref="InvalidOperationException" />
public void Start(int port, IPAddress address = null)
{
if (address == null) address = IPAddress.Any;
if (port < 0) throw new ArgumentOutOfRangeException(nameof(port));
if (port > 65535) throw new ArgumentOutOfRangeException(nameof(port));
if (_running) throw new InvalidOperationException("示例已经在运行中,无法再次启动。");
_address = address;
_port = port;
var location = "ws://" + _address.ToString() + ":" + port.ToString();
_server = new WebSocketServer(location);
_server.Start(Initialize);
_port = _server.Port;
_running = true;
}
/// <summary>对所有连接发送文本。</summary>

126
Apewer.Windows/Apewer.Windows.csproj

@ -3,77 +3,77 @@
<Import Project="..\Apewer\Apewer.props" />
<PropertyGroup>
<NoWarn>CS0108;CS0612</NoWarn>
<TargetFrameworks>net461;net40;net20;netcoreapp3.1</TargetFrameworks>
<NoWarn>CS0108;CS0612</NoWarn>
<TargetFrameworks>net461;net40;net20;netcoreapp3.1</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Apewer\Apewer.csproj" />
</ItemGroup>
<!-- .NET Core 3.1 -->
<PropertyGroup Condition="'$(TargetFramework)'=='netcoreapp3.1'">
<!-- <UseWPF>true</UseWPF> -->
<!-- <UseWindowsForms>true</UseWindowsForms> -->
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)'=='netcoreapp3.1'">
<!-- <FrameworkReference Include="Microsoft.AspNetCore.App" /> -->
<FrameworkReference Include="Microsoft.WindowsDesktop.App" />
</ItemGroup>
<!-- .NET Core 3.1 -->
<PropertyGroup Condition="'$(TargetFramework)'=='netcoreapp3.1'">
<!-- <UseWPF>true</UseWPF> -->
<!-- <UseWindowsForms>true</UseWindowsForms> -->
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)'=='netcoreapp3.1'">
<!-- <FrameworkReference Include="Microsoft.AspNetCore.App" /> -->
<FrameworkReference Include="Microsoft.WindowsDesktop.App" />
</ItemGroup>
<!-- .NET Framework 4.6.1 -->
<ItemGroup Condition="'$(TargetFramework)'=='net461'">
<Reference Include="CustomMarshalers" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="PresentationCore" />
<Reference Include="System.Core" />
<Reference Include="System.Configuration" />
<Reference Include="System.Design" />
<Reference Include="System.Drawing" />
<Reference Include="System.Management" />
<Reference Include="System.Runtime.Caching" />
<Reference Include="System.Security" />
<Reference Include="System.Speech" />
<Reference Include="System.Transactions" />
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
<Reference Include="WindowsBase" />
</ItemGroup>
<!-- .NET Framework 4.6.1 -->
<ItemGroup Condition="'$(TargetFramework)'=='net461'">
<Reference Include="CustomMarshalers" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="PresentationCore" />
<Reference Include="System.Core" />
<Reference Include="System.Configuration" />
<Reference Include="System.Design" />
<Reference Include="System.Drawing" />
<Reference Include="System.Management" />
<Reference Include="System.Runtime.Caching" />
<Reference Include="System.Security" />
<Reference Include="System.Speech" />
<Reference Include="System.Transactions" />
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
<Reference Include="WindowsBase" />
</ItemGroup>
<!-- .NET Framework 4.0 -->
<ItemGroup Condition="'$(TargetFramework)'=='net40'">
<Reference Include="CustomMarshalers" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="PresentationCore" />
<Reference Include="System.Core" />
<Reference Include="System.Configuration" />
<Reference Include="System.Design" />
<Reference Include="System.Drawing" />
<Reference Include="System.Management" />
<Reference Include="System.Runtime.Caching" />
<Reference Include="System.Security" />
<Reference Include="System.Speech" />
<Reference Include="System.Transactions" />
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
<Reference Include="WindowsBase" />
</ItemGroup>
<!-- .NET Framework 4.0 -->
<ItemGroup Condition="'$(TargetFramework)'=='net40'">
<Reference Include="CustomMarshalers" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="PresentationCore" />
<Reference Include="System.Core" />
<Reference Include="System.Configuration" />
<Reference Include="System.Design" />
<Reference Include="System.Drawing" />
<Reference Include="System.Management" />
<Reference Include="System.Runtime.Caching" />
<Reference Include="System.Security" />
<Reference Include="System.Speech" />
<Reference Include="System.Transactions" />
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
<Reference Include="WindowsBase" />
</ItemGroup>
<!-- .NET Framework 2.0 -->
<ItemGroup Condition="'$(TargetFramework)'=='net20'">
<Reference Include="CustomMarshalers" />
<Reference Include="System.Configuration" />
<Reference Include="System.Design" />
<Reference Include="System.Management" />
<Reference Include="System.Security" />
<Reference Include="System.Transactions" />
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup>
<Compile Update="Tray\MainForm.cs">
<SubType>Form</SubType>
</Compile>
</ItemGroup>
<!-- .NET Framework 2.0 -->
<ItemGroup Condition="'$(TargetFramework)'=='net20'">
<Reference Include="CustomMarshalers" />
<Reference Include="System.Configuration" />
<Reference Include="System.Design" />
<Reference Include="System.Management" />
<Reference Include="System.Security" />
<Reference Include="System.Transactions" />
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup>
<Compile Update="Tray\MainForm.cs">
<SubType>Form</SubType>
</Compile>
</ItemGroup>
</Project>

123
Apewer.Windows/WinForm/ModifierKey.cs

@ -0,0 +1,123 @@
using System;
namespace Apewer.WinForm
{
/// <summary>修饰键。</summary>
public struct ModifierKey : IEquatable<ModifierKey>
{
byte _value;
bool _alt;
bool _ctrl;
bool _shift;
bool _win;
/// <summary>包含 ALT 键。</summary>
public bool WithALT { get => _alt; }
/// <summary>包含 CTRL 键。</summary>
public bool WithCTRL { get => _ctrl; }
/// <summary>包含 SHIFT 键。</summary>
public bool WithSHIFT { get => _shift; }
/// <summary>包含 WIN 键。</summary>
public bool WithWIN { get => _win; }
/// <summary>修饰键组合的值。</summary>
public byte Value { get => _value; }
/// <exception cref="OverflowException"></exception>
private ModifierKey(byte value)
{
_alt = value << 7 >> 7 == 1;
_ctrl = value << 6 >> 7 == 1;
_shift = value << 5 >> 7 == 1;
_win = value << 4 >> 7 == 1;
_value = Convert.ToByte(value);
if (_value != value) throw new OverflowException($"参数【{value}】含有无效的键。");
}
private ModifierKey(bool alt, bool ctrl, bool shift, bool win)
{
_alt = alt;
_ctrl = ctrl;
_shift = shift;
_win = win;
var value = 0;
if (alt) value += 0x01;
if (ctrl) value += 0x02;
if (shift) value += 0x04;
if (win) value += 0x05;
_value = Convert.ToByte(value);
}
/// <summary></summary>
public override int GetHashCode() => _value;
/// <summary></summary>
public override bool Equals(object obj)
{
if (obj is ModifierKey b) return _value == b._value;
return false;
}
/// <summary></summary>
public bool Equals(ModifierKey another) => _value == another._value;
/// <summary></summary>
public static implicit operator byte(ModifierKey instance) => instance._value;
/// <summary></summary>
/// <exception cref="OverflowException"></exception>
public static implicit operator ModifierKey(byte value) => new ModifierKey(value);
/// <summary></summary>
/// <exception cref="ArgumentException" />
public static ModifierKey operator +(ModifierKey a, ModifierKey b)
{
if (a._alt && b._alt) throw new ArgumentException("相加的两个组合键共同包含了 ALT 键。");
if (a._ctrl && b._ctrl) throw new ArgumentException("相加的两个组合键共同包含了 CTRL 键。");
if (a._shift && b._shift) throw new ArgumentException("相加的两个组合键共同包含了 SHIFT 键。");
if (a._win && b._win) throw new ArgumentException("相加的两个组合键共同包含了 WIN 键。");
var alt = a._alt || b._alt;
var ctrl = a._ctrl || b._ctrl;
var shift = a._shift || b._shift;
var win = a._win || b._win;
return new ModifierKey(alt, ctrl, shift, win);
}
/// <summary></summary>
public static ModifierKey operator -(ModifierKey a, ModifierKey b)
{
var alt = a._alt;
var ctrl = a._ctrl;
var shift = a._shift;
var win = a._win;
if (b._alt) alt = false;
if (b._ctrl) ctrl = false;
if (b._shift) shift = false;
if (b._win) win = false;
return new ModifierKey(alt, ctrl, shift, win);
}
/// <summary>表示 ALT 修饰键。</summary>
public static ModifierKey ALT { get; } = new ModifierKey(0x01);
/// <summary>表示 CTRL 修饰键。</summary>
public static ModifierKey CTRL { get; } = new ModifierKey(0x02);
/// <summary>表示 SHIFT 修饰键。</summary>
public static ModifierKey SHIFT { get; } = new ModifierKey(0x04);
/// <summary>表示 WIN 修饰键。</summary>
public static ModifierKey WIN { get; } = new ModifierKey(0x08);
}
}

135
Apewer/BytesUtility.cs

@ -767,6 +767,17 @@ namespace Apewer
#endregion
#region PKCS #5
/// <summary>使用密码生成密钥。</summary>
static byte[] PKCS5(byte[] password, byte[] salt = null, int iterations = 1000, int bits = 32)
{
var rfc2898 = new Rfc2898DeriveBytes(password, salt, 1);
return rfc2898.GetBytes(32);
}
#endregion
#region AES
private static void Aes256(byte[] key, byte[] salt, Func<RijndaelManaged, ICryptoTransform> create, Stream input, Stream output)
@ -842,6 +853,130 @@ namespace Apewer
return result;
}
private static readonly byte[] AesDefaultIV = new byte[16];
static T UseAes<T>(byte[] key, byte[] iv, CipherMode cipherMode, PaddingMode paddingMode, Func<RijndaelManaged, T> callback)
{
if (key == null) throw new ArgumentNullException(nameof(key));
var keySize = key.Length * 8;
switch (keySize)
{
case 128:
case 192:
case 256:
break;
default:
throw new ArgumentException($"密钥大小【{keySize}】bits 无效。");
}
if (iv == null) iv = AesDefaultIV;
var ivSize = iv.Length * 8;
if (ivSize != 128) throw new ArgumentException($"初始化向量【{ivSize}】bits 无效。");
using (var rijndael = new RijndaelManaged())
{
rijndael.Key = key;
rijndael.IV = iv;
rijndael.Mode = cipherMode;
rijndael.Padding = paddingMode;
return callback.Invoke(rijndael);
}
}
static void UseAes(Stream input, Stream output, byte[] key, byte[] iv, CipherMode cipherMode, PaddingMode paddingMode, Func<RijndaelManaged, ICryptoTransform> create)
{
if (input == null) throw new ArgumentNullException(nameof(input));
if (output == null) throw new ArgumentNullException(nameof(output));
UseAes<object>(key, iv, cipherMode, paddingMode, rijndael =>
{
using (var transformer = create.Invoke(rijndael))
{
using (var stream = new CryptoStream(output, transformer, CryptoStreamMode.Write))
{
Read(input, stream);
stream.Close();
}
}
return null;
});
}
static byte[] UseAes(byte[] input, byte[] key, byte[] iv, CipherMode cipherMode, PaddingMode paddingMode, Func<RijndaelManaged, ICryptoTransform> create)
{
if (input == null) input = new byte[0];
var result = null as byte[];
return UseAes<byte[]>(key, iv, cipherMode, paddingMode, rijndael =>
{
using (var transformer = create.Invoke(rijndael))
{
var result = transformer.TransformFinalBlock(input, 0, input.Length);
return result;
}
});
}
/// <summary>执行 AES 128/192/256 加密。</summary>
/// <param name="plain">明文。</param>
/// <param name="key">密钥。</param>
/// <param name="cipherMode">块密码模式。</param>
/// <param name="paddingMode">填充模式。</param>
/// <returns></returns>
/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
/// <exception cref="CryptographicException" />
public static byte[] AesEncrypt(byte[] plain, byte[] key, CipherMode cipherMode = CipherMode.ECB, PaddingMode paddingMode = PaddingMode.PKCS7)
{
return UseAes(plain, key, null, cipherMode, paddingMode, (rijndael) => rijndael.CreateEncryptor(rijndael.Key, rijndael.IV));
}
/// <summary>执行 AES 128/192/256 加密。</summary>
/// <param name="plain">明文。</param>
/// <param name="key">密钥,长度必须是 128 位(16 字节)、192 位(24 字节)或 256 位(32 字节)。</param>
/// <param name="iv">初始化向量,必须是 128 位(16 字节)。</param>
/// <param name="cipherMode">块密码模式。</param>
/// <param name="paddingMode">填充模式。</param>
/// <returns></returns>
/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
/// <exception cref="CryptographicException" />
public static byte[] AesEncrypt(byte[] plain, byte[] key, byte[] iv, CipherMode cipherMode = CipherMode.ECB, PaddingMode paddingMode = PaddingMode.PKCS7)
{
return UseAes(plain, key, iv, cipherMode, paddingMode, (rijndael) => rijndael.CreateEncryptor(rijndael.Key, rijndael.IV));
}
/// <summary>执行 AES 128/192/256 解密。</summary>
/// <param name="cipher">密文。</param>
/// <param name="key">密钥,长度必须是 128 位(16 字节)、192 位(24 字节)或 256 位(32 字节)。</param>
/// <param name="cipherMode">块密码模式。</param>
/// <param name="paddingMode">填充模式。</param>
/// <returns></returns>
/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
/// <exception cref="CryptographicException" />
public static byte[] AesDecrypt(byte[] cipher, byte[] key, CipherMode cipherMode = CipherMode.ECB, PaddingMode paddingMode = PaddingMode.PKCS7)
{
return UseAes(cipher, key, null, cipherMode, paddingMode, (rijndael) => rijndael.CreateEncryptor(rijndael.Key, rijndael.IV));
}
/// <summary>执行 AES 128/192/256 解密。</summary>
/// <param name="cipher">密文。</param>
/// <param name="key">密钥,长度必须是 128 位(16 字节)、192 位(24 字节)或 256 位(32 字节)。</param>
/// <param name="iv">初始化向量,必须是 128 位(16 字节)。</param>
/// <param name="cipherMode">块密码模式。</param>
/// <param name="paddingMode">填充模式。</param>
/// <returns></returns>
/// <exception cref="ArgumentNullException" />
/// <exception cref="ArgumentException" />
/// <exception cref="CryptographicException" />
public static byte[] AesDecrypt(byte[] cipher, byte[] key, byte[] iv, CipherMode cipherMode = CipherMode.ECB, PaddingMode paddingMode = PaddingMode.PKCS7)
{
return UseAes(cipher, key, iv, cipherMode, paddingMode, (rijndael) => rijndael.CreateEncryptor(rijndael.Key, rijndael.IV));
}
#endregion
#region Hash

20
Apewer/Network/HttpHeaders.cs

@ -328,12 +328,32 @@ namespace Apewer.Network
return Add(name, value);
}
/// <summary>按名称排序。</summary>
public void Sort() => _list.Sort();
/// <summary>按指定的方式排序。</summary>
public void Sort(IComparer<HttpHeader> comparer) => _list.Sort(comparer ?? throw new ArgumentNullException(nameof(comparer)));
/// <summary>按指定的方式排序。</summary>
public void Sort(Comparison<HttpHeader> comparison) => _list.Sort(comparison ?? throw new ArgumentNullException(nameof(comparison)));
/// <summary>每个元素组成为新数组。</summary>
public HttpHeader[] ToArray() => _list.ToArray();
/// <summary>生成 <see cref="StringPairs"/> 数组。</summary>
public StringPairs ToStringParis()
{
var sp = new StringPairs();
foreach (var item in _list) sp.Add(item.Name, item.Value);
return sp;
}
/// <summary></summary>
public override string ToString() => $"Count = {_list.Count}";
/// <summary></summary>
public static implicit operator StringPairs(HttpHeaders headers) => headers?.ToStringParis();
#endregion
#region Json

18
Apewer/Web/MiniServer.cs

@ -151,7 +151,23 @@ namespace Apewer.Web
{
while (_socket != null)
{
var socket = _socket.Accept();
var socket = null as Socket;
try
{
socket = _socket.Accept();
}
catch
{
if (socket != null)
{
try { socket.Close(); } catch { }
try { socket.Disconnect(false); } catch { }
#if !NET20
try { socket.Dispose(); } catch { }
#endif
}
break;
}
if (socket != null) ThreadPool.QueueUserWorkItem(Process, socket);
}
}

4
Apewer/Web/StaticController.cs

@ -101,14 +101,14 @@ namespace Apewer.Web
if (System.IO.Directory.Exists(web))
{
_root = new Class<string>(web);
return www;
return web;
}
var @static = StorageUtility.CombinePath(app, "static");
if (System.IO.Directory.Exists(@static))
{
_root = new Class<string>(@static);
return www;
return @static;
}
_root = new Class<string>(app);

Loading…
Cancel
Save