Skip to content

Releases: sisk-http/core

v1.3

13 Nov 18:49
Compare
Choose a tag to compare

v.1.3

Sisk 1.3 is being released today! This update brings performance improvements, another way to write your favorite APIs, and something similar to dependency injection.

Sisk's commitment remains the same: to be simple to develop a quality HTTP application. Sisk has no dependencies other than the .NET ecosystem itself, and all its code is still less than 1KB in total. Sisk has a minimal footprint, focusing performance on your application's layer, not the server.

We would also like to showcase the new logo of the project. It is more modern while still referencing what the project used to be.

Sisk logo

Performance improvements

Sisk has a limitation: it depends on the current implementation of HttpListener to work. This implementation is great on Windows and has performance comparable to ASP.NET, but in recent tests, we found that the managed implementation of HttpListener lags significantly behind ASP.NET's Kestrel, which happens outside Windows environments. Even so, Sisk still manages to be much more performant and efficient than many other development frameworks in other languages. Our goal is not to be better than ASP.NET, but the closer we get to its performance, the more viable the choice of Sisk becomes for more projects.

In version 1.3, we achieved an average performance increase of 15% overall for request processing. This is because we improved the way the server sends the content of a response to the client. The HttpResponse object depends on HttpContent to define content to send to the client, and previously, this object had to be serialized through HttpContent.ReadAsByteArrayAsync. The problem is that many contents are based on ByteArrayContent, and when calling this method on this type of content, a memory buffer was created, and the response bytes were copied to this buffer. Then, this buffer was copied to the response's output stream.

Thanks to UnsafeAccessor in .NET 8, we can access the response bytes directly, without the need to create this secondary buffer. This greatly improved overall performance.

benchmark

In addition, there were performance improvements outside of the request processor as well. Improvements were made in the way the server writes messages to the access log and deserializes multipart content.

Static HttpContexts

An experimental feature is to expose the current HttpContext of a request in a local context of the execution thread. This allows you to expose members of a request outside the request method, greatly improving the readability of your code. The code snippet below shows an abstract class that functions as an API controller with an embedded database.

public abstract class Controller : RouterModule
{
    public DbContext Database
    {
        // Create or get an new DbContext instance
        get => HttpContext.Current.RequestBag.GetOrAdd(() => new DbContext());
    }

    // Exposing the HttpRequest instance is supported too
    public HttpRequest Request { get => HttpContext.Current.Request; }

    protected override void OnSetup(Router parentRouter)
    {
        base.OnSetup(parentRouter);

        HasRequestHandler(RequestHandler.Create(
            execute: (req, ctx) =>
            {
                // disposes the current DbContext if used
                ctx.RequestBag.GetOrDefault<DbContext>()?.Dispose();
                return null;
            },
            executionMode: RequestHandlerExecutionMode.AfterResponse));
    }
}

And use this implementation with methods that do not have an HttpRequest parameter, as you already have a Request in your controller instance.

[RoutePrefix("/api/posts")]
public class PostsController : Controller
{
    [RouteGet]
    public IEnumerable<Blog> ListPosts()
    {
        return Database.Posts
            .Where(post => post.AuthorId == AuthenticatedUser.Id)
            .ToList();
    }

    [RouteGet("<id>")]
    public Post GetPost()
    {
        int blogId = Request.RouteParameters["id"].GetInteger();

        Post? post = Database.Posts
            .FirstOrDefault(post => post.Id == blogId && post.AuthorId == AuthenticatedUser.Id);

        return post ?? new HttpResponse(404);
    }
}

You can read more about this feature in the documentation.

Full changelog

New features:

  • New logo.
  • Added support for .NET 9.
  • Added the StringKeyStore.SetRange method.
  • Added the TypedValueDictionary.GetOrDefault<T> method.
  • Added the TypedValueDictionary.GetOrAdd<T> method.
  • Added the TypedValueDictionary.GetOrAddAsync<T> method.
  • Added the HttpRequest.Uri property.
  • Added the HttpServerExecutionResult.Elapsed property.
  • Added the HttpContext.Current static property.
  • Added the HttpResponseExtensions.WithHeader(StringKeyStore) method.
  • Added the MimeHelper.DefaultMimeType static property.
  • Added the MimeHelper.IsBrowserKnownInlineMimeType(string) method.
  • Added the HttpServerFlags.PreventResponseContentsInProhibitedMethods flag.
  • Added the Route.Get, Route.Post, Route.Put, Route.Delete, Route.Head, Route.Options, Route.Any and Route.Patch static methods.
  • Added the RouterModule.OnSetup virtual method.
  • Added the CookieHelper static class.

