Changes recommended by Rider/Resharper

This commit is contained in:
2022-04-08 00:59:51 +02:00
parent 105cec55d4
commit f7c1a581e7
15 changed files with 233 additions and 99 deletions

13
.idea/.idea.VAR.HttpServer/.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,13 @@
# Default ignored files
/shelf/
/workspace.xml
# Rider ignored files
/contentModel.xml
/.idea.VAR.Json.iml
/modules.xml
/projectSettingsUpdater.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
</project>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="UserContentModel">
<attachedFolders />
<explicitIncludes />
<explicitExcludes />
</component>
</project>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RiderProjectSettingsUpdater">
<option name="vcsConfiguration" value="2" />
</component>
</project>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@@ -3,15 +3,15 @@ using System.Diagnostics;
namespace VAR.HttpServer.MiniServerTest
{
internal class Program
public static class Program
{
private static void Main(string[] args)
private static void Main()
{
HttpServer httpServer = new HttpServer
{
Port = 3000,
Handler = new HelloWorldHttpHandler(),
LogDegugMessage = (msg) => Console.WriteLine("DEBUG: {0}", msg),
LogDebugMessage = (msg) => Console.WriteLine("DEBUG: {0}", msg),
LogException = (ex) =>
{
Console.WriteLine("!!!!! Exception !!!!");
@@ -19,14 +19,14 @@ namespace VAR.HttpServer.MiniServerTest
Console.WriteLine("StackTrace: {0}", ex.StackTrace);
}
};
Console.Title = string.Format("MiniHTTPServer@{0}", httpServer.Port);
Console.Title = $"MiniHTTPServer@{httpServer.Port}";
Console.WriteLine("HTTP Server started on {0} port", httpServer.Port);
httpServer.Start();
Process proc = Process.Start(string.Format("http://localhost:{0}", httpServer.Port));
Process.Start($"http://localhost:{httpServer.Port}");
}
public class HelloWorldHttpHandler : IHttpHandler
private class HelloWorldHttpHandler : IHttpHandler
{
public void HandleRequest(HttpProcessor p)
{
@@ -42,7 +42,7 @@ namespace VAR.HttpServer.MiniServerTest
{
greetedName = "World";
}
string strGreeting = string.Format("Hello {0}!", greetedName);
string strGreeting = $"Hello {greetedName}!";
// Render
p.ResponseSuccess();

View File

@@ -1,11 +1,11 @@
using System.Reflection;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("VAR.HttpServerTests")]
[assembly: AssemblyTitle("VAR.HttpServer.Tests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("VAR")]
[assembly: AssemblyProduct("VAR.HttpServerTests")]
[assembly: AssemblyProduct("VAR.HttpServer.Tests")]
[assembly: AssemblyCopyright("Copyright © VAR 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

View File

@@ -6,8 +6,8 @@
<ProjectGuid>{1D73D51B-D094-4775-93A4-A26F8B66C167}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>VAR.HttpServerTests</RootNamespace>
<AssemblyName>VAR.HttpServerTests</AssemblyName>
<RootNamespace>VAR.HttpServer.Tests</RootNamespace>
<AssemblyName>VAR.HttpServer.Tests</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>

View File

@@ -7,7 +7,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VAR.HttpServer", "VAR.HttpS
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VAR.HttpServer.MiniServerTest", "VAR.HttpServer.MiniServerTest\VAR.HttpServer.MiniServerTest.csproj", "{6BD47B75-3DC2-4559-9311-E3D8117D4A89}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VAR.HttpServerTests", "VAR.HttpServerTests\VAR.HttpServerTests.csproj", "{1D73D51B-D094-4775-93A4-A26F8B66C167}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VAR.HttpServer.Tests", "VAR.HttpServer.Tests\VAR.HttpServer.Tests.csproj", "{1D73D51B-D094-4775-93A4-A26F8B66C167}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution

View File

@@ -0,0 +1,58 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_IFELSE/@EntryValue">NotRequired</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/TRAILING_COMMA_IN_MULTILINE_LISTS/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/TRAILING_COMMA_IN_SINGLELINE_LISTS/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/EMPTY_BLOCK_STYLE/@EntryValue">TOGETHER_SAME_LINE</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_EMBEDDED_BLOCK_ARRANGEMENT/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_EMBEDDED_BLOCK_ON_SAME_LINE/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_AFTER_TYPECAST_PARENTHESES/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_WITHIN_SINGLE_LINE_ARRAY_INITIALIZER_BRACES/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/HtmlFormatter/ALLOW_FAR_ALIGNMENT/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/HtmlFormatter/NormalizeTagNames/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/HtmlFormatter/ProcessingInstructionAttributeIndenting/@EntryValue">OneStep</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/HtmlFormatter/TagAttributeIndenting/@EntryValue">OneStep</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/HtmlFormatter/TagSpaceBeforeHeaderEnd1/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForBuiltInTypes/@EntryValue">UseVarWhenEvident</s:String>
<s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForOtherTypes/@EntryValue">UseVarWhenEvident</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AES/@EntryIndexedValue">AES</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AM/@EntryIndexedValue">AM</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AUX/@EntryIndexedValue">AUX</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=DC/@EntryIndexedValue">DC</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=DES/@EntryIndexedValue">DES</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=EPM/@EntryIndexedValue">EPM</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GDI/@EntryIndexedValue">GDI</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ID/@EntryIndexedValue">ID</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IP/@EntryIndexedValue">IP</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RECT/@EntryIndexedValue">RECT</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RGB/@EntryIndexedValue">RGB</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SCART/@EntryIndexedValue">SCART</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SPDIF/@EntryIndexedValue">SPDIF</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SQL/@EntryIndexedValue">SQL</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SRCCOPY/@EntryIndexedValue">SRCCOPY</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TCP/@EntryIndexedValue">TCP</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=URL/@EntryIndexedValue">URL</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=USB/@EntryIndexedValue">USB</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=VAR/@EntryIndexedValue">VAR</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=WMIC/@EntryIndexedValue">WMIC</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=YRYBY/@EntryIndexedValue">YRYBY</s:String>
<s:Boolean x:Key="/Default/CodeStyle/Naming/CSharpNaming/ApplyAutoDetectedRules/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Constants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=EnumMember/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb"&gt;&lt;ExtraRule Prefix="T" Suffix="" Style="AaBb_AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Interfaces/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="I" Suffix="" Style="AaBb_AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=LocalConstants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Locals/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb_AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Method/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Parameters/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb_AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateConstants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb_AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb_AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticReadonly/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb_AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Property/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PublicFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=StaticReadonly/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypesAndNamespaces/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" /&gt;</s:String>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
</wpf:ResourceDictionary>

View File

@@ -0,0 +1,2 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/Highlighting/SweaWarningsMode/@EntryValue">ShowAndRun</s:String></wpf:ResourceDictionary>

View File

@@ -10,49 +10,65 @@ namespace VAR.HttpServer
{
private static readonly int MaxPostSize = 10 * 1024 * 1024; // 10MB
private TcpClient _socket;
public TcpClient Socket { get { return _socket; } }
private readonly TcpClient _socket;
private IHttpHandler _handler;
public IHttpHandler Handler { get { return _handler; } }
public TcpClient Socket => _socket;
private readonly Action<string> _logDebugMessage = null;
private readonly IHttpHandler _handler;
private readonly Action<Exception> _logException = null;
public IHttpHandler Handler => _handler;
// ReSharper disable once NotAccessedField.Local
private readonly Action<string> _logDebugMessage;
private readonly Action<Exception> _logException;
private Stream _inputStream;
private StreamWriter _outputStream;
public StreamWriter OutputStream { get { return _outputStream; } }
public StreamWriter OutputStream => _outputStream;
private string _httpRequest;
public string HttpRequest => _httpRequest;
private string _httpMethod;
public string HttpMethod { get { return _httpMethod; } }
public string HttpMethod => _httpMethod;
private string _httpResource;
public string HttpResource { get { return _httpResource; } }
public string HttpResource => _httpResource;
private string _httpResourceLowercase;
public string HttpResourceLowercase { get { return _httpResourceLowercase; } }
public string HttpResourceLowercase => _httpResourceLowercase;
private string _httpQuery;
public string HttpQuery { get { return _httpQuery; } }
public string HttpQuery => _httpQuery;
private string _httpProtocolVersionString;
private Dictionary<string, string> _httpHeaders = new Dictionary<string, string>();
public Dictionary<string, string> HttpHeader { get { return _httpHeaders; } }
public string HttpProtocolVersionString => _httpProtocolVersionString;
private readonly Dictionary<string, string> _httpHeaders = new Dictionary<string, string>();
public Dictionary<string, string> HttpHeader => _httpHeaders;
private string _postString;
public string PostString { get { return _postString; } }
private Dictionary<string, string> _httpParams = new Dictionary<string, string>();
public Dictionary<string, string> HttpParams { get { return _httpParams; } }
public string PostString => _postString;
public bool IsPostback { get { return _httpMethod.ToUpper().Equals("POST"); } }
private readonly Dictionary<string, string> _httpParams = new Dictionary<string, string>();
public HttpProcessor(TcpClient s, IHttpHandler handler, Action<string> logDebugMessage, Action<Exception> logException)
public Dictionary<string, string> HttpParams => _httpParams;
public bool IsPostback => _httpMethod.ToUpper().Equals("POST");
public HttpProcessor(TcpClient s, IHttpHandler handler, Action<string> logDebugMessage,
Action<Exception> logException)
{
_socket = s;
_handler = handler;
@@ -87,6 +103,7 @@ namespace VAR.HttpServer
ResponseServerError();
throw;
}
_outputStream.Flush();
_inputStream = null;
_outputStream = null;
@@ -100,16 +117,23 @@ namespace VAR.HttpServer
private string StreamReadLine(Stream inputStream)
{
int next_char;
string data = string.Empty;
while (true)
{
next_char = inputStream.ReadByte();
if (next_char == '\n') { break; }
if (next_char == '\r') { continue; }
if (next_char == -1) { Thread.Sleep(1); continue; };
data += Convert.ToChar(next_char);
int nextChar = inputStream.ReadByte();
if (nextChar == '\n') { break; }
if (nextChar == '\r') { continue; }
if (nextChar == -1)
{
Thread.Sleep(1);
continue;
}
data += Convert.ToChar(nextChar);
}
return data;
}
@@ -121,6 +145,7 @@ namespace VAR.HttpServer
{
throw new Exception("invalid HTTP request line");
}
_httpRequest = request;
_httpMethod = tokens[0].ToUpper();
_httpResource = tokens[1];
@@ -132,8 +157,9 @@ namespace VAR.HttpServer
int idx = _httpResource.IndexOf('?');
_httpQuery = _httpResource.Substring(idx + 1);
_httpResource = _httpResource.Substring(0, idx);
ReadParms(_httpQuery);
ReadParameters(_httpQuery);
}
_httpResourceLowercase = _httpResource.ToLower();
}
@@ -150,8 +176,9 @@ namespace VAR.HttpServer
int separator = line.IndexOf(':');
if (separator == -1)
{
throw new Exception(string.Format("Invalid HTTP header line: {0}", line));
throw new Exception($"Invalid HTTP header line: {line}");
}
string name = line.Substring(0, separator);
int pos = separator + 1;
while ((pos < line.Length) && (line[pos] == ' '))
@@ -168,55 +195,52 @@ namespace VAR.HttpServer
private void ReadPostData()
{
int contentLen = 0;
MemoryStream ms = new MemoryStream();
if (_httpHeaders.ContainsKey("Content-Length"))
{
contentLen = Convert.ToInt32(_httpHeaders["Content-Length"]);
int contentLen = Convert.ToInt32(_httpHeaders["Content-Length"]);
if (contentLen > MaxPostSize)
{
throw new Exception(string.Format("POST Content-Length({0}) > MaxPostSize({1})", contentLen, MaxPostSize));
throw new Exception($"POST Content-Length({contentLen}) > MaxPostSize({MaxPostSize})");
}
byte[] buf = new byte[BufferSize];
int to_read = contentLen;
while (to_read > 0)
int toRead = contentLen;
while (toRead > 0)
{
int numread = _inputStream.Read(buf, 0, Math.Min(BufferSize, to_read));
if (numread == 0)
int numRead = _inputStream.Read(buf, 0, Math.Min(BufferSize, toRead));
if (numRead == 0)
{
if (to_read == 0)
{
break;
}
else
{
throw new Exception("Client disconnected during POST");
}
throw new Exception("Client disconnected during POST");
}
to_read -= numread;
ms.Write(buf, 0, numread);
toRead -= numRead;
ms.Write(buf, 0, numRead);
}
ms.Seek(0, SeekOrigin.Begin);
}
_postString = new StreamReader(ms).ReadToEnd();
if (string.IsNullOrEmpty(_postString) == false)
{
ReadParms(_postString);
ReadParameters(_postString);
}
}
private void ReadParms(string parms)
private void ReadParameters(string strParameters)
{
string[] parmPairs = parms.Split('&');
foreach (string parmPair in parmPairs)
string[] parameterPairs = strParameters.Split('&');
foreach (string parameterPair in parameterPairs)
{
string[] tokens = parmPair.Split('=');
string[] tokens = parameterPair.Split('=');
string key = HttpUtility.UrlDecode(tokens[0]);
string value = string.Empty;
if (tokens.Length > 1)
{
value = HttpUtility.UrlDecode(tokens[1]);
}
if (_httpParams.ContainsKey(key))
{
_httpParams[key] = value;
@@ -233,7 +257,7 @@ namespace VAR.HttpServer
try
{
_outputStream.WriteLine("HTTP/1.0 200 OK");
_outputStream.WriteLine(string.Format("Content-Type: {0}", contentType));
_outputStream.WriteLine($"Content-Type: {contentType}");
_outputStream.WriteLine("Connection: close");
_outputStream.WriteLine("");
}

View File

@@ -7,36 +7,48 @@ namespace VAR.HttpServer
{
public class HttpServer
{
protected int _port = 8000;
private int _port = 8000;
public int Port
{
get { return _port; }
get => _port;
set
{
if (_isActive) { throw new Exception("HttpServer: Can't set port while active"); }
_port = value;
}
}
private TcpListener _listener = null;
private TcpListener _listener;
private Thread _thread = null;
private Thread _thread;
private bool _isActive = false;
public bool IsActive { get { return _isActive; } }
private bool _isActive;
public bool IsActive => _isActive;
private IHttpHandler _handler;
private IHttpHandler _handler = null;
public IHttpHandler Handler
{
get { return _handler; }
set { _handler = value; }
get => _handler;
set => _handler = value;
}
private Action<string> _logDebugMessage = null;
public Action<string> LogDegugMessage { set { _logDebugMessage = value; } }
private Action<string> _logDebugMessage;
private Action<Exception> _logException = null;
public Action<Exception> LogException { set { _logException = value; } }
public Action<string> LogDebugMessage
{
set => _logDebugMessage = value;
}
private Action<Exception> _logException;
public Action<Exception> LogException
{
set => _logException = value;
}
private void ListenConnections()
{
@@ -45,10 +57,12 @@ namespace VAR.HttpServer
while (_isActive)
{
TcpClient client = _listener.AcceptTcpClient();
HttpProcessor responseProcessor = new HttpProcessor(client, _handler, _logDebugMessage, _logException);
Thread responseThread = new Thread(new ThreadStart(responseProcessor.Process));
HttpProcessor responseProcessor =
new HttpProcessor(client, _handler, _logDebugMessage, _logException);
Thread responseThread = new Thread(responseProcessor.Process);
responseThread.Start();
}
_listener = null;
}
catch (Exception)
@@ -72,7 +86,7 @@ namespace VAR.HttpServer
};
_listener.Start();
_isActive = true;
_thread = new Thread(new ThreadStart(ListenConnections));
_thread = new Thread(ListenConnections);
_thread.Start();
}
catch (Exception ex)
@@ -80,6 +94,7 @@ namespace VAR.HttpServer
_logException?.Invoke(ex);
return false;
}
return true;
}
@@ -97,6 +112,7 @@ namespace VAR.HttpServer
{
_listener.Stop();
}
_thread = null;
}
catch (Exception ex)
@@ -104,6 +120,7 @@ namespace VAR.HttpServer
_logException?.Invoke(ex);
return false;
}
return true;
}
}

View File

@@ -4,7 +4,7 @@ using System.Text;
namespace VAR.HttpServer
{
public sealed class HttpUtility
public static class HttpUtility
{
public static string UrlDecode(string str, Encoding e = null)
{
@@ -19,20 +19,19 @@ namespace VAR.HttpServer
long len = str.Length;
var bytes = new List<byte>();
int xchar;
char ch;
for (int i = 0; i < len; i++)
{
ch = str[i];
char ch = str[i];
if (ch == '%' && i + 2 < len && str[i + 1] != '%')
{
int xChar;
if (str[i + 1] == 'u' && i + 5 < len)
{
xchar = HexToInt(str, i + 2, 4);
if (xchar != -1)
xChar = HexToInt(str, i + 2, 4);
if (xChar != -1)
{
WriteCharBytes(bytes, (char)xchar, e);
WriteCharBytes(bytes, (char)xChar, e);
i += 5;
}
else
@@ -40,32 +39,24 @@ namespace VAR.HttpServer
WriteCharBytes(bytes, '%', e);
}
}
else if ((xchar = HexToInt(str, i + 1, 2)) != -1)
else if ((xChar = HexToInt(str, i + 1, 2)) != -1)
{
WriteCharBytes(bytes, (char)xchar, e);
WriteCharBytes(bytes, (char)xChar, e);
i += 2;
}
else
{
WriteCharBytes(bytes, '%', e);
}
continue;
}
if (ch == '+')
{
WriteCharBytes(bytes, ' ', e);
}
else
{
WriteCharBytes(bytes, ch, e);
}
WriteCharBytes(bytes, ch == '+' ? ' ' : ch, e);
}
byte[] buf = bytes.ToArray();
bytes = null;
return e.GetString(buf);
}
private static void WriteCharBytes(IList buf, char ch, Encoding e)
@@ -115,6 +106,7 @@ namespace VAR.HttpServer
int current = HexDigitToInt((byte)c);
if (current == -1) { return -1; }
val = (val << 4) + current;
}
@@ -125,6 +117,7 @@ namespace VAR.HttpServer
{
StringBuilder sbOutput = new StringBuilder();
if (e == null) { e = Encoding.UTF8; }
byte[] bytes = e.GetBytes(str);
foreach (byte c in bytes)
{
@@ -133,13 +126,16 @@ namespace VAR.HttpServer
sbOutput.Append('+');
continue;
}
if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
{
sbOutput.Append((char)c);
continue;
}
sbOutput.AppendFormat("%{0:X2}", (int)c);
}
return sbOutput.ToString();
}
}