diff --git a/MTSC-TestServer/Program.cs b/MTSC-TestServer/Program.cs
index ed19a33..63c0be1 100644
--- a/MTSC-TestServer/Program.cs
+++ b/MTSC-TestServer/Program.cs
@@ -28,7 +28,8 @@ namespace MTSC_TestServer
.AddExceptionHandler(new ExceptionConsoleLogger())
//.AddHandler(new BroadcastHandler())
.AddHandler(new WebsocketHandler().AddWebsocketHandler(new BroadcastModule()))
- .AddHandler(new HttpHandler().AddHttpModule(new FileServerModule()))
+ .AddHandler(new HttpHandler().AddHttpModule(new FileServerModule())
+ .AddHttpModule(new PostModule()))
.Run();
}
diff --git a/MTSC/Common/Http/HttpMessage.cs b/MTSC/Common/Http/HttpMessage.cs
index f243d60..19b997c 100644
--- a/MTSC/Common/Http/HttpMessage.cs
+++ b/MTSC/Common/Http/HttpMessage.cs
@@ -486,6 +486,15 @@ namespace MTSC.Common.Http
///
/// Key of the header.
/// True if the message contains a header with the provided key.
+ public bool ContainsHeader(EntityHeadersEnum header)
+ {
+ return ContainsHeader(entityHeaders[(int)header]);
+ }
+ ///
+ /// Check if the message contains a header.
+ ///
+ /// Key of the header.
+ /// True if the message contains a header with the provided key.
public bool ContainsHeader(string header)
{
return headers.ContainsKey(header);
diff --git a/MTSC/Common/Http/ServerModules/PostModule.cs b/MTSC/Common/Http/ServerModules/PostModule.cs
new file mode 100644
index 0000000..ed9615e
--- /dev/null
+++ b/MTSC/Common/Http/ServerModules/PostModule.cs
@@ -0,0 +1,120 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using MTSC.Exceptions;
+using MTSC.Server;
+using MTSC.Server.Handlers;
+
+namespace MTSC.Common.Http.ServerModules
+{
+ public class PostModule : IHttpModule
+ {
+ private static string urlEncodedHeader = "application/x-www-form-urlencoded";
+ private static string multipartHeader = "multipart/form-data";
+
+ public event EventHandler> FormReceived;
+
+ #region Private Methods
+ private Dictionary ParseFormUrlEncoded(HttpMessage request)
+ {
+ if (!request.ContainsHeader(HttpMessage.EntityHeadersEnum.ContentLength))
+ {
+ throw new InvalidPostFormException("Form is missing content-length header!");
+ }
+ else
+ {
+ Dictionary formData = new Dictionary();
+ int length = int.Parse(request[HttpMessage.EntityHeadersEnum.ContentLength]);
+ int step = 0, parsedLength = 0;
+ StringBuilder fieldBuilder = new StringBuilder();
+ StringBuilder valueBuilder = new StringBuilder();
+ /*
+ * Parse request body to obtain the form data.
+ * Example of a form: field1=value1&field2=value2
+ */
+ for (int i = 0; i < request.Body.Length; i++)
+ {
+ if(request.Body[i] == '\n')
+ {
+ continue;
+ }
+ else if(step == 0)
+ {
+ parsedLength++;
+ if(request.Body[i] == '=')
+ {
+ step = 1;
+ }
+ else
+ {
+ fieldBuilder.Append((char)request.Body[i]);
+ }
+ }
+ else
+ {
+ parsedLength++;
+ if(request.Body[i] == '&')
+ {
+ step = 0;
+ formData[fieldBuilder.ToString()] = valueBuilder.ToString();
+ fieldBuilder.Clear();
+ valueBuilder.Clear();
+ }
+ else
+ {
+ valueBuilder.Append((char)request.Body[i]);
+ if(parsedLength == length)
+ {
+ formData[fieldBuilder.ToString()] = valueBuilder.ToString();
+ }
+ }
+ }
+ }
+ return formData;
+ }
+ }
+
+ private Dictionary ParseFormMultipart(HttpMessage request)
+ {
+ throw new NotImplementedException("Multipart form parsing not implemented yet.");
+ }
+ #endregion
+
+ #region Interface Implementation
+ bool IHttpModule.HandleRequest(Server.Server server, HttpHandler handler, ClientData client, HttpMessage request, ref HttpMessage response)
+ {
+ if(request.Method == HttpMessage.MethodEnum.Post &&
+ request.ContainsHeader(HttpMessage.EntityHeadersEnum.ContentType))
+ {
+ if (request[HttpMessage.EntityHeadersEnum.ContentType].Contains(urlEncodedHeader))
+ {
+ Dictionary form = ParseFormUrlEncoded(request);
+ FormReceived?.Invoke(this, form);
+ server.LogDebug("Received POST form of " + form.Keys.Count + " keys!");
+ return true;
+ }
+ else if (request[HttpMessage.EntityHeadersEnum.ContentType].Contains(multipartHeader))
+ {
+ Dictionary form = ParseFormMultipart(request);
+ FormReceived?.Invoke(this, form);
+ server.LogDebug("Received POST form of " + form.Keys.Count + " keys!");
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ void IHttpModule.Tick(Server.Server server, HttpHandler handler)
+ {
+
+ }
+ #endregion
+ }
+}
diff --git a/MTSC/Server/Handlers/HttpHandler.cs b/MTSC/Server/Handlers/HttpHandler.cs
index 11871de..25394b5 100644
--- a/MTSC/Server/Handlers/HttpHandler.cs
+++ b/MTSC/Server/Handlers/HttpHandler.cs
@@ -14,6 +14,8 @@ namespace MTSC.Server.Handlers
///
public class HttpHandler : IHandler
{
+ private static string urlEncodedHeader = "application/x-www-form-urlencoded";
+ private static string multipartHeader = "multipart/form-data";
#region Fields
List httpModules = new List();
ConcurrentQueue> messageQueue = new ConcurrentQueue>();