Skip to content

Commit

Permalink
0.8.9
Browse files Browse the repository at this point in the history
  • Loading branch information
CypherPotato committed Feb 14, 2023
1 parent 4fb661e commit 4b3cb8b
Show file tree
Hide file tree
Showing 13 changed files with 233 additions and 925 deletions.
9 changes: 9 additions & 0 deletions src/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Metadata;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

[assembly: MetadataUpdateHandler(typeof(Sisk.Provider.ServiceReloadManager))]
883 changes: 0 additions & 883 deletions src/Entity/MimeTypeMap.cs

This file was deleted.

46 changes: 32 additions & 14 deletions src/Entity/MultipartObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,43 +139,47 @@ public class MultipartObject
/// <namespace>
/// Sisk.Core.Entity
/// </namespace>
public MultipartObjectImageFormat GetImageFormat()
public MultipartObjectCommonFormat GetCommonFileFormat()
{
IEnumerable<byte> len8 = ContentBytes.Take(8);
IEnumerable<byte> len4 = ContentBytes.Take(4);
IEnumerable<byte> len3 = ContentBytes.Take(3);

if (len8.SequenceEqual(new byte[] { 137, 80, 78, 71, 13, 10, 26, 10 }))
{
return MultipartObjectImageFormat.PNG;
return MultipartObjectCommonFormat.PNG;
}
else if (len4.SequenceEqual(new byte[] { (byte)'R', (byte)'I', (byte)'F', (byte)'F' }))
{
return MultipartObjectCommonFormat.WEBP;
}
else if (len4.SequenceEqual(new byte[] { 0x25, 0x50, 0x44, 0x46 }))
{
return MultipartObjectCommonFormat.PDF;
}
else if (len3.SequenceEqual(new byte[] { 0xFF, 0xD8, 0xFF }))
{
return MultipartObjectImageFormat.JPEG;
return MultipartObjectCommonFormat.JPEG;
}
else if (len3.SequenceEqual(new byte[] { 73, 73, 42 }))
{
return MultipartObjectImageFormat.TIFF;
return MultipartObjectCommonFormat.TIFF;
}
else if (len3.SequenceEqual(new byte[] { 77, 77, 42 }))
{
return MultipartObjectImageFormat.TIFF;
return MultipartObjectCommonFormat.TIFF;
}
else if (len3.SequenceEqual(new byte[] { 0x42, 0x4D }))
{
return MultipartObjectImageFormat.BMP;
return MultipartObjectCommonFormat.BMP;
}
else if (len3.SequenceEqual(new byte[] { 0x47, 0x46, 0x49 }))
{
return MultipartObjectImageFormat.GIF;
}
else if (len4.SequenceEqual(new byte[] { (byte)'R', (byte)'I', (byte)'F', (byte)'F' }))
{
return MultipartObjectImageFormat.WEBP;
return MultipartObjectCommonFormat.GIF;
}
else
{
return MultipartObjectImageFormat.Unknown;
return MultipartObjectCommonFormat.Unknown;
}
}

Expand Down Expand Up @@ -367,7 +371,7 @@ bool Equals(byte[] source, byte[] separator, int index)
/// <namespace>
/// Sisk.Core.Entity
/// </namespace>
public enum MultipartObjectImageFormat
public enum MultipartObjectCommonFormat
{
/// <summary>
/// Represents that the object is not a recognized image.
Expand Down Expand Up @@ -465,6 +469,20 @@ public enum MultipartObjectImageFormat
/// <namespace>
/// Sisk.Core.Entity
/// </namespace>
WEBP = 105
WEBP = 105,

/// <summary>
/// Represents an PDF file.
/// </summary>
/// <definition>
/// PDF = 200
/// </definition>
/// <type>
/// Enum Value
/// </type>
/// <namespace>
/// Sisk.Core.Entity
/// </namespace>
PDF = 200
}
}
21 changes: 20 additions & 1 deletion src/Http/HttpRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -555,10 +555,29 @@ public string GetRawHttpRequest(bool includeBody = true)
/// <namespace>
/// Sisk.Core.Http
/// </namespace>
[Obsolete("This method is now obsolete. Use CreateEmptyResponse() instead.")]
public HttpResponse CreateHeadResponse()
{
return CreateEmptyResponse();
}

/// <summary>
/// Create an HTTP response with code 204 No Content without any body.
/// </summary>
/// <returns></returns>
/// <definition>
/// public HttpResponse CreateEmptyResponse()
/// </definition>
/// <type>
/// Method
/// </type>
/// <namespace>
/// Sisk.Core.Http
/// </namespace>
public HttpResponse CreateEmptyResponse()
{
HttpResponse res = new HttpResponse();
res.Status = System.Net.HttpStatusCode.OK;
res.Status = System.Net.HttpStatusCode.NoContent;
return res;
}

