Skip to content

Commit 2e053dd

Browse files
committed
added json configuration, implemented custom http server directly on bytes
1 parent 6b6abbd commit 2e053dd

File tree

8 files changed

+349
-86
lines changed

8 files changed

+349
-86
lines changed

RelayServerTest/Config.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"PortRelay": 20011,
3+
"PortHttp": 20012,
4+
"UpdateProxy": false,
5+
"ProxyUri": "http://localhost:8001/ip"
6+
}

RelayServerTest/HttpSimpleVisuals.cs renamed to RelayServerTest/HttpSimple/Alternative/HttpNativeServer.cs

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
using System.Text.Json;
1616
using System.Threading.Tasks;
1717

18-
namespace RelayServer
18+
namespace RelayServer.HttpSimple.Alternative
1919
{
20-
internal class HttpSimpleVisuals
20+
internal class HttpNativeServer
2121
{
2222
HttpListener listener = new HttpListener();
2323
private SecureProtoRelayServer? server;
@@ -37,22 +37,23 @@ internal class HttpSimpleVisuals
3737
private ConcurrentDictionary<IPEndPoint, UdpStatistics> udpSessionStats;
3838
private GeneralStats generalStatJsonObject;
3939

40-
public HttpSimpleVisuals(SecureProtoRelayServer s)
40+
private int portHttp;
41+
public HttpNativeServer(SecureProtoRelayServer s, int porthttp)
4142
{
4243
ArgumentNullException.ThrowIfNull(s);
43-
this.server = s;
44+
server = s;
45+
portHttp = porthttp;
4446

45-
4647
}
4748

48-
49+
4950

5051
public void BeginService()
5152
{
5253
//>netsh http add iplisten ipaddress=0.0.0.0:20012
5354
//netsh http add urlacl url=http://*:20012/ user=everyone
54-
listener.Prefixes.Add("http://*:20012/");
55-
listener.Prefixes.Add("http://*:20012/generalstats/");
55+
listener.Prefixes.Add(string.Format("http://*:{0}/", portHttp.ToString()));
56+
listener.Prefixes.Add(string.Format("http://*:{0}/generalstats/", portHttp.ToString()));
5657

5758
listener.Start();
5859

@@ -70,11 +71,13 @@ public void BeginService()
7071
}
7172
else if (req.RawUrl.Equals("/text", StringComparison.OrdinalIgnoreCase))
7273
{
73-
PreparePrettyJsonPageResponse(context);
74+
PrepareTextResponse(context);
75+
7476
}
7577
else
7678
{
77-
PrepareTextResponse(context);
79+
PrepareDynamicTextResponse(context);
80+
7881

7982
}
8083
}
@@ -88,7 +91,7 @@ private void PrepareTextResponse(HttpListenerContext context)
8891
{
8992
using HttpListenerResponse resp = context.Response;
9093
resp.Headers.Set("Content-Type", "text/html");
91-
94+
resp.Headers.Set("Access-Control-Allow-Origin", "*");
9295
Update();
9396

9497
string data =
@@ -118,13 +121,26 @@ private void PrepareJsonResponse(HttpListenerContext context)
118121
using Stream stream = resp2.OutputStream;
119122
stream.Write(buffer_, 0, buffer_.Length);
120123
}
121-
private void PreparePrettyJsonPageResponse(HttpListenerContext context)
124+
private void PrepareDynamicTextResponse(HttpListenerContext context)
125+
{
126+
using HttpListenerResponse resp2 = context.Response;
127+
128+
resp2.Headers.Set("Content-Type", "text/html");
129+
resp2.Headers.Set("Access-Control-Allow-Origin", "*");
130+
byte[] buffer_ = Encoding.UTF8.GetBytes(PageResources.TextVisualizePage);
131+
132+
resp2.ContentLength64 = buffer_.Length;
133+
using Stream stream = resp2.OutputStream;
134+
stream.Write(buffer_, 0, buffer_.Length);
135+
}
136+
137+
private void PrepareAutoTextPageResponse(HttpListenerContext context)
122138
{
123139
using HttpListenerResponse resp2 = context.Response;
124140

125141
resp2.Headers.Set("Content-Type", "text/html");
126142
resp2.Headers.Set("Access-Control-Allow-Origin", "*");
127-
byte[] buffer_ = Encoding.UTF8.GetBytes(Resources.StatisticsPage);
143+
byte[] buffer_ = Encoding.UTF8.GetBytes(PageResources.TextVisualizePage);
128144

129145
resp2.ContentLength64 = buffer_.Length;
130146
using Stream stream = resp2.OutputStream;
@@ -138,8 +154,18 @@ public bool Update()
138154
if ((DateTime.Now - LastUpdate).TotalMilliseconds < 900)
139155
return false;
140156
LastUpdate = DateTime.Now;
141-
server.GetTcpStatistics(out TcpGeneralStats, out tctSessionStats);
142-
server.GetUdpStatistics(out udpGeneralStats, out udpSessionStats);
157+
try
158+
{
159+
server.GetTcpStatistics(out var tcpGeneralStats, out var tcpSessionStats);
160+
server.GetUdpStatistics(out var udpGeneralStats, out var udpSessionStats);
161+
162+
TcpGeneralStats = tcpGeneralStats;
163+
tctSessionStats = tcpSessionStats;
164+
this.udpGeneralStats = udpGeneralStats;
165+
this.udpSessionStats = udpSessionStats;
166+
}
167+
catch (Exception ex) { return false; }
168+
143169
return true;
144170
}
145171

@@ -159,7 +185,7 @@ public string GetGeneralStatistics()
159185
UdpGeneralStats = udpGeneralStats.Stringify()
160186
};
161187
}
162-
188+
163189
return GetJson(generalStatJsonObject);
164190

