diff --git a/.idea/.idea.VAR.HttpServer/.idea/.gitignore b/.idea/.idea.VAR.HttpServer/.idea/.gitignore
new file mode 100644
index 0000000..60335c0
--- /dev/null
+++ b/.idea/.idea.VAR.HttpServer/.idea/.gitignore
@@ -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
diff --git a/.idea/.idea.VAR.HttpServer/.idea/encodings.xml b/.idea/.idea.VAR.HttpServer/.idea/encodings.xml
new file mode 100644
index 0000000..df87cf9
--- /dev/null
+++ b/.idea/.idea.VAR.HttpServer/.idea/encodings.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.VAR.HttpServer/.idea/indexLayout.xml b/.idea/.idea.VAR.HttpServer/.idea/indexLayout.xml
new file mode 100644
index 0000000..7b08163
--- /dev/null
+++ b/.idea/.idea.VAR.HttpServer/.idea/indexLayout.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.VAR.HttpServer/.idea/projectSettingsUpdater.xml b/.idea/.idea.VAR.HttpServer/.idea/projectSettingsUpdater.xml
new file mode 100644
index 0000000..4bb9f4d
--- /dev/null
+++ b/.idea/.idea.VAR.HttpServer/.idea/projectSettingsUpdater.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.VAR.HttpServer/.idea/vcs.xml b/.idea/.idea.VAR.HttpServer/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/.idea.VAR.HttpServer/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/VAR.HttpServer.MiniServerTest/Program.cs b/VAR.HttpServer.MiniServerTest/Program.cs
index 03ce54b..139e336 100644
--- a/VAR.HttpServer.MiniServerTest/Program.cs
+++ b/VAR.HttpServer.MiniServerTest/Program.cs
@@ -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();
diff --git a/VAR.HttpServerTests/HttpUtilityTests.cs b/VAR.HttpServer.Tests/HttpUtilityTests.cs
similarity index 100%
rename from VAR.HttpServerTests/HttpUtilityTests.cs
rename to VAR.HttpServer.Tests/HttpUtilityTests.cs
diff --git a/VAR.HttpServerTests/Properties/AssemblyInfo.cs b/VAR.HttpServer.Tests/Properties/AssemblyInfo.cs
similarity index 82%
rename from VAR.HttpServerTests/Properties/AssemblyInfo.cs
rename to VAR.HttpServer.Tests/Properties/AssemblyInfo.cs
index aba9650..6750399 100644
--- a/VAR.HttpServerTests/Properties/AssemblyInfo.cs
+++ b/VAR.HttpServer.Tests/Properties/AssemblyInfo.cs
@@ -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("")]
diff --git a/VAR.HttpServerTests/VAR.HttpServerTests.csproj b/VAR.HttpServer.Tests/VAR.HttpServer.Tests.csproj
similarity index 97%
rename from VAR.HttpServerTests/VAR.HttpServerTests.csproj
rename to VAR.HttpServer.Tests/VAR.HttpServer.Tests.csproj
index 1da4dfe..95c17b3 100644
--- a/VAR.HttpServerTests/VAR.HttpServerTests.csproj
+++ b/VAR.HttpServer.Tests/VAR.HttpServer.Tests.csproj
@@ -6,8 +6,8 @@
{1D73D51B-D094-4775-93A4-A26F8B66C167}
Library
Properties
- VAR.HttpServerTests
- VAR.HttpServerTests
+ VAR.HttpServer.Tests
+ VAR.HttpServer.Tests
v4.6.1
512
{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
diff --git a/VAR.HttpServer.sln b/VAR.HttpServer.sln
index 7e9affa..e1f40ad 100644
--- a/VAR.HttpServer.sln
+++ b/VAR.HttpServer.sln
@@ -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
diff --git a/VAR.HttpServer.sln.DotSettings b/VAR.HttpServer.sln.DotSettings
new file mode 100644
index 0000000..b805caf
--- /dev/null
+++ b/VAR.HttpServer.sln.DotSettings
@@ -0,0 +1,58 @@
+
+ NotRequired
+ True
+ True
+ TOGETHER_SAME_LINE
+ True
+ True
+ False
+ True
+ True
+ True
+ OneStep
+ OneStep
+ True
+ UseVarWhenEvident
+ UseVarWhenEvident
+ AES
+ AM
+ AUX
+ DC
+ DES
+ EPM
+ GDI
+ ID
+ IP
+ RECT
+ RGB
+ SCART
+ SPDIF
+ SQL
+ SRCCOPY
+ TCP
+ URL
+ USB
+ VAR
+ WMIC
+ YRYBY
+ False
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb"><ExtraRule Prefix="T" Suffix="" Style="AaBb_AaBb" /></Policy>
+ <Policy Inspect="True" Prefix="I" Suffix="" Style="AaBb_AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb_AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb_AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" />
+ <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb_AaBb" />
+ <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb_AaBb" />
+ <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb_AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" />
+ True
+ True
+ True
+ True
+
\ No newline at end of file
diff --git a/VAR.HttpServer.sln.DotSettings.user b/VAR.HttpServer.sln.DotSettings.user
new file mode 100644
index 0000000..e9e707c
--- /dev/null
+++ b/VAR.HttpServer.sln.DotSettings.user
@@ -0,0 +1,2 @@
+
+ ShowAndRun
\ No newline at end of file
diff --git a/VAR.HttpServer/HttpProcessor.cs b/VAR.HttpServer/HttpProcessor.cs
index d92b400..a7b7dc5 100644
--- a/VAR.HttpServer/HttpProcessor.cs
+++ b/VAR.HttpServer/HttpProcessor.cs
@@ -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 _logDebugMessage = null;
+ private readonly IHttpHandler _handler;
- private readonly Action _logException = null;
+ public IHttpHandler Handler => _handler;
+
+ // ReSharper disable once NotAccessedField.Local
+ private readonly Action _logDebugMessage;
+
+ private readonly Action _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 _httpHeaders = new Dictionary();
- public Dictionary HttpHeader { get { return _httpHeaders; } }
+ public string HttpProtocolVersionString => _httpProtocolVersionString;
+
+ private readonly Dictionary _httpHeaders = new Dictionary();
+
+ public Dictionary HttpHeader => _httpHeaders;
private string _postString;
- public string PostString { get { return _postString; } }
- private Dictionary _httpParams = new Dictionary();
- public Dictionary HttpParams { get { return _httpParams; } }
+ public string PostString => _postString;
- public bool IsPostback { get { return _httpMethod.ToUpper().Equals("POST"); } }
+ private readonly Dictionary _httpParams = new Dictionary();
- public HttpProcessor(TcpClient s, IHttpHandler handler, Action logDebugMessage, Action logException)
+ public Dictionary HttpParams => _httpParams;
+
+ public bool IsPostback => _httpMethod.ToUpper().Equals("POST");
+
+ public HttpProcessor(TcpClient s, IHttpHandler handler, Action logDebugMessage,
+ Action 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("");
}
@@ -257,4 +281,4 @@ namespace VAR.HttpServer
}
}
}
-}
+}
\ No newline at end of file
diff --git a/VAR.HttpServer/HttpServer.cs b/VAR.HttpServer/HttpServer.cs
index 79eed62..fbdfb15 100644
--- a/VAR.HttpServer/HttpServer.cs
+++ b/VAR.HttpServer/HttpServer.cs
@@ -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 _logDebugMessage = null;
- public Action LogDegugMessage { set { _logDebugMessage = value; } }
- private Action _logException = null;
- public Action LogException { set { _logException = value; } }
+ private Action _logDebugMessage;
+
+ public Action LogDebugMessage
+ {
+ set => _logDebugMessage = value;
+ }
+
+ private Action _logException;
+
+ public Action 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;
}
}
diff --git a/VAR.HttpServer/HttpUtility.cs b/VAR.HttpServer/HttpUtility.cs
index 68ba9fd..269385f 100644
--- a/VAR.HttpServer/HttpUtility.cs
+++ b/VAR.HttpServer/HttpUtility.cs
@@ -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();
- 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,14 +126,17 @@ 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();
}
}
-}
+}
\ No newline at end of file