Expand Down
2 changes: 1 addition & 1 deletion src/Http/HttpRequestEventSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ internal HttpRequestEventSource(HttpListenerResponse res, HttpListenerRequest re
res.AddHeader("Cache-Control", "no-store");
res.AddHeader("Content-Type", "text/event-stream");
res.AddHeader("X-Powered-By", HttpServer.poweredByHeader);
HttpServer.SetCorsHeaders(host.hostContext.CrossOriginResourceSharingPolicy, res);
HttpServer.SetCorsHeaders(host.hostContext.CrossOriginResourceSharingPolicy, res, httpServerConfiguration.Flags);
}

/// <summary>
Expand Down
27 changes: 19 additions & 8 deletions src/Http/HttpServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -232,8 +232,9 @@ private void TryCloseStream(HttpListenerResponse response)
}
}

internal static void SetCorsHeaders(CrossOriginResourceSharingHeaders cors, HttpListenerResponse baseResponse)
internal static void SetCorsHeaders(CrossOriginResourceSharingHeaders cors, HttpListenerResponse baseResponse, HttpServerFlags flag)
{
if (!flag.SendCorsHeaders) return;
if (cors.AllowHeaders.Length > 0) baseResponse.Headers.Set("Access-Control-Allow-Headers", string.Join(", ", cors.AllowHeaders));
if (cors.AllowMethods.Length > 0) baseResponse.Headers.Set("Access-Control-Allow-Methods", string.Join(", ", cors.AllowMethods));
if (cors.AllowOrigins.Length > 0) baseResponse.Headers.Set("Access-Control-Allow-Origin", string.Join(", ", cors.AllowOrigins));
Expand Down Expand Up @@ -261,6 +262,7 @@ private void ListenerCallback(IAsyncResult result)
return;
}

HttpServerFlags flag = ServerConfiguration.Flags;
Stopwatch sw = new Stopwatch();
HttpListenerResponse baseResponse = context.Response;
HttpListenerRequest baseRequest = context.Request;
Expand Down Expand Up @@ -312,6 +314,11 @@ private void ListenerCallback(IAsyncResult result)
request = new HttpRequest(baseRequest, baseResponse, this.ServerConfiguration, matchedListeningHost);
}

if (ServerConfiguration.ResolveForwardedOriginAddress)
{
verbosePrefix = $"{DateTime.Now:g} %%STATUS%% {request.Origin.ToString().TrimEnd('\0')} ({baseRequest.Url?.Scheme} {baseRequest.Url!.Authority}) {baseRequest.HttpMethod.ToUpper()} {baseRequest.Url?.AbsolutePath ?? "/"}";
}