165191
}
@@ -192,7 +218,7 @@ public string GetSessionStatistics()
192218

193219
private string GetJson<T>(T data) where T : class
194220
{
195-
return JsonSerializer.Serialize<T>(data, new JsonSerializerOptions() { WriteIndented = true });
221+
return JsonSerializer.Serialize(data, new JsonSerializerOptions() { WriteIndented = true });
196222
}
197223

198224
public class StatisticsJson
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Reflection.PortableExecutable;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
8+
namespace RelayServer.HttpSimple
9+
{
10+
internal static class HttpHeaderUtil
11+
{
12+
public const string MainPageHeader = @"HTTP/1.1 200 OK
13+
Content-Length: 777
14+
Content-Type: text/html
15+
Server: Microsoft-HTTPAPI/2.0
16+
Access-Control-Allow-Origin: *
17+
Connection: keep-alive
18+
Date: Fri, 27 Jan 2023 18:06:10 GMT
19+
20+
";
21+
private const string GenericHeader1 = @"HTTP/1.1 200 OK
22+
Content-Length: ";
23+
private const string GenericHeader2 = @"
24+
Content-Type: text/html
25+
Server: Microsoft-HTTPAPI/2.0
26+
Access-Control-Allow-Origin: *
27+
Connection: keep-alive
28+
Date: Fri, 27 Jan 2023 18:06:10 GMT
29+
30+
";
31+
static byte[] GenericHeader1Bytes = Encoding.ASCII.GetBytes(GenericHeader1);
32+
static byte[] GenericHeader2Bytes = Encoding.ASCII.GetBytes(GenericHeader2);
33+
static byte[] contentLenghtBytes= new byte[4];
34+
static byte[] headerBytes;
35+
static HttpHeaderUtil()
36+
{
37+
headerBytes = GenericHeader1Bytes.Concat(contentLenghtBytes).Concat(GenericHeader2Bytes).ToArray();
38+
}
39+
public static byte[] GetASCIIHeader(int contentLenght)
40+
{
41+
var contentLenghtBytes=Encoding.ASCII.GetBytes(contentLenght.ToString());
42+
Buffer.BlockCopy(contentLenghtBytes, 0, headerBytes, 33, contentLenghtBytes.Length);
43+
return GenericHeader1Bytes.Concat(contentLenghtBytes).Concat(GenericHeader2Bytes).ToArray();
44+
}
45+
}
46+
}

RelayServerTest/Resources.cs renamed to RelayServerTest/HttpSimple/PageResources.cs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Drawing;
34
using System.Linq;
5+
using System.Reflection.Metadata;
46
using System.Text;
57
using System.Threading.Tasks;
68