Changes:

  • Improved the path matching algorithm.
  • Improved the log writer algorithm.
  • The HTTP server will now show an warning when it's starting without any route defined.
  • Changed type from Router.Action from RouteAction to Delegate.
  • Changed return type from TypedValueDictionary.Unset from void to bool.
  • Fixed when the HTTP server was starting with one random port and defined ports when using portable configurations.

Fixes:

  • Fixed the TypedValueDictionary.IsSet<T> attribute usage.
  • Fixed an issue where byte counts were being calculated with decimals in SizeHelper.HumanReadableSize.

Breaking changes:

  • Removed the HttpKnownHeaderNames.From member.
  • Removed the HttpRequest.GetQueryValue methods.
  • Removed the HttpServer.GetVersion() method. You can still use the HttpServer.PoweredBy property instead.
  • Route/paths parameters will not be added into HttpRequest.Query anymore. You should use the HttpRequest.RouteParameters property instead.
  • Made CookieHelper and static class and removed it from all classes who used it. You still can use the SetCookie methods from where it was defined.
  • Deprecated the HttpServerConfiguration.DefaultEncoding property.

Thank you for using Sisk!

v1.2

29 Oct 05:12
Compare
Choose a tag to compare

v1.2

This changelog includes changes from v1.0.2 to v1.2.0.

What's Changed

  • Added the StringValue.Create(string) method.
  • Added the HttpResponse(HttpStatusInformation) constructor.
  • Added IEquatable<Route> to Route class.
  • Added IEquatable<MultipartObject> to MultipartObject class.
  • Added notnull for constraint <T> of the ValueResult<T> class.
  • Added the DefaultPageCSS static property to DefaultMessagePage class.
  • Added the CreateBuilder(string) static method to HttpServer class.
  • Added experimental support for listening ports paths instead only listening at the root index.
  • Added the ListeningPort.Path property, plus their constructors.
  • Added the HttpRequest.RouteParameters property. In next Sisk versions, all path/route parameters will be moved to this property instead HttpRequest.Query. For now, the Query property will have the same behavior as before.
  • Added boolean operators for HttpStatusInformation struct.
  • Added the StringKeyStore class.
  • Added the CookieHelper.BuildCookieHeaderValue static method.
  • Added the ConfigurationFileLookupDirectory enum to PortableConfigurationBuilder.WithConfigFile method.
  • Added the HttpContext.ExtraHeaders property.
  • Added the extension method HttpResponse.WithCookie(Cookie) method.
  • Added the HttpServerExecutionResult.Context property.
  • Improved the ListeningPort.Parse method.
  • Improved various CookieHelpers methods syntax signatures.
  • The HttpContext.Router property ins't nullable anymore.
  • The HttpServerConfiguration.AccessLogsStream property nows defaults to LogStream.ConsoleOutput.
  • The HttpRequestException is now sealed.
  • The HttpResponse.Headers property ins't read-only anymore.
  • The HttpServerFlags.EnableNewMultipartFormReader is now enabled by default. If you encounter problems with the Multipart form parser, you can disable it and use the old parser.
  • The Router.GlobalRequestHandlers ins't nullable anymore. And it is an List<IRequestHandler> instead IRequestHandler[] now.
  • The Router.NotFoundErrorHandler and Router.MethodNotAllowedErrorHandler now, by default, returns an HTML response from DefaultMessagePage if the requests accepts text/html. You can disable this behavior by overriding the mentioned properties.
  • The ServerConfiguration.MaximumContentLength property is now Int64 instead Int32.
  • Route matching and conflict catching algorithms improved.
  • Removed string-based route-path algorithms.
  • Fixed an issue regarding how the CertificateUtil class generates hashcodes for DNS names.
  • Fixed various documentation members typos.
  • Fixed an issue where the Expires and Last-Modified headers from HttpContentHeaders objects weren't being sent as universal time, but local time.
  • Fixed more issues related ot the HttpContentHeaders.
  • Fixed an issue where the HttpServer weren't releasing the WaitNext() method on dispose.
  • Fixed an issue related to HttpWebSocket connections not being correctly closed.
  • Fixed Sisk.SslProxy HTTP serializer and deserializer issues.
  • Fixed logic error on StringValueCollectoin.TryGetValue.
  • Fixed multiple issues related to the IniConfigurationReader INI-configuration reader.
  • Fixed numeric errors on SizeHelper constants.