if (matchedListeningHost.Router == null || !matchedListeningHost.CanListen)
{
baseResponse.StatusCode = 503; // Service Unavailable
Expand All @@ -321,7 +328,7 @@ private void ListenerCallback(IAsyncResult result)

if (ServerConfiguration.IncludeRequestIdHeader)
{
baseResponse.Headers.Set("X-Request-Id", request.RequestId.ToString());
baseResponse.Headers.Set(flag.HeaderNameRequestId, request.RequestId.ToString());
}

if (OnConnectionOpen != null)
Expand All @@ -340,14 +347,14 @@ private void ListenerCallback(IAsyncResult result)
incomingSize += request.CalcRequestSize();

// check for illegal body content requests
if ((
if (flag.ThrowContentOnNonSemanticMethods && (
request.Method == HttpMethod.Get
|| request.Method == HttpMethod.Options
|| request.Method == HttpMethod.Head
|| request.Method == HttpMethod.Trace
) && context.Request.ContentLength64 > 0)
{
executionResult.Status = HttpServerExecutionStatus.ContentServedOnNotSupportedMethod;
executionResult.Status = HttpServerExecutionStatus.ContentServedOnIllegalMethod;
baseResponse.StatusCode = 400;
return;
}
Expand All @@ -364,7 +371,7 @@ private void ListenerCallback(IAsyncResult result)
&& response?.internalStatus != HttpResponse.HTTPRESPONSE_EVENTSOURCE_CLOSE)
{
var cors = matchedListeningHost.CrossOriginResourceSharingPolicy;
SetCorsHeaders(cors, baseResponse);
SetCorsHeaders(cors, baseResponse, flag);
}

if (response is null)
Expand Down Expand Up @@ -400,12 +407,13 @@ private void ListenerCallback(IAsyncResult result)
{
response.Headers
};

foreach (string incameHeader in resHeaders)
{
baseResponse.AddHeader(incameHeader, resHeaders[incameHeader] ?? "");
}

if (responseBytes.Length > 0 && context.Request.HttpMethod != "HEAD")
if (responseBytes.Length > 0)
{
baseResponse.ContentType = resHeaders["Content-Type"] ?? response.Content!.Headers.ContentType!.MediaType ?? "text/plain";

Expand All @@ -419,8 +427,11 @@ private void ListenerCallback(IAsyncResult result)
}

baseResponse.ContentLength64 = responseBytes.Length;
baseResponse.OutputStream.Write(responseBytes);
outcomingSize += responseBytes.Length;
if (context.Request.HttpMethod != "HEAD")
{
baseResponse.OutputStream.Write(responseBytes);
outcomingSize += responseBytes.Length;
}
}

outcomingSize += response.CalcHeadersSize();
Expand Down
5 changes: 5 additions & 0 deletions src/Http/HttpServerConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ namespace Sisk.Core.Http
/// </namespace>
public class HttpServerConfiguration : IDisposable
{
/// <summary>
/// Gets or sets advanced flags and configuration settings for the HTTP server.
/// </summary>
public HttpServerFlags Flags { get; set; } = new HttpServerFlags();

/// <summary>
/// Gets or sets the <see cref="TextWriter"/> object which the HTTP server will write HTTP server access messages to.
/// </summary>
Expand Down
11 changes: 9 additions & 2 deletions src/Http/HttpServerExecutionResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,16 @@ public enum HttpServerExecutionStatus
Executed,

/// <summary>
/// Represents that the request sent an request body, but it's method does not allow sending of contents.
/// Represents that the request has sent an request body with an with a HTTP method that is not indicated for
/// receiving request contents.
/// </summary>
ContentServedOnNotSupportedMethod,
ContentServedOnIllegalMethod,

/// <summary>
/// This enum is deprecated. Use <see cref="ContentServedOnIllegalMethod"/> instead.
/// </summary>
[Obsolete]
ContentServedOnNotSupportedMethod = ContentServedOnIllegalMethod,

/// <summary>
/// Represents that the content of the request is too large than what was configured on the server.
Expand Down
34 changes: 34 additions & 0 deletions src/Http/HttpServerFlags.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Sisk.Core.Http
{
/// <summary>
/// Provides advanced fields for Sisk server behavior.
/// </summary>
public class HttpServerFlags
{
/// <summary>
/// Determines if the HTTP server should drop requests which has content body in GET, OPTIONS, HEAD and TRACE methods.
/// </summary>
public bool ThrowContentOnNonSemanticMethods = true;

/// <summary>
/// Determines the HTTP header name of the request ID.
/// </summary>
public string HeaderNameRequestId = "X-Request-Id";

/// <summary>
/// Determines if the HTTP server automatically should send CORS headers if set.
/// </summary>
public bool SendCorsHeaders = true;

/// <summary>
/// Determines if the HTTP server should automatically send HTTP headers of an pre-processed GET response if the request is using HEAD method.
/// </summary>
public bool TreatHeadAsGetMethod = true;
}
}
17 changes: 12 additions & 5 deletions src/Provider/ConfigParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public override void WriteJson(JsonWriter writer, object? value, JsonSerializer
}
}

public static void ParseConfiguration(ServiceProvider provider)
public static void ParseConfiguration(ServiceProvider provider, bool startServer)
{
string filePath = Path.GetFullPath(provider.ConfigurationFile);
if (!File.Exists(filePath))
Expand Down Expand Up @@ -62,7 +62,9 @@ public static void ParseConfiguration(ServiceProvider provider)
return;
}

provider.ServerConfiguration = new HttpServerConfiguration();
if (provider.ServerConfiguration is null)
provider.ServerConfiguration = new HttpServerConfiguration();

JToken? serverToken = jsonFile["Server"];
if (serverToken != null)
{
Expand Down Expand Up @@ -244,11 +246,16 @@ public static void ParseConfiguration(ServiceProvider provider)
listeningHost.CrossOriginResourceSharingPolicy = corsPolicy ?? new CrossOriginResourceSharingHeaders();

provider.ServerConfiguration.ListeningHosts.Add(listeningHost);
provider.HttpServer = new HttpServer(provider.ServerConfiguration);
provider.HttpServer.Start();

if (startServer)
{
provider.HttpServer = new HttpServer(provider.ServerConfiguration);
provider.HttpServer.Start();
}

provider.Initialized = true;

if (provider.Verbose)
if (provider.Verbose && startServer)
{
foreach (ListeningPort port in ports)
{
Expand Down
Loading

0 comments on commit 4b3cb8b

Please sign in to comment.