79
namespace RelayServer
810
{
9-
internal class Resources
11+
internal class PageResources
1012
{
1113
public const string StatisticsPage =
1214
@"<!DOCTYPE html>
@@ -45,5 +47,35 @@ function loadJson()
4547
</script>
4648
</html>"
4749
;
50+
public const string TextVisualizePage = @"<!DOCTYPE html>
51+
<html>
52+
<head>
53+
<body>
54+
<body style=""background-color:black;""><font color=""white""></font>
55+
<pre style=""font-size: large; color: white;"" id = ""Display""></pre>
56+
</body>
57+
<script>
58+
let hostname = window.location.hostname;
59+
let url = ""http://""+hostname+"":20012/text"";
60+
function loadJson()
61+
{
62+
var xhttp = new XMLHttpRequest();
63+
xhttp.onreadystatechange = function()
64+
{
65+
if (this.readyState == 4 && this.status == 200)
66+
{
67+
let a = xhttp.responseText;
68+
document.getElementById(""Display"").innerHTML = a;//JSON.stringify(tags,undefined,2)
69+
}
70+
};
71+
xhttp.open(""GET"", url, true);
72+
xhttp.send();
73+
}
74+
loadJson();
75+
var intervalId = window.setInterval(function(){
76+
loadJson()
77+
}, 1000);
78+
</script>
79+
</html>";
4880
}
4981
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
using NetworkLibrary.Components.Statistics;
2+
using NetworkLibrary.TCP.Base;
3+
using NetworkLibrary.Utils;
4+
using Protobuff.P2P;
5+
using System;
6+
using System.Collections.Concurrent;
7+
using System.Collections.Generic;
8+
using System.Diagnostics;
9+
using System.Drawing;
10+
using System.Linq;
11+
using System.Net;
12+
using System.Text;
13+
using System.Threading.Tasks;
14+
using static RelayServer.HttpSimple.Alternative.HttpNativeServer;
15+
16+
namespace RelayServer.HttpSimple
17+
{
18+
internal class SimpleHttpServer
19+
{
20+
private byte[] mainPageBytes;
21+
// this is the one periodically requested by main page.
22+
const string textPagePart1 = "<html><body><body style=\"background-color:black;\"><font color=\"white\"><pre style=\"font-size: large; color: white;\">";
23+
const string textPagePart2 = "</pre><script>setTimeout(function(){ location.reload();},1000);</script></body></html>";
24+
25+
private DateTime LastUpdate = DateTime.Now.AddSeconds(-2);
26+
private TcpStatistics TcpGeneralStats;
27+
private UdpStatistics udpGeneralStats;
28+
private ConcurrentDictionary<Guid, TcpStatistics> tcpSessionStats;
29+
private ConcurrentDictionary<IPEndPoint, UdpStatistics> udpSessionStats;
30+
31+
private SecureProtoRelayServer server;
32+
private AsyncTcpServer httpMiniServer;
33+
private SharerdMemoryStreamPool streamPool = new SharerdMemoryStreamPool();
34+
public SimpleHttpServer(SecureProtoRelayServer s, int porthttp)
35+
{
36+
server = s;
37+
38+
var mainPageHeaderBytes = Encoding.ASCII.GetBytes(HttpHeaderUtil.MainPageHeader);
39+
var mainPageBodybytes = Encoding.UTF8.GetBytes(PageResources.TextVisualizePage);
40+
mainPageBytes = mainPageHeaderBytes.Concat(mainPageBodybytes).ToArray();
41+
42+
httpMiniServer = new AsyncTcpServer(porthttp);
43+
httpMiniServer.GatherConfig = ScatterGatherConfig.UseQueue;
44+
httpMiniServer.MaxIndexedMemoryPerClient = 128000;
45+
httpMiniServer.OnBytesReceived += ServerBytesReceived;
46+
httpMiniServer.StartServer();
47+
}
48+
private void ServerBytesReceived(in Guid guid, byte[] bytes, int offset, int count)
49+
{
50+
try
51+
{
52+
var request = UTF8Encoding.ASCII.GetString(bytes, offset, 10);
53+
var tags = request.Split(' ');
54+
if (tags[1] == "/")
55+
{
56+
httpMiniServer.SendBytesToClient(guid, mainPageBytes);
57+
}
58+
else if (tags[1] == "/text")
59+
{
60+
UpdateStatistics();
61+
string data =
62+
"Session Count: " + tcpSessionStats.Count + "\n" +
63+
"Cpu Usage: " + PerformanceStatistics.GetCpuUsage() + "\n" +
64+
"Memory Usage: " + PerformanceStatistics.GetMemoryUsage() + "\n" +
65+
TcpGeneralStats.ToString() + "\n\n" +
66+
udpGeneralStats.ToString();
67+
68+
string page = textPagePart1 + data + textPagePart2;
69+
byte[] body = Encoding.UTF8.GetBytes(page);
70+
byte[] header = HttpHeaderUtil.GetASCIIHeader(body.Length);
71+
72+
httpMiniServer.SendBytesToClient(in guid, header);
73+
httpMiniServer.SendBytesToClient(in guid, body);
74+
75+
}
76+
} catch { }
77+
78+
}
79+
80+
private void GetTextResponse(Stream stream)
81+
{
82+
UpdateStatistics();
83+
string data =
84+
"Session Count: " + tcpSessionStats.Count + "\n" +
85+
"Cpu Usage: " + PerformanceStatistics.GetCpuUsage() + "\n" +
86+
"Memory Usage: " + PerformanceStatistics.GetMemoryUsage() + "\n" +
87+
TcpGeneralStats.ToString() + "\n\n" +
88+
udpGeneralStats.ToString();
89+
90+
string page = textPagePart1 + data + textPagePart2;
91+
byte[] body = Encoding.UTF8.GetBytes(page);
92+
byte[] header = HttpHeaderUtil.GetASCIIHeader(body.Length);
93+
94+
stream.Position = 0;
95+
stream.Write(header, 0, header.Length);
96+
stream.Write(body, 0, body.Length);
97+
98+
}
99+
100+
public bool UpdateStatistics()
101+
{
102+
if ((DateTime.Now - LastUpdate).TotalMilliseconds < 900)
103+
return false;
104+
LastUpdate = DateTime.Now;
105+
try
106+
{
107+
server.GetTcpStatistics(out var tcpGeneralStats, out var tcpSessionStats);
108+
server.GetUdpStatistics(out var udpGeneralStats, out var udpSessionStats);
109+
110+
TcpGeneralStats = tcpGeneralStats;
111+
this.tcpSessionStats = tcpSessionStats;
112+
this.udpGeneralStats = udpGeneralStats;
113+
this.udpSessionStats = udpSessionStats;
114+
}
115+
catch (Exception ex) { return false; }
116+
117+
return true;
118+
}
119+
}
120+
}

0 commit comments

Comments
 (0)