Breaking and deprecating changes:

  • [Breaking] Dropped support for .NET 6 and 7. These versions will be maintained until November 30, 2024, in the legacy 1.0.x branch for severe bugs and critical security issues.
  • [Breaking] Removed the HttpServerHostContextBuilder.UseAutoScan(bool) method. The bool parameter was removed.
  • [Breaking] Removed the HtmlContent.DefaultEncoding static property. It now evaluates to Encoding.Default.
  • [Breaking] Removed the HttpRequest.SetContextBag* and HttpRequest.GetContextBag* methods. You should use the HttpRequest.Bag property instead.
  • [Breaking] Removed the HttpRequest.Close* method. You should use the HttpResponse.Refuse() method instead.
  • [Breaking] Removed the HttpResponse.CreateEmptyResponse method. You should use the empty HttpResponse constructor instead.
  • [Breaking] Removed the HttpResponse.CreateRedirectResponse method.
  • [Breaking] Removed the HttpResponse.StatusInformatoin property. You should use the HttpResponse.Status property instead.
  • [Breaking] The AutoScanModules methods (on Router and HttpServerHostContextBuilder) now automatically set static classes as static members and searches for instance and static methods in instance classes if an public constructor is found.
  • [Breaking] The RouterModule.HasRequestHandler(IRequestHandler) method is now protected. Before was public.
  • [Breaking] Renamed the Sisk.IniConfiguration.IniConfigurationPipeline class name to IniConfigurationReader.
  • [Depreated] the HttpRequest.GetQueryValue and HttpRequest.GetQueryValue<T>(string) methods are now deprecated. You should use the HttpRequest.Query property instead.

v1.1.1

17 Oct 18:50
Compare
Choose a tag to compare

What's Changed

New Contributors

Full Changelog: 1.0.2.0...1.1.1.0

v1.0.2

01 Sep 20:09
Compare
Choose a tag to compare
  • Added the HttpServerHostContextBuilder.UseStartupMessage method.
  • Added the HttpServer.CreateListener() method.
  • Added the WaitTimeout property to HttpWebSocket.
  • Added the HttpWebSocket.WaitNext(TimeSpan) overload method.
  • Made StringValue and StringValueCollection contructors public.
  • Now IRequestHandler can be applied on classes declarations.
  • Breaking: renamed the PortableConfigurationBuilder.WithConfigurationPipeline method to WithConfigReader.
  • Improved the server exception message for ServerConfiguration.ErrorsLogsStream errors.
  • The HttpWebSocket.WithPing is not really fluent and returns the self HttpWebSocket instance as parameter.
  • Deprecate HttpRequest.Close method. You should use the new HttpResponse.Refuse() method instead.
  • Deprecate HttpResponse.CreateEmptyResponse() method.
  • Fixed an issue where exceptions raised on HttpRequestHandler methods ServerStarting, ServerStarted and SetupRouter would be ignored. Eexceptions within these handlers are now thrown.
  • Fixed an deadlock in HttpServerHostContext.Dispose() method. #10

v1.0

22 Aug 00:39
Compare
Choose a tag to compare

This major releases brings stability, performance and API improvements.

Read the full logs for the 1.0 here.

v0.16.2

29 Apr 16:47
Compare
Choose a tag to compare

This minor version of Sisk contains improvements in usability, performance, bug fixes and some new features. See the full changelogs here.

v0.16.1

26 Feb 13:36
Compare
Choose a tag to compare

This release includes the new StringValues, changes and fixes. Read them here.

v0.16

19 Jan 16:50
Compare
Choose a tag to compare

Please, read the full changelogs here.

v0.16-rc-3

07 Dec 20:15
Compare
Choose a tag to compare
  • fixed an issue HttpRequest.GetQueryValue would throw other exceptions besides InvalidCastException.
  • fixed an issue that read streams wasn't positioned at zero before sending again.
  • fixed an issue regarding Router.AutoScan<>

v0.15.3

25 Nov 22:16
Compare
Choose a tag to compare

This update includes an critical bugfix for v.0.15.3 and v.0.16-rc-3:

  • when using ResolveForwardedOriginAddress, the forwarded IP was not the proxy IP.