├── .github
├── ISSUE_TEMPLATE
│ ├── 🆘-help-wanted.md
│ ├── 💡-new-idea.md
│ ├── 🛠️-api-proposal.md
│ └── 🪲-bug-report.md
├── Icon-HQ.png
├── Icon.png
├── cadente-ico.png
└── workflows
│ └── codeql.yml
├── .gitignore
├── .nuget
├── README.html
└── README.md
├── CONTRIBUTING.md
├── LICENSE.txt
├── README.md
├── cadente
├── README.md
└── Sisk.Cadente
│ ├── .editorconfig
│ ├── HttpConnection.cs
│ ├── HttpConnectionState.cs
│ ├── HttpEventStreamWriter.cs
│ ├── HttpHeader.cs
│ ├── HttpHeaderExtensions.cs
│ ├── HttpHeaderName.cs
│ ├── HttpHost.cs
│ ├── HttpHostClient.cs
│ ├── HttpHostContext.cs
│ ├── HttpHostHandler.cs
│ ├── HttpHostTimeoutManager.cs
│ ├── HttpSerializer
│ ├── HttpRequestBase.cs
│ ├── HttpRequestReader.cs
│ └── HttpResponseSerializer.cs
│ ├── HttpsOptions.cs
│ ├── Logger.cs
│ ├── Sisk.Cadente.csproj
│ ├── SpanReader.cs
│ ├── Streams
│ ├── HttpChunkedStream.cs
│ └── HttpRequestStream.cs
│ └── TransferEncoding.cs
├── extensions
├── Sisk.BasicAuth
│ ├── .editorconfig
│ ├── BasicAuthenticateRequestHandler.cs
│ ├── BasicAuthenticationCredentials.cs
│ └── Sisk.BasicAuth.csproj
├── Sisk.Documenting.Html
│ ├── .editorconfig
│ ├── HtmlDocumentationExporter.cs
│ ├── Sisk.Documenting.Html.csproj
│ └── Style.cs
├── Sisk.Documenting
│ ├── .editorconfig
│ ├── Annotations
│ │ ├── ApiEndpointAttribute.cs
│ │ ├── ApiHeaderAttribute.cs
│ │ ├── ApiParameterAttribute.cs
│ │ ├── ApiParametersFromAttribute.cs
│ │ ├── ApiPathParameterAttribute.cs
│ │ ├── ApiRequestAttribute.cs
│ │ └── ApiResponseAttribute.cs
│ ├── ApiDocumentation.cs
│ ├── ApiDocumentationReader.cs
│ ├── ApiGenerationContext.cs
│ ├── BodyExampleResult.cs
│ ├── IApiDocumentationExporter.cs
│ ├── IExampleBodyTypeHandler.cs
│ ├── IExampleParameterTypeHandler.cs
│ ├── JsonExampleTypeHandler.cs
│ ├── ParameterExampleResult.cs
│ └── Sisk.Documenting.csproj
├── Sisk.Helpers.mitmproxy
│ ├── .editorconfig
│ ├── MitmproxyHelper.cs
│ ├── MitmproxyProvider.cs
│ └── Sisk.Helpers.mitmproxy.csproj
├── Sisk.IniConfiguration.Core
│ ├── .editorconfig
│ ├── IniDocument.cs
│ ├── IniSection.cs
│ ├── IniSectionCollection.cs
│ ├── Serialization
│ │ ├── IniReader.cs
│ │ ├── IniWriter.cs
│ │ └── Token.cs
│ └── Sisk.IniConfiguration.Core.csproj
├── Sisk.IniConfiguration
│ ├── .editorconfig
│ ├── IniConfigurationReader.cs
│ ├── README.md
│ └── Sisk.IniConfiguration.csproj
├── Sisk.JsonRPC
│ ├── .editorconfig
│ ├── Annotations
│ │ ├── MethodDescriptionAttribute.cs
│ │ ├── ParamDescriptionAttribute.cs
│ │ ├── WebMethodAttribute.cs
│ │ └── WebNameAttribute.cs
│ ├── Converters
│ │ ├── JsonRpcErrorConverter.cs
│ │ ├── JsonRpcRequestConverter.cs
│ │ └── JsonRpcResponseConverter.cs
│ ├── Documentation
│ │ ├── DocumentationDescriptor.cs
│ │ ├── IJsonRpcDocumentationExporter.cs
│ │ ├── JsonRpcDocumentation.cs
│ │ ├── JsonRpcHtmlExport.cs
│ │ └── JsonRpcJsonExport.cs
│ ├── JsonErrorCode.cs
│ ├── JsonRpcError.cs
│ ├── JsonRpcException.cs
│ ├── JsonRpcHandler.cs
│ ├── JsonRpcMethodCollection.cs
│ ├── JsonRpcRequest.cs
│ ├── JsonRpcResponse.cs
│ ├── JsonRpcServerHandler.cs
│ ├── JsonRpcServerHandlerExtensions.cs
│ ├── JsonRpcTransportLayer.cs
│ ├── MethodScanner.cs
│ ├── RpcDelegate.cs
│ └── Sisk.JsonRPC.csproj
├── Sisk.ServiceProvider
│ ├── .editorconfig
│ ├── Provider
│ │ ├── ConfigParser.cs
│ │ ├── RotatingLogPolicy.cs
│ │ ├── ServiceProvider.cs
│ │ └── ServiceProviderConfigurator.cs
│ ├── RequestHandlerFactory.cs
│ ├── RouterFactory.cs
│ └── Sisk.ServiceProvider.csproj
└── Sisk.SslProxy
│ ├── .editorconfig
│ ├── CertificateUtil.cs
│ ├── DnsUtil.cs
│ ├── ProxyGateway.cs
│ ├── SerializerUtils.cs
│ ├── Sisk.SslProxy.csproj
│ ├── SslProxy.cs
│ ├── SslProxyContextHandler.cs
│ ├── SslProxyExtensions.cs
│ └── SslProxyServerHandler.cs
├── src
├── .editorconfig
├── Entity
│ ├── CircularBuffer.cs
│ ├── CrossOriginResourceSharingHeaders.cs
│ ├── HttpHeaderCollection.cs
│ ├── MultipartFormCollection.cs
│ ├── MultipartFormReader.cs
│ ├── MultipartObject.cs
│ ├── MultipartObjectCommonFormat.cs
│ ├── MultipartObjectCommonFormatByteMark.cs
│ ├── StringKeyStoreCollection.cs
│ ├── StringValue.cs
│ ├── StringValueCollection.cs
│ └── TypedValueDictionary.cs
├── GlobalSuppressions.cs
├── Helpers
│ ├── CookieHelper.cs
│ ├── HeaderHelper.cs
│ ├── MimeHelper.cs
│ ├── PathHelper.cs
│ └── SizeHelper.cs
├── Http
│ ├── BrotliContent.cs
│ ├── CompressedContent.cs
│ ├── DefaultMessagePage.cs
│ ├── DeflateContent.cs
│ ├── ForwardingResolver.cs
│ ├── GZipContent.cs
│ ├── Handlers
│ │ ├── AsyncHttpServerHandler.cs
│ │ ├── DefaultHttpServerHandler.cs
│ │ ├── HttpServerHandler.cs
│ │ └── HttpServerHandlerRepository.cs
│ ├── Hosting
│ │ ├── ConfigurationContext.cs
│ │ ├── ConfigurationFileLookupDirectory.cs
│ │ ├── HttpServerHostContext.cs
│ │ ├── HttpServerHostContextBuilder.cs
│ │ ├── HttpServerHostContextBuilderExceptionMode.cs
│ │ ├── IConfigurationReader.cs
│ │ ├── InitializationParameterCollection.cs
│ │ └── PortableConfigurationBuilder.cs
│ ├── HtmlContent.cs
│ ├── HttpContext.cs
│ ├── HttpKnownHeaderNames.cs
│ ├── HttpRequest.cs
│ ├── HttpResponse.cs
│ ├── HttpResponseExtensions.cs
│ ├── HttpServer.Core.cs
│ ├── HttpServer.cs
│ ├── HttpServerConfiguration.cs
│ ├── HttpServerExecutionResult.cs
│ ├── HttpStatusInformation.cs
│ ├── ListeningHost.cs
│ ├── ListeningHostRepository.cs
│ ├── ListeningPort.cs
│ ├── LogStream.cs
│ ├── PrefixedLogStream.cs
│ ├── RotatingLogPolicy.cs
│ └── Streams
│ │ ├── HttpEventSourceCollection.cs
│ │ ├── HttpRequestEventSource.cs
│ │ ├── HttpResponseStreamManager.cs
│ │ ├── HttpStreamPingPolicy.cs
│ │ ├── HttpWebSocket.cs
│ │ └── HttpWebSocketConnectionCollection.cs
├── Internal
│ ├── ByteArrayAccessors.cs
│ ├── DiagnosticId.cs
│ ├── HttpStatusDescription.cs
│ ├── HttpStringInternals.cs
│ ├── LogFormatter.cs
│ ├── MimeTypeList.cs
│ ├── PathUtility.cs
│ ├── PlainTextFileExtensions.cs
│ ├── PlainTextFileMimeTypes.cs
│ ├── SR.cs
│ ├── ServiceProvider
│ │ └── JsonConfigParser.cs
│ ├── SharedChars.cs
│ ├── SpanHelpers.cs
│ └── StringExtensions.cs
├── Routing
│ ├── AsyncRequestHandler.cs
│ ├── IRequestHandler.cs
│ ├── RegexRoute.cs
│ ├── RequestCallback.cs
│ ├── RequestHandledAttribute.cs
│ ├── RequestHandler.cs
│ ├── Route.cs
│ ├── RouteAttribute.cs
│ ├── RouteMatch.cs
│ ├── RouteMethod.cs
│ ├── RoutePrefixAttribute.cs
│ ├── Router.Helpers.cs
│ ├── Router.Invoker.cs
│ ├── Router.SetRoute.cs
│ ├── Router.cs
│ ├── RouterModule.cs
│ └── ValueResult.cs
└── Sisk.Core.csproj
└── tests
├── MSTestSettings.cs
├── Server.cs
├── Tests
└── HttpResponseTests.cs
└── tests.csproj
/.github/ISSUE_TEMPLATE/🆘-help-wanted.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "\U0001F198 Help wanted"
3 | about: Questions about the public API, behavior or general specification of the Sisk
4 | ecosystem.
5 | title: ''
6 | labels: help wanted
7 | assignees: ''
8 |
9 | ---
10 |
11 | > Please, before asking your question, keep in mind to ask an example
12 | >
13 | > - **minimum:** provide the minimum details for us to understand your problem or question.
14 | > - **complete:** please provide all relevant details to reproduce the issue or for us to understand your issue.
15 | > - **reproducible:** an issue or problem that we can reproduce in our environment to better understand your issue.
16 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/💡-new-idea.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "\U0001F4A1 New idea"
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: enhancement
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **How do you think this idea would be useful for the whole community that will use Sisk in the future and not just for you?**
20 | A clear answer on how this idea can help future users with Sisk and not just you.
21 |
22 | **Additional context**
23 | Add any other context or screenshots about the feature request here.
24 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/🛠️-api-proposal.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "\U0001F6E0️ API proposal"
3 | about: Propose a change/addition or fix to the public API interface
4 | title: ''
5 | labels: enhancement
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Which API members are affected by this request? Include their full name, assembly and parameter types names, if applyable:**
11 | *I want to change the `Sisk.Core.HttpServer.Emit(int, @config, @host, @router)`, because I think this method API design is ugly.*
12 |
13 | **How do you think it would be better?**
14 | *I think it should be made clear that this method shouldn't be used in production, specifying it on it's summary or public docs.*
15 |
16 | **What motivated you to think that?**
17 | *I've seen some colleagues use this method for an application in production.*
18 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/🪲-bug-report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "\U0001FAB2 Bug report"
3 | about: Report unexpected behaviors with Sisk Framework and packages
4 | title: ''
5 | labels: bug
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Which Sisk package is this bug related?**
11 | - Sisk.Core
12 | - Sisk.ServiceProviders
13 | - Sisk.BasicAuth
14 | - All
15 |
16 | **Describe the bug**
17 | A clear and concise description of what the bug is.
18 |
19 | **To Reproduce**
20 | An example of code or process to reproduce the problem, which we can also reproduce.
21 |
22 | **Expected behavior**
23 | What was supposed to happen and isn't happening?
24 |
25 | **Desktop (please complete the following information):**
26 | - OS: [e.g. Windows 11 Pro, build 22621]
27 | - .NET and language version [e.g. .NET 8 with C# 12]
28 | - Tested http client [e.g. Chrome, Firefox, Postman, Telnet]
29 | - Package version [e.g. 0.14, 0.15.0.46, etc]
30 |
31 | **Additional context**
32 | Add any other context about the problem here.
33 |
--------------------------------------------------------------------------------
/.github/Icon-HQ.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sisk-http/core/622794480cc1699a73281d725db258d6408275f0/.github/Icon-HQ.png
--------------------------------------------------------------------------------
/.github/Icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sisk-http/core/622794480cc1699a73281d725db258d6408275f0/.github/Icon.png
--------------------------------------------------------------------------------
/.github/cadente-ico.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sisk-http/core/622794480cc1699a73281d725db258d6408275f0/.github/cadente-ico.png
--------------------------------------------------------------------------------
/.nuget/README.html:
--------------------------------------------------------------------------------
1 |
Sisk is a web development framework that is lightweight, agnostic, easy, simple, and robust. The perfect choice for your next project.
2 |
8 | Documentation
9 | You can get started with Sisk here or build the documentation repository here .
10 | For information about release notes, changelogs and API breaking changes, see docs/Changelog.md .
11 | The Sisk core idea is to create a service that runs on the internet and follows the pattern you define. Moreover, Sisk is a framework that adapts to how you want it to work, not the other way around.
12 | Due to its explicit nature, its behavior is predictable. The main differentiator from ASP.NET is that Sisk can be up and running in very few lines of code, avoiding unnecessary configurations, and requiring the minimum setup to get your server working. Additionally, it does not demand any additional .NET SDK packages to develop, as the base package of .NET 6 is sufficient to start your development with Sisk.
13 | It can handle multiple requests asynchronously, provides useful tools to manage and accelerate web development.
14 | using Sisk.Core.Http;
15 | using Sisk.Core.Routing;
16 |
17 | namespace myProgram ;
18 |
19 | class Program
20 | {
21 | static void Main (string [] args )
22 | {
23 | var app = HttpServer.CreateBuilder();
24 |
25 | app.Router += new Route(RouteMethod.Get, "/" , request =>
26 | {
27 | return new HttpResponse(200 )
28 | .WithContent("Hello, world!" );
29 | });
30 |
31 | app.Start();
32 | }
33 | }
34 |
35 | Main features
36 | Sisk can do web development the way you want. Create MVC, MVVC, SOLID applications, or any other design pattern you're interested in.
37 |
38 | Lightweight: robust projects tested in small, low-cost, low-performance environments and got good results.
39 | Open-source: the entire Sisk ecosystem is open source, and all the libraries and technologies we use must be open source as well. Sisk is entirely distributed under the MIT License, which allows the commercial development.
40 | Sustainable: you are the one who makes the project, Sisk gives you the tools. Because it is open source, the community (including you) can maintain, fix bugs and improve Sisk over time.
41 |
42 | Read More
43 | Read more about Sisk at it's repository or website .
44 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to Sisk
2 |
3 | Welcome and thank you for your interest in contributing to Sisk!
4 |
5 | There are many ways in which you can contribute to Sisk, including:
6 |
7 | ### Reporting Bugs
8 |
9 | You can report any bugs in the [Github Issues](https://github.com/sisk-http/core/issues) page. Please, fill out all requested fields in the issue template to give the maximum of information to the developer. This will help the developer to reproduce the bug and fix it faster.
10 |
11 | ### Writing code
12 |
13 | // TODO
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024-present PROJECT PRINCIPIUM and Sisk Contributors
4 | Copyright (c) 2022-2024 PROJECT PRINCIPIUM
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
--------------------------------------------------------------------------------
/cadente/README.md:
--------------------------------------------------------------------------------
1 | # Cadente - The Sisk managed HTTP listener
2 |
3 | This folder contains the code for the implementation of the Sisk HTTP/1.1 listener, called Project Cadente. It is a managed alternative to the [HttpListener](https://learn.microsoft.com/en-us/dotnet/api/system.net.httplistener?view=net-9.0) of .NET. This implementation exists because:
4 |
5 | - We do not know how long Microsoft will want to maintain HttpListener as a component of .NET.
6 | - They don't want to detach Kestrel from ASP.NET.
7 | - It is not possible to use HttpListener with SSL natively, only with a reverse proxy or with IIS on Windows.
8 | - The implementation of HttpListener outside of Windows is slow, but stable. This implementation is an attempt to create something more performant, closer or better than Kestrel speeds.
9 |
10 | ## How to use
11 |
12 | For now, this implementation does not even have a package or is used in Sisk.HttpServer, but it can be used with:
13 |
14 | ```csharp
15 | static void Main ( string [] args ) {
16 | using CadenteHttpListener host = new CadenteHttpListener ( 5555, HandleSession );
17 |
18 | // optional properties to run SSL
19 | host.HttpsOptions = new HttpsOptions ( CertificateUtil.CreateTrustedDevelopmentCertificate () );
20 |
21 | Console.WriteLine ( "server running at : http://localhost:5555/" );
22 |
23 | host.Start ();
24 | Thread.Sleep ( -1 );
25 | }
26 |
27 | public static void HandleSession ( HttpSession session ) {
28 | // handle the request here
29 | }
30 | ```
31 |
32 | ## Implementation status
33 |
34 | This package is expected to supersede Sisk.SslProxy and deprecate it.
35 |
36 | The current status of the implementation is:
37 |
38 | | Resource | Status | Notes |
39 | | ------- | ------ | ----------- |
40 | | Base HTTP/1.1 Reader | OK - Needs testing | |
41 | | HTTPS | OK - Needs testing | |
42 | | Chunked transfer-encoding | OK - Needs testing | Only for responses. |
43 | | SSE/Response content streaming | OK - Needs testing | |
44 | | Gzip transfer encoding | Not implemented | Implement for both request and response. |
45 | | Deflate transfer encoding | Not implemented | Implement for both request and response. |
46 | | Brotli transfer encoding | Not implemented | Implement for both request and response. |
47 | | Handle Expect-100 | Not implemented | There is already an implementation in Sisk.SslProxy. |
48 | | Web Sockets | Not implemented | |
49 | | Trailer headers | - | Will not be implemented. |
50 | | Pipelining | - | May be implemented later. |
51 |
52 | Everything in this project is still super experimental and should never be used in production.
53 |
54 | ## Why not HTTP/2 or QUIC?
55 |
56 | Because they're hard to implement. And because HTTP/1.1 is still capable of doing everything they do, most applications and clients don't need all the features they have. Overall, the HTTP protocol itself is awful, a mess, just like the entire web infrastructure, but it is the most used and capable internet transport we have today (for application-level protocols, not network protocols).
57 |
58 | The truth is that HTTP/2 and QUIC are solutions to problems invented by their creators. But, if you disagree with me, you still can use Sisk with [HTTP/2 or QUIC](https://learn.microsoft.com/en-us/iis/manage/configuring-security/how-to-set-up-ssl-on-iis) in Windows.
59 |
60 | ## License
61 |
62 | The same as the Sisk project (MIT).
--------------------------------------------------------------------------------
/cadente/Sisk.Cadente/HttpConnectionState.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: HttpConnectionState.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.Cadente;
11 |
12 | internal enum HttpConnectionState {
13 | ConnectionClosed = 0,
14 | ConnectionClosedByStreamRead = 1,
15 |
16 | UnhandledException = 10,
17 |
18 | BadRequest = 20,
19 |
20 | ResponseWriteException = 30,
21 | }
22 |
23 | internal enum HttpRequestReadState {
24 | RequestRead = 0,
25 | StreamZero = 1,
26 | StreamError = 2
27 | }
--------------------------------------------------------------------------------
/cadente/Sisk.Cadente/HttpEventStreamWriter.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: HttpEventStreamWriter.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Text;
11 |
12 | namespace Sisk.Cadente;
13 |
14 | ///
15 | /// Provides methods to write data and events to an underlying stream in the Server-Sent Events (SSE) format.
16 | ///
17 | public sealed class HttpEventStreamWriter {
18 | private Stream _innerStream;
19 | private Encoding _messageEncoding;
20 |
21 | internal HttpEventStreamWriter ( Stream innerStream, Encoding encoding ) {
22 | _innerStream = innerStream;
23 | _messageEncoding = encoding;
24 | }
25 |
26 | ///
27 | /// Asynchronously writes a data message to the underlying stream.
28 | ///
29 | /// The data to write.
30 | /// A task that represents the asynchronous write operation.
31 | public async Task WriteDataAsync ( string data ) {
32 | byte [] payload = _messageEncoding.GetBytes ( $"data: {data}\n\n" );
33 | await _innerStream.WriteAsync ( payload );
34 | }
35 |
36 | ///
37 | /// Asynchronously writes an event message to the underlying stream.
38 | ///
39 | /// The name of the event to write.
40 | /// A task that represents the asynchronous write operation.
41 | public async Task WriteEventAsync ( string eventName ) {
42 | byte [] payload = _messageEncoding.GetBytes ( $"event: {eventName}\n\n" );
43 | await _innerStream.WriteAsync ( payload );
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/cadente/Sisk.Cadente/HttpHeader.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: HttpHeader.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Diagnostics.CodeAnalysis;
11 | using System.Text;
12 |
13 | namespace Sisk.Cadente;
14 |
15 | ///
16 | /// Represents an HTTP header, consisting of a name and a value.
17 | ///
18 | public readonly struct HttpHeader : IEquatable {
19 |
20 | internal readonly ReadOnlyMemory NameBytes;
21 | internal readonly ReadOnlyMemory ValueBytes;
22 |
23 | static Encoding HeaderEncoding = Encoding.UTF8;
24 |
25 | ///
26 | /// Gets a value indicating whether this has any empty value or name.
27 | ///
28 | public bool IsEmpty { get => NameBytes.IsEmpty || ValueBytes.IsEmpty; }
29 |
30 | ///
31 | /// Initializes a new instance of the struct with the specified name and value as byte arrays.
32 | ///
33 | /// The byte array representing the name of the header.
34 | /// The byte array representing the value of the header.
35 | public HttpHeader ( in ReadOnlyMemory nameBytes, in ReadOnlyMemory valueBytes ) {
36 | NameBytes = nameBytes;
37 | ValueBytes = valueBytes;
38 | }
39 |
40 | ///
41 | /// Initializes a new instance of the struct with the specified name and value as strings.
42 | ///
43 | /// The name of the header.
44 | /// The value of the header.
45 | public HttpHeader ( string name, string value ) {
46 | NameBytes = HeaderEncoding.GetBytes ( name );
47 | ValueBytes = HeaderEncoding.GetBytes ( value );
48 | }
49 |
50 | ///
51 | /// Gets the name of the header as a string.
52 | ///
53 | public string Name {
54 | get {
55 | return HeaderEncoding.GetString ( NameBytes.Span );
56 | }
57 | }
58 |
59 | ///
60 | /// Gets the value of the header as a string.
61 | ///
62 | public string Value {
63 | get {
64 | return HeaderEncoding.GetString ( ValueBytes.Span );
65 | }
66 | }
67 |
68 | ///
69 | /// Gets the string representation of this .
70 | ///
71 | public override string ToString () {
72 | return $"{Name}: {Value}";
73 | }
74 |
75 | ///
76 | public override bool Equals ( [NotNullWhen ( true )] object? obj ) {
77 | if (obj is HttpHeader other) {
78 | return Equals ( other );
79 | }
80 | else {
81 | return object.Equals ( this, obj );
82 | }
83 | }
84 |
85 | ///
86 | public override int GetHashCode () {
87 | return HashCode.Combine ( NameBytes, ValueBytes );
88 | }
89 |
90 | ///
91 | public bool Equals ( HttpHeader other ) {
92 | return NameBytes.Span.SequenceEqual ( other.NameBytes.Span ) &&
93 | ValueBytes.Span.SequenceEqual ( other.ValueBytes.Span );
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/cadente/Sisk.Cadente/HttpHeaderExtensions.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: HttpHeaderExtensions.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Collections;
11 | using System.Runtime.InteropServices;
12 | using System.Text;
13 |
14 | namespace Sisk.Cadente;
15 |
16 | internal static class HttpHeaderExtensions {
17 | public static void Set ( this List headers, in HttpHeader header ) {
18 | lock (((ICollection) headers).SyncRoot) {
19 |
20 | var span = CollectionsMarshal.AsSpan ( headers );
21 | for (int i = span.Length - 1; i >= 0; i--) {
22 | if (Ascii.EqualsIgnoreCase ( span [ i ].NameBytes.Span, header.NameBytes.Span )) {
23 | headers.RemoveAt ( i );
24 | }
25 | }
26 |
27 | headers.Add ( header );
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/cadente/Sisk.Cadente/HttpHostClient.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: HttpHostClient.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Net;
11 | using System.Security.Cryptography.X509Certificates;
12 |
13 | namespace Sisk.Cadente;
14 |
15 | ///
16 | /// Represents an HTTP host client with its endpoint and certificate information.
17 | ///
18 | public sealed class HttpHostClient {
19 |
20 | ///
21 | /// Gets the endpoint of the client.
22 | ///
23 | public IPEndPoint ClientEndpoint { get; }
24 |
25 | ///
26 | /// Gets the client certificate, if any.
27 | ///
28 | public X509Certificate? ClientCertificate { get; internal set; }
29 |
30 | ///
31 | /// Gets or sets an optional state object associated with the client.
32 | ///
33 | public object? State { get; set; }
34 |
35 | internal HttpHostClient ( IPEndPoint clientEndpoint ) {
36 | ClientEndpoint = clientEndpoint;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/cadente/Sisk.Cadente/HttpHostHandler.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: HttpHostHandler.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.Cadente;
11 |
12 | ///
13 | /// Provides a base class for handling HTTP host events.
14 | ///
15 | public abstract class HttpHostHandler {
16 |
17 | ///
18 | /// Called when a new context is created for the specified HTTP host.
19 | ///
20 | /// The HTTP host that created the context.
21 | /// The newly created context.
22 | /// A task that represents the asynchronous operation.
23 | public virtual Task OnContextCreatedAsync ( HttpHost host, HttpHostContext context ) {
24 | return Task.CompletedTask;
25 | }
26 |
27 | ///
28 | /// Called when a new client connects to the specified HTTP host.
29 | ///
30 | /// The HTTP host that the client connected to.
31 | /// The client that connected to the host.
32 | /// A task that represents the asynchronous operation.
33 | public virtual Task OnClientConnectedAsync ( HttpHost host, HttpHostClient client ) {
34 | return Task.CompletedTask;
35 | }
36 |
37 | ///
38 | /// Called when a client disconnects from the specified HTTP host.
39 | ///
40 | /// The HTTP host that the client disconnected from.
41 | /// The client that disconnected from the host.
42 | /// A task that represents the asynchronous operation.
43 | public virtual Task OnClientDisconnectedAsync ( HttpHost host, HttpHostClient client ) {
44 | return Task.CompletedTask;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/cadente/Sisk.Cadente/HttpHostTimeoutManager.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: HttpHostTimeoutManager.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.Cadente;
11 |
12 | ///
13 | /// Manages timeouts for HTTP hosts.
14 | ///
15 | public sealed class HttpHostTimeoutManager {
16 |
17 | internal int _ClientReadTimeoutSeconds = 30;
18 | internal int _ClientWriteTimeoutSeconds = 30;
19 |
20 | ///
21 | /// Gets or sets the timeout for client read operations.
22 | ///
23 | public TimeSpan ClientReadTimeout {
24 | get => TimeSpan.FromSeconds ( _ClientReadTimeoutSeconds );
25 | set => _ClientReadTimeoutSeconds = (int) value.TotalSeconds;
26 | }
27 |
28 | ///
29 | /// Gets or sets the timeout for client write operations.
30 | ///
31 | public TimeSpan ClientWriteTimeout {
32 | get => TimeSpan.FromSeconds ( _ClientWriteTimeoutSeconds );
33 | set => _ClientWriteTimeoutSeconds = (int) value.TotalSeconds;
34 | }
35 |
36 | internal HttpHostTimeoutManager () { }
37 | }
--------------------------------------------------------------------------------
/cadente/Sisk.Cadente/HttpSerializer/HttpRequestBase.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: HttpRequestBase.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Text;
11 |
12 | namespace Sisk.Cadente.HttpSerializer;
13 |
14 | sealed class HttpRequestBase {
15 |
16 | private string? _method;
17 | private string? _path;
18 | private HttpHeader []? _headers;
19 |
20 | public bool IsExpecting100;
21 |
22 | public long ContentLength;
23 | public bool CanKeepAlive;
24 |
25 | public required ReadOnlyMemory BufferedContent;
26 |
27 | public required ReadOnlyMemory MethodRef;
28 | public required ReadOnlyMemory PathRef;
29 |
30 | public required ReadOnlyMemory Headers;
31 |
32 | public string Method {
33 | get {
34 | _method ??= Encoding.ASCII.GetString ( MethodRef.Span );
35 | return _method;
36 | }
37 | }
38 |
39 | public string Path {
40 | get {
41 | _path ??= Encoding.ASCII.GetString ( PathRef.Span );
42 | return _path;
43 | }
44 | }
45 |
46 | public HttpHeader [] HeadersAR {
47 | get {
48 | _headers ??= Headers.ToArray ();
49 | return _headers;
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/cadente/Sisk.Cadente/HttpsOptions.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: HttpsOptions.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Security.Authentication;
11 | using System.Security.Cryptography.X509Certificates;
12 |
13 | namespace Sisk.Cadente;
14 |
15 | ///
16 | /// Represents the options for configuring an HTTPS server.
17 | ///
18 | public sealed class HttpsOptions {
19 |
20 | ///
21 | /// Gets the SSL certificate used by the proxy server.
22 | ///
23 | public X509Certificate ServerCertificate { get; }
24 |
25 | ///
26 | /// Gets or sets a value indicating whether client certificates are required for authentication.
27 | ///
28 | public bool ClientCertificateRequired { get; set; } = false;
29 |
30 | ///
31 | /// Gets or sets the SSL/HTTPS protocols allowed for connections.
32 | ///
33 | public SslProtocols AllowedProtocols { get; set; } = SslProtocols.Tls12 | SslProtocols.Tls13;
34 |
35 | ///
36 | /// Gets or sets a value indicating whether to check for certificate revocation.
37 | ///
38 | public bool CheckCertificateRevocation { get; set; } = false;
39 |
40 | ///
41 | /// Initializes a new instance of the class.
42 | ///
43 | /// The used to encrypt data between the client and the server.
44 | public HttpsOptions ( X509Certificate certificate ) {
45 | ServerCertificate = certificate;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/cadente/Sisk.Cadente/Logger.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: Logger.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Runtime.CompilerServices;
11 |
12 | namespace Sisk.Cadente;
13 |
14 | static class Logger {
15 |
16 | [MethodImpl ( MethodImplOptions.AggressiveInlining )]
17 | public static void LogInformation ( string? message ) {
18 | #if VERBOSE && DEBUG
19 | Debug.WriteLine ( $"Sisk.ManagedHttpListener [{DateTime.Now:R}] {message}" );
20 | #endif
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/cadente/Sisk.Cadente/SpanReader.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: SpanReader.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Runtime.CompilerServices;
11 |
12 | namespace Sisk.Cadente;
13 |
14 | ref struct SpanReader where T : IEquatable {
15 |
16 | int readLength = 0;
17 |
18 | public ReadOnlySpan UnreadSpan { get => Span [ readLength.. ]; }
19 | public ReadOnlySpan Span { get; }
20 |
21 | public int Consumed { get => readLength; }
22 |
23 | public SpanReader ( in ReadOnlySpan span ) {
24 | Span = span;
25 | }
26 |
27 | public bool TryReadToAny ( out ReadOnlySpan result, scoped ReadOnlySpan delimiters, bool advancePastDelimiter = false ) {
28 |
29 | ReadOnlySpan remaining = UnreadSpan;
30 |
31 | int index = delimiters.Length switch {
32 | 0 => -1,
33 | 2 => remaining.IndexOfAny ( delimiters [ 0 ], delimiters [ 1 ] ),
34 | 3 => remaining.IndexOfAny ( delimiters [ 0 ], delimiters [ 1 ], delimiters [ 3 ] ),
35 | _ => remaining.IndexOfAny ( delimiters )
36 | };
37 |
38 | if (index != -1) {
39 | result = remaining.Slice ( 0, index );
40 | Advance ( index + (advancePastDelimiter ? 1 : 0) );
41 | return true;
42 | }
43 |
44 | result = default;
45 | return false;
46 | }
47 |
48 | [MethodImpl ( MethodImplOptions.AggressiveInlining )]
49 | public void Advance ( int count ) {
50 | readLength += count;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/cadente/Sisk.Cadente/Streams/HttpChunkedStream.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: HttpChunkedStream.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Text;
11 |
12 | namespace Sisk.Cadente.Streams;
13 |
14 | internal class HttpChunkedStream : Stream {
15 | private Stream _stream;
16 | int written = 0;
17 | bool innerStreamReturnedZero = false;
18 |
19 | const int CHUNKED_MAX_SIZE = 4096;
20 | static readonly byte [] CrLf = [ 0x0D, 0x0A ];
21 |
22 | public HttpChunkedStream ( Stream stream ) {
23 | _stream = stream;
24 | }
25 |
26 | public override bool CanRead => _stream.CanRead;
27 |
28 | public override bool CanSeek => false;
29 |
30 | public override bool CanWrite => false;
31 |
32 | public override long Length => throw new NotSupportedException ();
33 |
34 | public override long Position { get => written; set => throw new NotSupportedException (); }
35 |
36 | public override void Flush () {
37 | _stream.Flush ();
38 | }
39 |
40 | public override int Read ( byte [] buffer, int offset, int count ) {
41 |
42 | if (innerStreamReturnedZero)
43 | return 0;
44 |
45 | Span readBuffer = stackalloc byte [ Math.Min ( count - 2, CHUNKED_MAX_SIZE ) ];
46 | int read = _stream.Read ( readBuffer );
47 | byte [] readBytesEncoded = Encoding.ASCII.GetBytes ( $"{read:x}\r\n" );
48 |
49 | if (read == 0) {
50 | innerStreamReturnedZero = true;
51 | }
52 |
53 | Array.Copy (
54 | sourceArray: readBytesEncoded,
55 | sourceIndex: 0,
56 | destinationArray: buffer,
57 | destinationIndex: 0,
58 | length: readBytesEncoded.Length );
59 |
60 | int copyStart = readBytesEncoded.Length;
61 |
62 | readBuffer [ 0..read ].CopyTo ( buffer.AsSpan () [ copyStart.. ] );
63 |
64 | int bufferEnd = readBytesEncoded.Length + read;
65 | buffer [ bufferEnd + 0 ] = 0x0D;
66 | buffer [ bufferEnd + 1 ] = 0x0A;
67 |
68 | written += read;
69 |
70 | return bufferEnd + 2;
71 | }
72 |
73 | public override long Seek ( long offset, SeekOrigin origin ) {
74 | throw new NotSupportedException ();
75 | }
76 |
77 | public override void SetLength ( long value ) {
78 | throw new NotSupportedException ();
79 | }
80 |
81 | public override void Write ( byte [] buffer, int offset, int count ) {
82 | throw new NotSupportedException ();
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/cadente/Sisk.Cadente/Streams/HttpRequestStream.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: HttpRequestStream.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using Sisk.Cadente.HttpSerializer;
11 |
12 | namespace Sisk.Cadente.Streams;
13 |
14 | internal class HttpRequestStream : Stream {
15 | private Stream s;
16 | private HttpRequestBase baseRequest;
17 | int read = 0;
18 | int bufferedByteLength = 0;
19 |
20 | public HttpRequestStream ( Stream clientStream, HttpRequestBase baseRequest ) {
21 | s = clientStream;
22 | this.baseRequest = baseRequest;
23 | bufferedByteLength = this.baseRequest.BufferedContent.Length;
24 | }
25 |
26 | public override bool CanRead => s.CanRead;
27 |
28 | public override bool CanSeek => false;
29 |
30 | public override bool CanWrite => false;
31 |
32 | public override long Length => baseRequest.ContentLength;
33 |
34 | public override long Position { get => read; set => s.Position = value; }
35 |
36 | public override void Flush () {
37 | s.Flush ();
38 | }
39 |
40 | public override int Read ( byte [] buffer, int offset, int count ) {
41 | if (read >= baseRequest.ContentLength) {
42 | return 0;
43 | }
44 |
45 | int bufferRead = ReadFromBuffer ( buffer, offset, count );
46 | if (bufferRead > 0) {
47 | read += bufferRead;
48 | return bufferRead;
49 | }
50 | else {
51 | int streamRead = s.Read ( buffer, offset, count );
52 | read += streamRead;
53 | return streamRead;
54 | }
55 | }
56 |
57 | int ReadFromBuffer ( byte [] buffer, int offset, int count ) {
58 | long availableRead = Math.Min ( bufferedByteLength, baseRequest.ContentLength ) - read;
59 |
60 | if (availableRead <= 0)
61 | return 0;
62 |
63 | long toRead = Math.Min ( count, availableRead );
64 |
65 | int bufferOffset = read;
66 |
67 | var bufferMemory = new Memory ( buffer );
68 | baseRequest.BufferedContent [ bufferOffset.. ].CopyTo ( bufferMemory [ offset..(offset + (int) toRead) ] );
69 |
70 | return (int) toRead;
71 | }
72 |
73 | public override long Seek ( long offset, SeekOrigin origin ) {
74 | return s.Seek ( offset, origin );
75 | }
76 |
77 | public override void SetLength ( long value ) {
78 | s.SetLength ( value );
79 | }
80 |
81 | public override void Write ( byte [] buffer, int offset, int count ) {
82 | s.Write ( buffer, offset, count );
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/cadente/Sisk.Cadente/TransferEncoding.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: TransferEncoding.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.Cadente;
11 |
12 | ///
13 | /// Represents an HTTP transfer-encoding algorithm.
14 | ///
15 | [Flags]
16 | public enum TransferEncoding {
17 | ///
18 | /// Indicates that the response is sent in a series of chunks.
19 | ///
20 | Chunked = 1 << 1,
21 |
22 | ///
23 | /// Indicates that the response is compressed using GZip encoding.
24 | ///
25 | GZip = 1 << 2,
26 |
27 | ///
28 | /// Indicates that the response is compressed using Deflate encoding.
29 | ///
30 | Deflate = 1 << 3
31 | }
32 |
--------------------------------------------------------------------------------
/extensions/Sisk.BasicAuth/BasicAuthenticationCredentials.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: BasicAuthenticationCredentials.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.BasicAuth;
11 |
12 | ///
13 | /// Represents basic authentication credentials for an HTTP request.
14 | ///
15 | ///
16 | /// public class BasicAuthenticationCredentials
17 | ///
18 | ///
19 | /// Class
20 | ///
21 | public class BasicAuthenticationCredentials {
22 | ///
23 | /// Gets the user id component from this credentials.
24 | ///
25 | ///
26 | /// public string UserId { get; }
27 | ///
28 | ///
29 | /// Property
30 | ///
31 | public string UserId { get; private set; }
32 |
33 | ///
34 | /// Gets the plain password component from this credentials.
35 | ///
36 | ///
37 | /// public string Password { get; }
38 | ///
39 | ///
40 | /// Property
41 | ///
42 | public string Password { get; private set; }
43 |
44 | internal BasicAuthenticationCredentials ( string username, string password ) {
45 | UserId = username;
46 | Password = password;
47 | }
48 | }
--------------------------------------------------------------------------------
/extensions/Sisk.BasicAuth/Sisk.BasicAuth.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | enable
6 | enable
7 | True
8 | True
9 |
10 | Sisk.BasicAuth
11 | Sisk.BasicAuth
12 |
13 | CypherPotato
14 | Project Principium
15 | Sisk.BasicAuth
16 | This package includes an helper for embeding basic authentication in your applications made with Sisk.
17 | https://sisk.proj.pw/
18 | Icon.png
19 | README.md
20 | https://github.com/sisk-http/core
21 | http-server,http,web framework
22 | git
23 |
24 | 1.2.0
25 | 1.2.0
26 | 1.2.0
27 |
28 | en
29 | LICENSE.txt
30 | True
31 |
32 |
33 |
34 |
35 | True
36 | \
37 |
38 |
39 | True
40 | \
41 |
42 |
43 | True
44 | \
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/extensions/Sisk.Documenting.Html/Sisk.Documenting.Html.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | enable
6 | enable
7 | True
8 | True
9 |
10 | True
11 | true
12 |
13 | Sisk.Documenting.Html
14 | Sisk.Documenting.Html
15 |
16 | CypherPotato
17 | Project Principium
18 | Sisk.Documenting.Html
19 | This package provides the HtmlDocumentationExporter object.
20 | https://sisk.proj.pw/
21 | Icon.png
22 | README.md
23 | https://github.com/sisk-http/core
24 | http-server,http,web framework
25 | git
26 |
27 | 1.4.0
28 | 1.4.0
29 | 1.4.0-beta1
30 |
31 | en
32 | LICENSE.txt
33 | True
34 |
35 |
36 |
37 | true
38 |
39 |
40 | $(NoWarn);SYSLIB0020
41 |
42 |
43 |
44 |
45 | True
46 | \
47 |
48 |
49 | True
50 | \
51 |
52 |
53 | True
54 | \
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/extensions/Sisk.Documenting/Annotations/ApiEndpointAttribute.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: ApiEndpointAttribute.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.Documenting.Annotations;
11 |
12 | ///
13 | /// Specifies an attribute for an API endpoint, allowing metadata such as name, description, and group to be associated with methods.
14 | ///
15 | [AttributeUsage ( AttributeTargets.Method, AllowMultiple = false )]
16 | public sealed class ApiEndpointAttribute : Attribute {
17 | ///
18 | /// Gets or sets the name of the API endpoint.
19 | ///
20 | public string Name { get; set; }
21 |
22 | ///
23 | /// Gets or sets the description of the API endpoint.
24 | ///
25 | public string? Description { get; set; }
26 |
27 | ///
28 | /// Gets or sets the group to which the API endpoint belongs.
29 | ///
30 | public string? Group { get; set; }
31 |
32 | ///
33 | /// Gets or sets whether the description should be inherited from XML documentation if the attribute description
34 | /// is not provided.
35 | ///
36 | public bool InheritDescriptionFromXmlDocumentation { get; set; } = true;
37 |
38 | public ApiEndpointAttribute () {
39 | Name = string.Empty;
40 | }
41 |
42 | ///
43 | /// Initializes a new instance of the class with the specified endpoint name.
44 | ///
45 | /// The name of the API endpoint.
46 | public ApiEndpointAttribute ( string name ) {
47 | Name = name;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/extensions/Sisk.Documenting/Annotations/ApiHeaderAttribute.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: ApiHeaderAttribute.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.Documenting.Annotations;
11 |
12 | ///
13 | /// Specifies an attribute for an API header, allowing metadata such as header name, description, and requirement status to be associated with methods.
14 | ///
15 | [AttributeUsage ( AttributeTargets.Method, AllowMultiple = true )]
16 | public sealed class ApiHeaderAttribute : Attribute {
17 | ///
18 | /// Gets the name of the header.
19 | ///
20 | public string HeaderName { get; }
21 |
22 | ///
23 | /// Gets or sets the description of the header.
24 | ///
25 | public string? Description { get; set; }
26 |
27 | ///
28 | /// Gets or sets a value indicating whether the header is required.
29 | ///
30 | public bool IsRequired { get; set; }
31 |
32 | ///
33 | /// Initializes a new instance of the class with the specified header name.
34 | ///
35 | /// The name of the header.
36 | public ApiHeaderAttribute ( string headerName ) {
37 | HeaderName = headerName;
38 | }
39 |
40 | internal ApiEndpointHeader GetApiEndpointObject () {
41 | return new ApiEndpointHeader {
42 | HeaderName = HeaderName,
43 | Description = Description,
44 | IsRequired = IsRequired
45 | };
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/extensions/Sisk.Documenting/Annotations/ApiParameterAttribute.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: ApiParameterAttribute.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.Documenting.Annotations;
11 |
12 | ///
13 | /// Specifies an attribute for an API parameter, allowing metadata such as name, type, description, and requirement status to be associated with methods.
14 | ///
15 | [AttributeUsage ( AttributeTargets.Method, AllowMultiple = true )]
16 | public sealed class ApiParameterAttribute : Attribute {
17 | ///
18 | /// Gets the name of the parameter.
19 | ///
20 | public string Name { get; }
21 |
22 | ///
23 | /// Gets the type name of the parameter.
24 | ///
25 | public string TypeName { get; }
26 |
27 | ///
28 | /// Gets or sets the description of the parameter.
29 | ///
30 | public string? Description { get; set; }
31 |
32 | ///
33 | /// Gets or sets a value indicating whether the parameter is required.
34 | ///
35 | public bool IsRequired { get; set; }
36 |
37 | ///
38 | /// Initializes a new instance of the class with the specified name and type name.
39 | ///
40 | /// The name of the parameter.
41 | /// The type name of the parameter.
42 | public ApiParameterAttribute ( string name, string typeName ) {
43 | Name = name;
44 | TypeName = typeName;
45 | }
46 |
47 | internal ApiEndpointParameter GetApiEndpointObject () {
48 | return new ApiEndpointParameter {
49 | Name = Name,
50 | TypeName = TypeName,
51 | Description = Description,
52 | IsRequired = IsRequired
53 | };
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/extensions/Sisk.Documenting/Annotations/ApiParametersFromAttribute.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: ApiParametersFromAttribute.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.Documenting.Annotations;
11 |
12 | [AttributeUsage ( AttributeTargets.Method, AllowMultiple = true )]
13 | public sealed class ApiParametersFromAttribute : Attribute {
14 |
15 | public Type Type { get; }
16 |
17 | public ApiParametersFromAttribute ( Type type ) {
18 | Type = type;
19 | }
20 |
21 | internal ApiEndpointParameter [] GetParameters ( ApiGenerationContext context ) {
22 | return context.ParameterExampleTypeHandler?.GetParameterExamplesForType ( Type )
23 | .Select ( x => new ApiEndpointParameter () {
24 | Name = x.ParameterName,
25 | Description = x.Description,
26 | IsRequired = x.IsRequired,
27 | TypeName = x.TypeName
28 | } ).ToArray ()
29 | ?? Array.Empty ();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/extensions/Sisk.Documenting/Annotations/ApiPathParameterAttribute.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: ApiPathParameterAttribute.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.Documenting.Annotations;
11 |
12 | ///
13 | /// Specifies an attribute for an API path parameter, allowing metadata such as name, type, and description to be associated with methods.
14 | ///
15 | [AttributeUsage ( AttributeTargets.Method, AllowMultiple = true )]
16 | public sealed class ApiPathParameterAttribute : Attribute {
17 | ///
18 | /// Gets the name of the path parameter.
19 | ///
20 | public string Name { get; }
21 |
22 | ///
23 | /// Gets or sets the type of the path parameter.
24 | ///
25 | public string? Type { get; set; }
26 |
27 | ///
28 | /// Gets or sets the description of the path parameter.
29 | ///
30 | public string? Description { get; set; }
31 |
32 | ///
33 | /// Initializes a new instance of the class with the specified name.
34 | ///
35 | /// The name of the path parameter.
36 | public ApiPathParameterAttribute ( string name ) {
37 | Name = name;
38 | }
39 |
40 | internal ApiEndpointPathParameter GetApiEndpointObject () {
41 | return new ApiEndpointPathParameter {
42 | Name = Name,
43 | Description = Description,
44 | Type = Type
45 | };
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/extensions/Sisk.Documenting/Annotations/ApiRequestAttribute.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: ApiRequestAttribute.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.Documenting.Annotations;
11 |
12 | ///
13 | /// Specifies an attribute for an API request, allowing metadata such as description, example language, and example content to be associated with methods.
14 | ///
15 | [AttributeUsage ( AttributeTargets.Method, AllowMultiple = true )]
16 | public sealed class ApiRequestAttribute : Attribute {
17 | ///
18 | /// Gets or sets the description of the API request.
19 | ///
20 | public string Description { get; set; }
21 |
22 | ///
23 | /// Gets or sets the programming language used in the example, if applicable.
24 | ///
25 | public string? ExampleLanguage { get; set; }
26 |
27 | ///
28 | /// Gets or sets the actual example request content.
29 | ///
30 | public string? Example { get; set; }
31 |
32 | public Type? ExampleType { get; set; }
33 |
34 | ///
35 | /// Initializes a new instance of the class with the specified description.
36 | ///
37 | /// The description of the API request.
38 | public ApiRequestAttribute ( string description ) {
39 | Description = description;
40 | }
41 |
42 | internal ApiEndpointRequestExample GetApiEndpointObject ( ApiGenerationContext context ) {
43 |
44 | string? example = Example;
45 | string? exampleLanguage = ExampleLanguage;
46 |
47 | if (ExampleType != null && context.BodyExampleTypeHandler?.GetBodyExampleForType ( ExampleType ) is { } exampleResult) {
48 | example = exampleResult.ExampleContents;
49 | exampleLanguage = exampleResult.ExampleLanguage;
50 | }
51 |
52 | return new ApiEndpointRequestExample {
53 | Description = Description,
54 | ExampleLanguage = exampleLanguage,
55 | Example = example,
56 | };
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/extensions/Sisk.Documenting/Annotations/ApiResponseAttribute.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: ApiResponseAttribute.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Net;
11 |
12 | namespace Sisk.Documenting.Annotations;
13 |
14 | ///
15 | /// Specifies an attribute for an API response, allowing metadata such as status code, description, example content, and example language to be associated with methods.
16 | ///
17 | [AttributeUsage ( AttributeTargets.Method, AllowMultiple = true )]
18 | public sealed class ApiResponseAttribute : Attribute {
19 | ///
20 | /// Gets the HTTP status code for the response.
21 | ///
22 | public HttpStatusCode StatusCode { get; }
23 |
24 | ///
25 | /// Gets or sets the description of the response.
26 | ///
27 | public string? Description { get; set; }
28 |
29 | ///
30 | /// Gets or sets the example response content.
31 | ///
32 | public string? Example { get; set; }
33 |
34 | ///
35 | /// Gets or sets the programming language used in the example, if applicable.
36 | ///
37 | public string? ExampleLanguage { get; set; }
38 |
39 |
40 | public Type? ExampleType { get; set; }
41 |
42 | ///
43 | /// Initializes a new instance of the class with the specified status code.
44 | ///
45 | /// The HTTP status code for the response.
46 | public ApiResponseAttribute ( HttpStatusCode statusCode ) {
47 | StatusCode = statusCode;
48 | }
49 |
50 | internal ApiEndpointResponse GetApiEndpointObject ( ApiGenerationContext context ) {
51 |
52 | string? example = Example;
53 | string? exampleLanguage = ExampleLanguage;
54 |
55 | if (ExampleType != null && context.BodyExampleTypeHandler?.GetBodyExampleForType ( ExampleType ) is { } exampleResult) {
56 | example = exampleResult.ExampleContents;
57 | exampleLanguage = exampleResult.ExampleLanguage;
58 | }
59 |
60 | return new ApiEndpointResponse {
61 | StatusCode = StatusCode,
62 | Description = Description,
63 | Example = example,
64 | ExampleLanguage = exampleLanguage,
65 | };
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/extensions/Sisk.Documenting/ApiGenerationContext.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: ApiGenerationContext.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.Documenting;
11 |
12 | public sealed class ApiGenerationContext {
13 |
14 | ///
15 | /// Gets or sets the name of the application.
16 | ///
17 | public string? ApplicationName { get; set; }
18 |
19 | ///
20 | /// Gets or sets the version of the application.
21 | ///
22 | public string? ApplicationVersion { get; set; }
23 |
24 | ///
25 | /// Gets or sets the description of the application.
26 | ///
27 | public string? ApplicationDescription { get; set; }
28 |
29 | public IExampleBodyTypeHandler? BodyExampleTypeHandler { get; set; }
30 |
31 | public IExampleParameterTypeHandler? ParameterExampleTypeHandler { get; set; }
32 | }
33 |
--------------------------------------------------------------------------------
/extensions/Sisk.Documenting/BodyExampleResult.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: BodyExampleResult.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.Documenting;
11 |
12 | public sealed class BodyExampleResult {
13 | public string ExampleContents { get; }
14 | public string? ExampleLanguage { get; }
15 |
16 | public BodyExampleResult ( string exampleContents, string? exampleLanguage ) {
17 | ExampleContents = exampleContents;
18 | ExampleLanguage = exampleLanguage;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/extensions/Sisk.Documenting/IApiDocumentationExporter.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: IApiDocumentationExporter.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.Documenting;
11 |
12 | ///
13 | /// Defines a contract for exporting API documentation content.
14 | ///
15 | public interface IApiDocumentationExporter {
16 |
17 | ///
18 | /// Exports the specified API documentation content.
19 | ///
20 | /// The API documentation to export.
21 | /// An representing the exported documentation.
22 | public HttpContent ExportDocumentationContent ( ApiDocumentation documentation );
23 | }
--------------------------------------------------------------------------------
/extensions/Sisk.Documenting/IExampleBodyTypeHandler.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: IExampleBodyTypeHandler.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.Documenting;
11 |
12 | public interface IExampleBodyTypeHandler {
13 | public BodyExampleResult? GetBodyExampleForType ( Type type );
14 | }
15 |
--------------------------------------------------------------------------------
/extensions/Sisk.Documenting/IExampleParameterTypeHandler.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: IExampleParameterTypeHandler.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.Documenting;
11 |
12 | public interface IExampleParameterTypeHandler {
13 | public ParameterExampleResult [] GetParameterExamplesForType ( Type type );
14 | }
15 |
--------------------------------------------------------------------------------
/extensions/Sisk.Documenting/ParameterExampleResult.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: ParameterExampleResult.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.Documenting;
11 |
12 | public sealed class ParameterExampleResult {
13 | public string ParameterName { get; init; }
14 | public string TypeName { get; init; }
15 | public string? Description { get; init; }
16 | public bool IsRequired { get; init; }
17 |
18 | public ParameterExampleResult ( string parameterName, string typeName, bool isRequired, string? description ) {
19 | ParameterName = parameterName;
20 | TypeName = typeName;
21 | IsRequired = isRequired;
22 | Description = description;
23 | }
24 |
25 | public ParameterExampleResult ( string parameterName, string typeName, bool isRequired ) {
26 | ParameterName = parameterName;
27 | TypeName = typeName;
28 | IsRequired = isRequired;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/extensions/Sisk.Documenting/Sisk.Documenting.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | enable
6 | enable
7 | True
8 | True
9 |
10 | True
11 | true
12 |
13 | Sisk.Documenting
14 | Sisk.Documenting
15 |
16 | CypherPotato
17 | Project Principium
18 | Sisk.Documenting
19 | This package provides a way to export documentation from your Sisk API.
20 | https://sisk.proj.pw/
21 | Icon.png
22 | README.md
23 | https://github.com/sisk-http/core
24 | http-server,http,web framework
25 | git
26 |
27 | 1.4.0
28 | 1.4.0
29 | 1.4.0-beta1
30 |
31 | en
32 | LICENSE.txt
33 | True
34 |
35 |
36 |
37 | true
38 |
39 |
40 | $(NoWarn);SYSLIB0020
41 |
42 |
43 |
44 |
45 | True
46 | \
47 |
48 |
49 | True
50 | \
51 |
52 |
53 | True
54 | \
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/extensions/Sisk.Helpers.mitmproxy/MitmproxyHelper.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: MitmproxyHelper.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using Asmichi.ProcessManagement;
11 | using Sisk.Core.Http.Hosting;
12 | using Sisk.Helpers.Mitmproxy;
13 |
14 | namespace Sisk.Helpers.mitmproxy;
15 |
16 | ///
17 | /// Provides extension methods for configuring an HTTP server to use mitmproxy.
18 | ///
19 | public static class MitmproxyHelper {
20 | ///
21 | /// Configures the specified to use mitmproxy with a random proxy port.
22 | ///
23 | /// The instance to configure.
24 | /// The updated instance.
25 | public static HttpServerHostContextBuilder UseMitmproxy ( this HttpServerHostContextBuilder builder ) => UseMitmproxy ( builder, proxyPort: 0 );
26 |
27 | ///
28 | /// Configures the specified to use mitmproxy with the specified options.
29 | ///
30 | /// The instance to configure.
31 | /// The port on which the mitmproxy will listen.
32 | /// Indicates whether the mitmproxy should run in silent mode. Default is false.
33 | /// An optional action to configure the child process start information.
34 | /// The updated instance.
35 | public static HttpServerHostContextBuilder UseMitmproxy ( this HttpServerHostContextBuilder builder,
36 | ushort proxyPort = 0,
37 | bool silent = false,
38 | Action? setupAction = null ) {
39 | var proxy = new MitmproxyProvider ( proxyPort, setupAction ) {
40 | Silent = silent
41 | };
42 |
43 | builder.UseHandler ( proxy );
44 | builder.UseStartupMessage ( () => $"""
45 | The mitmproxy is listening at:
46 | - https://localhost:{proxy.ProxyPort}/
47 | """ );
48 |
49 | return builder;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/extensions/Sisk.Helpers.mitmproxy/MitmproxyProvider.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: MitmproxyProvider.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using Asmichi.ProcessManagement;
11 | using Sisk.Core.Http;
12 | using Sisk.Core.Http.Handlers;
13 |
14 | namespace Sisk.Helpers.Mitmproxy;
15 |
16 | ///
17 | /// Provides a MITM proxy server handler.
18 | ///
19 | public sealed class MitmproxyProvider : HttpServerHandler {
20 | private ChildProcessStartInfo MitmdumpProcessInfo = null!;
21 | private readonly Action? setupAction;
22 |
23 | ///
24 | /// Gets the mitmdump process.
25 | ///
26 | public IChildProcess MitmdumpProcess { get; private set; } = null!;
27 |
28 | ///
29 | /// Gets or sets the proxy port.
30 | ///
31 | public ushort ProxyPort { get; private set; }
32 |
33 | ///
34 | /// Gets or sets a value indicating whether to run the mitmdump process silently.
35 | ///
36 | public bool Silent { get; set; }
37 |
38 | ///
39 | /// Initializes a new instance of the class.
40 | ///
41 | public MitmproxyProvider () {
42 | ProxyPort = 0;
43 | }
44 |
45 | ///
46 | /// Initializes a new instance of the class with a specified proxy port and optional process setup action.
47 | ///
48 | /// The port on which the mitmproxy will listen.
49 | /// Optional. An action to configure the child process start information.
50 | public MitmproxyProvider ( ushort proxyPort, Action? processSetupAction = null ) {
51 | ProxyPort = proxyPort;
52 | setupAction = processSetupAction;
53 | }
54 |
55 | ///
56 | protected override void OnServerStarting ( HttpServer server ) {
57 | ChildProcessStartInfo pinfo = new ChildProcessStartInfo () {
58 | FileName = "mitmdump"
59 | };
60 |
61 | OutputRedirection outputRedirection = Silent ? OutputRedirection.NullDevice : OutputRedirection.ParentOutput;
62 | pinfo.StdOutputRedirection = outputRedirection;
63 | pinfo.StdErrorRedirection = outputRedirection;
64 |
65 | if (ProxyPort == 0) {
66 | ProxyPort = (ushort) (server.ServerConfiguration.ListeningHosts [ 0 ].Ports [ 0 ].Port + 1);
67 | }
68 |
69 | pinfo.Arguments = [ "--mode", $"reverse:{server.ListeningPrefixes [ 0 ]}", "-p", ProxyPort.ToString () ];
70 |
71 | if (setupAction != null)
72 | setupAction ( pinfo );
73 |
74 | MitmdumpProcessInfo = pinfo;
75 | }
76 |
77 | ///
78 | protected override void OnServerStarted ( HttpServer server ) {
79 | try {
80 | MitmdumpProcess = ChildProcess.Start ( MitmdumpProcessInfo );
81 | }
82 | catch (Exception e) {
83 | Console.WriteLine ( "Failed to start the mitmproxy. Perhaps you forgot to install it and make " +
84 | "mitmdump executable available in your PATH?" );
85 | Console.WriteLine ( $"Inner exception: {e.Message}" );
86 | Environment.Exit ( -1 );
87 | }
88 | }
89 |
90 | ///
91 | protected override void OnServerStopping ( HttpServer server ) {
92 | MitmdumpProcess.Kill ();
93 | }
94 |
95 | ///
96 | protected override void OnServerStopped ( HttpServer server ) {
97 | MitmdumpProcess.Dispose ();
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/extensions/Sisk.IniConfiguration.Core/Serialization/Token.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: Token.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.IniConfiguration.Core.Serialization;
11 |
12 | static class Token {
13 | public const char SECTION_START = '[';
14 | public const char SECTION_END = ']';
15 | public const char COMMENT_1 = '#';
16 | public const char COMMENT_2 = ';';
17 | public const char STRING_QUOTE_1 = '\'';
18 | public const char STRING_QUOTE_2 = '\"';
19 | public const char PROPERTY_DELIMITER = '=';
20 | public const char NEW_LINE = '\n';
21 | public const char RETURN = '\r';
22 | public const char TAB = '\t';
23 | public const char SPACE = ' ';
24 | }
25 |
--------------------------------------------------------------------------------
/extensions/Sisk.IniConfiguration.Core/Sisk.IniConfiguration.Core.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | enable
6 | enable
7 | True
8 | True
9 |
10 | Sisk.IniConfiguration.Core
11 | Sisk.IniConfiguration.Core
12 |
13 | CypherPotato
14 | Project Principium
15 | Sisk.IniConfiguration.Core
16 | Provides the core readers and writers for INI-based document files.
17 | https://sisk.proj.pw/
18 | Icon.png
19 | README.md
20 | https://github.com/sisk-http/core
21 | http-server,http,web framework
22 | git
23 |
24 | 1.4.3
25 | 1.4.3
26 | 1.4.3
27 |
28 | en
29 | LICENSE.txt
30 | True
31 |
32 |
33 |
34 | true
35 |
36 |
37 | $(NoWarn);SYSLIB0020
38 |
39 |
40 |
41 |
42 | True
43 | \
44 |
45 |
46 | True
47 | \
48 |
49 |
50 | True
51 | \
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/extensions/Sisk.IniConfiguration/README.md:
--------------------------------------------------------------------------------
1 | # Sisk.IniConfiguration
2 |
3 | A Sisk library for reading and writing INI files and using them as Sisk configurations.
4 |
5 | Current implementation flavor:
6 |
7 | - Properties and section names are **case-insensitive**.
8 | - Properties names and values are **trimmed**.
9 | - Values can be quoted with single or double quotes. Quotes can have line-breaks inside them.
10 | - Comments are supported with `#` and `;`. Also, **trailing comments are allowed**.
11 | - Properties can have multiple values.
12 |
13 | ## Usage
14 |
15 | Using the following ini code as example:
16 |
17 | ```ini
18 | One = 1
19 | Value = this is an value
20 | Another value = "this value
21 | has an line break on it"
22 |
23 | ; the code below has some colors
24 | [some section]
25 | Color = Red
26 | Color = Blue
27 | Color = Yellow ; do not use yellow
28 | ```
29 |
30 | Parse it with:
31 |
32 | ```csharp
33 | // parse the ini text from the string
34 | IniDocument doc = IniDocument.FromString(iniText);
35 |
36 | // get one value
37 | string? one = doc.Global.GetOne("one");
38 | string? anotherValue = doc.Global.GetOne("another value");
39 |
40 | // get multiple values
41 | string[]? colors = doc.GetSection("some section")?.GetMany("color");
42 | ```
--------------------------------------------------------------------------------
/extensions/Sisk.IniConfiguration/Sisk.IniConfiguration.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | enable
6 | enable
7 | True
8 | True
9 |
10 | Sisk.IniConfiguration
11 | Sisk.IniConfiguration
12 |
13 | CypherPotato
14 | Project Principium
15 | Sisk.IniConfiguration
16 | This package provides an INI configuration provider for Sisk projects.
17 | https://sisk.proj.pw/
18 | Icon.png
19 | README.md
20 | https://github.com/sisk-http/core
21 | http-server,http,web framework
22 | git
23 |
24 | 1.4
25 | 1.4
26 | 1.4
27 |
28 | en
29 | LICENSE.txt
30 | True
31 |
32 |
33 |
34 | true
35 |
36 |
37 | $(NoWarn);SYSLIB0020
38 |
39 |
40 |
41 |
42 | True
43 | \
44 |
45 |
46 | True
47 | \
48 |
49 |
50 | True
51 | \
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/extensions/Sisk.JsonRPC/Annotations/MethodDescriptionAttribute.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: MethodDescriptionAttribute.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.JsonRPC.Annotations;
11 |
12 | ///
13 | /// Specifies a description for a method.
14 | ///
15 | [AttributeUsage ( AttributeTargets.Method, AllowMultiple = false )]
16 | public sealed class MethodDescriptionAttribute : Attribute {
17 | ///
18 | /// Gets the description of the method.
19 | ///
20 | public string Description { get; }
21 |
22 | ///
23 | /// Optional. Gets or sets the web method category.
24 | ///
25 | public string? Category { get; set; }
26 |
27 | ///
28 | /// Initializes a new instance of the class with the specified description.
29 | ///
30 | /// The description of the method.
31 | public MethodDescriptionAttribute ( string description ) {
32 | Description = description;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/extensions/Sisk.JsonRPC/Annotations/ParamDescriptionAttribute.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: ParamDescriptionAttribute.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.JsonRPC.Annotations;
11 |
12 | ///
13 | /// Specifies a description for a method parameter.
14 | ///
15 | [AttributeUsage ( AttributeTargets.Method, AllowMultiple = true )]
16 | public sealed class ParamDescriptionAttribute : Attribute {
17 | ///
18 | /// Gets the description of the method parameter.
19 | ///
20 | public string Description { get; }
21 |
22 | ///
23 | /// Gets the target parameter name.
24 | ///
25 | public string ParameterName { get; }
26 |
27 | ///
28 | /// Initializes a new instance of the class with the specified description.
29 | ///
30 | /// The parameter name.
31 | /// The description of the method parameter.
32 | public ParamDescriptionAttribute ( string paramName, string description ) {
33 | ParameterName = paramName;
34 | Description = description;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/extensions/Sisk.JsonRPC/Annotations/WebMethodAttribute.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: WebMethodAttribute.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.JsonRPC.Annotations;
11 |
12 | ///
13 | /// Represents an JSON-RPC method.
14 | ///
15 | [AttributeUsage ( AttributeTargets.Method, AllowMultiple = false, Inherited = false )]
16 | public sealed class WebMethodAttribute : Attribute {
17 | ///
18 | /// Gets or sets the method name.
19 | ///
20 | public string? Name { get; set; }
21 |
22 | ///
23 | /// Creates an new with no parameters.
24 | ///
25 | public WebMethodAttribute () {
26 | }
27 |
28 | ///
29 | /// Creates an new with given
30 | /// parameters.
31 | ///
32 | /// The method name.
33 | public WebMethodAttribute ( string methodName ) {
34 | Name = methodName;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/extensions/Sisk.JsonRPC/Annotations/WebNameAttribute.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: WebNameAttribute.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.JsonRPC.Annotations;
11 |
12 | ///
13 | /// Represents an attribute which holds the class name for a group of
14 | /// JSON-RPC methods.
15 | ///
16 | [AttributeUsage ( AttributeTargets.Class )]
17 | public sealed class WebNameAttribute : Attribute {
18 | ///
19 | /// Gets or sets the name associated with the method group.
20 | ///
21 | public string Name { get; set; }
22 |
23 | ///
24 | /// Creates an new instance of the attribute.
25 | ///
26 | /// The method-group name.
27 | public WebNameAttribute ( string name ) {
28 | Name = name;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/extensions/Sisk.JsonRPC/Converters/JsonRpcErrorConverter.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: JsonRpcErrorConverter.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using LightJson;
11 | using LightJson.Converters;
12 |
13 | namespace Sisk.JsonRPC.Converters;
14 |
15 | internal class JsonRpcErrorConverter : JsonConverter {
16 | public override bool CanSerialize ( Type type, JsonOptions options ) {
17 | return type == typeof ( JsonRpcError );
18 | }
19 |
20 | public override object Deserialize ( JsonValue value, Type requestedType, JsonOptions options ) {
21 | throw new NotSupportedException ();
22 | }
23 |
24 | public override JsonValue Serialize ( object value, JsonOptions options ) {
25 | JsonRpcError error = (JsonRpcError) value;
26 | return new JsonObject () {
27 | [ "code" ] = error.Code,
28 | [ "message" ] = error.Message,
29 | [ "data" ] = error.Data
30 | };
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/extensions/Sisk.JsonRPC/Converters/JsonRpcRequestConverter.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: JsonRpcRequestConverter.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using LightJson;
11 | using LightJson.Converters;
12 |
13 | namespace Sisk.JsonRPC.Converters;
14 |
15 | internal class JsonRpcRequestConverter : JsonConverter {
16 | public override bool CanSerialize ( Type type, JsonOptions options ) {
17 | return type == typeof ( JsonRpcRequest );
18 | }
19 |
20 | public override object Deserialize ( JsonValue value, Type requestedType, JsonOptions options ) {
21 | return new JsonRpcRequest ( value.GetJsonObject () );
22 | }
23 |
24 | public override JsonValue Serialize ( object value, JsonOptions options ) {
25 | throw new NotSupportedException ();
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/extensions/Sisk.JsonRPC/Converters/JsonRpcResponseConverter.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: JsonRpcResponseConverter.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using LightJson;
11 | using LightJson.Converters;
12 |
13 | namespace Sisk.JsonRPC.Converters;
14 |
15 | internal class JsonRpcResponseConverter : JsonConverter {
16 | public override bool CanSerialize ( Type type, JsonOptions options ) {
17 | return type == typeof ( JsonRpcResponse );
18 | }
19 |
20 | public override object Deserialize ( JsonValue value, Type requestedType, JsonOptions options ) {
21 | throw new NotSupportedException ();
22 | }
23 |
24 | public override JsonValue Serialize ( object value, JsonOptions options ) {
25 | JsonRpcResponse response = (JsonRpcResponse) value;
26 | if (response.Error is JsonRpcError err) {
27 | return new JsonObject () {
28 | [ "jsonrpc" ] = "2.0",
29 | [ "error" ] = JsonValue.Serialize ( err ),
30 | [ "id" ] = response.Id
31 | };
32 | }
33 | else {
34 | return new JsonObject () {
35 | [ "jsonrpc" ] = "2.0",
36 | [ "result" ] = response.Result!.Value,
37 | [ "id" ] = response.Id
38 | };
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/extensions/Sisk.JsonRPC/Documentation/DocumentationDescriptor.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: DocumentationDescriptor.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Reflection;
11 | using Sisk.JsonRPC.Annotations;
12 |
13 | namespace Sisk.JsonRPC.Documentation;
14 |
15 | internal class DocumentationDescriptor {
16 | internal static JsonRpcDocumentation GetDocumentationDescriptor ( JsonRpcHandler handler, JsonRpcDocumentationMetadata? metadata ) {
17 |
18 | List methods = new List ();
19 |
20 | foreach (var method in handler.Methods.methods) {
21 | var methodDocs = method.Value.Method.GetCustomAttribute ();
22 | var paramsDocs = method.Value.Method.GetCustomAttributes ();
23 |
24 | methods.Add ( new JsonRpcDocumentationMethod (
25 | methodName: method.Key,
26 | category: methodDocs?.Category,
27 | description: methodDocs?.Description,
28 | returnType: method.Value.Method.ReturnType,
29 | parameters: method.Value.Method.GetParameters ()
30 | .Select ( p => new JsonRpcDocumentationParameter (
31 | parameterName: p.Name!,
32 | parameterType: p.ParameterType,
33 | description: paramsDocs.FirstOrDefault ( f => f.ParameterName == p.Name )?.Description,
34 | isOptional: p.IsOptional
35 | ) )
36 | .ToArray () ) );
37 | }
38 |
39 | return new JsonRpcDocumentation ( methods.OrderBy ( m => m.MethodName ).ToArray (), metadata );
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/extensions/Sisk.JsonRPC/Documentation/IJsonRpcDocumentationExporter.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: IJsonRpcDocumentationExporter.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.JsonRPC.Documentation;
11 |
12 | ///
13 | /// Defines a method to export JSON-RPC documentation to a byte array.
14 | ///
15 | public interface IJsonRpcDocumentationExporter {
16 |
17 | ///
18 | /// Exports the JSON-RPC documentation to a byte array.
19 | ///
20 | /// The JSON-RPC documentation to export.
21 | /// A byte array containing the exported documentation.
22 | public byte [] ExportDocumentBytes ( JsonRpcDocumentation documentation );
23 | }
24 |
--------------------------------------------------------------------------------
/extensions/Sisk.JsonRPC/Documentation/JsonRpcJsonExport.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: JsonRpcJsonExport.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Text;
11 | using LightJson;
12 |
13 | namespace Sisk.JsonRPC.Documentation;
14 |
15 | ///
16 | /// Provides an JSON-based .
17 | ///
18 | public sealed class JsonRpcJsonExport : IJsonRpcDocumentationExporter {
19 |
20 | ///
21 | /// The instance used to encode the documentation.
22 | ///
23 | public JsonOptions JsonOptions { get; set; }
24 |
25 | ///
26 | /// Creates an new instance with default parameters.
27 | ///
28 | public JsonRpcJsonExport () {
29 | JsonOptions = new JsonOptions () { NamingPolicy = System.Text.Json.JsonNamingPolicy.CamelCase };
30 | }
31 |
32 | ///
33 | /// Creates an new instance with the provided
34 | /// instance.
35 | ///
36 | public JsonRpcJsonExport ( JsonOptions options ) {
37 | JsonOptions = options;
38 | }
39 |
40 | ///
41 | /// Encodes the specified documentation into an .
42 | ///
43 | /// The JSON-RPC documentation to encode.
44 | ///
45 | public JsonValue EncodeDocumentation ( JsonRpcDocumentation documentation ) {
46 | JsonArray arr = JsonOptions.CreateJsonArray ();
47 |
48 | static string GetTypeName ( Type type ) {
49 | if (type.IsGenericType) {
50 | string genericDefinition = string.Join ( ", ", type.GetGenericArguments ().Select ( s => s.Name ) );
51 | return $"{type.Name}<{genericDefinition}>";
52 | }
53 | else {
54 | return type.Name;
55 | }
56 | }
57 |
58 | foreach (var method in documentation.Methods) {
59 |
60 | var item = new {
61 | Name = method.MethodName,
62 | Description = method.Description,
63 | Returns = GetTypeName ( method.ReturnType ),
64 | Parameters = method.Parameters
65 | .Select ( p => new {
66 | Name = p.ParameterName,
67 | TypeName = GetTypeName ( p.ParameterType ),
68 | Description = p.Description,
69 | IsOptional = p.IsOptional
70 | } )
71 | .ToArray ()
72 | };
73 |
74 | arr.Add ( JsonValue.Serialize ( item, JsonOptions ) );
75 | }
76 |
77 | return JsonOptions.Serialize ( new {
78 | Metadata = Pipe ( documentation.Metadata, m => new {
79 | m!.ApplicationName,
80 | m.ApplicationDescription,
81 | m.ServicePath,
82 | m.AllowedMethods
83 | } ),
84 | Methods = arr
85 | } );
86 | }
87 |
88 | ///
89 | public byte [] ExportDocumentBytes ( JsonRpcDocumentation documentation ) {
90 | string json = EncodeDocumentation ( documentation ).ToString ();
91 | return Encoding.UTF8.GetBytes ( json );
92 | }
93 |
94 | U? Pipe ( T value, Func transform ) {
95 | if (value == null)
96 | return default;
97 | return transform ( value );
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/extensions/Sisk.JsonRPC/JsonErrorCode.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: JsonErrorCode.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.JsonRPC;
11 |
12 | internal class JsonErrorCode {
13 | public const int InvalidRequest = -32600;
14 | public const int MethodNotFound = -32601;
15 | public const int InvalidParams = -32602;
16 | public const int InternalError = -32603;
17 | public const int ParseError = -32700;
18 | }
19 |
--------------------------------------------------------------------------------
/extensions/Sisk.JsonRPC/JsonRpcError.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: JsonRpcError.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using LightJson;
11 |
12 | namespace Sisk.JsonRPC;
13 |
14 | ///
15 | /// Represents an JSON-RPC error.
16 | ///
17 | public readonly struct JsonRpcError {
18 | ///
19 | /// Gets the JSON-RPC error code.
20 | ///
21 | public int Code { get; }
22 |
23 | ///
24 | /// Gets the JSON-RPC error message.
25 | ///
26 | public string Message { get; }
27 |
28 | ///
29 | /// Gets the JSON-RPC error additional data.
30 | ///
31 | public JsonValue Data { get; }
32 |
33 | ///
34 | /// Creates an new instance of the structure.
35 | ///
36 | public JsonRpcError () {
37 | Code = -32603;
38 | Message = "An exception was thrown.";
39 | Data = JsonValue.Null;
40 | }
41 |
42 | ///
43 | /// Creates an new instance of the structure with given
44 | /// parameters.
45 | ///
46 | /// The JSON-RPC error code.
47 | /// The JSON-RPC error message.
48 | public JsonRpcError ( int code, string message ) {
49 | Code = code;
50 | Message = message;
51 | Data = JsonValue.Null;
52 | }
53 |
54 | ///
55 | /// Creates an new instance of the structure with given
56 | /// parameters.
57 | ///
58 | /// The JSON-RPC error code.
59 | /// The JSON-RPC error message.
60 | /// The JSON-RPC error additional data.
61 | public JsonRpcError ( int code, string message, JsonValue data ) {
62 | Code = code;
63 | Message = message;
64 | Data = data;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/extensions/Sisk.JsonRPC/JsonRpcException.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: JsonRpcException.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using LightJson;
11 |
12 | namespace Sisk.JsonRPC;
13 |
14 | ///
15 | /// Represents an error that occur during the JSON-RPC application
16 | /// execution.
17 | ///
18 | public class JsonRpcException : Exception {
19 | ///
20 | /// Gets the error code associated with the JSON-RPC error.
21 | ///
22 | public int Code { get; }
23 |
24 | ///
25 | /// Gets additional data associated with the error, if any.
26 | ///
27 | public new object? Data { get; }
28 |
29 | ///
30 | /// Initializes a new instance of the class
31 | /// with a specified error message.
32 | ///
33 | /// The error message that explains the reason for the exception.
34 | public JsonRpcException ( string message ) : base ( message ) {
35 | Code = 1;
36 | Data = null;
37 | }
38 |
39 | ///
40 | /// Initializes a new instance of the class
41 | /// with a specified error message, error code, and additional data.
42 | ///
43 | /// The error message that explains the reason for the exception.
44 | /// The error code associated with the JSON-RPC error.
45 | /// Additional data associated with the error.
46 | public JsonRpcException ( string message, int code, object? data ) : base ( message ) {
47 | Code = code;
48 | Data = data;
49 | }
50 |
51 | ///
52 | /// Converts the current into a .
53 | ///
54 | /// A representing the error details.
55 | public JsonRpcError AsRpcError () {
56 | return new JsonRpcError ( Code, Message, JsonValue.Serialize ( Data ) );
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/extensions/Sisk.JsonRPC/JsonRpcHandler.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: JsonRpcHandler.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using LightJson;
11 | using Sisk.Core.Http;
12 | using Sisk.JsonRPC.Converters;
13 | using Sisk.JsonRPC.Documentation;
14 |
15 | namespace Sisk.JsonRPC;
16 |
17 | ///
18 | /// Represents a handler for JSON-RPC requests.
19 | ///
20 | public sealed class JsonRpcHandler {
21 | internal readonly JsonOptions _jsonOptions;
22 | internal readonly HttpServer _server;
23 | readonly JsonRpcMethodCollection _methodCollection;
24 | readonly JsonRpcTransportLayer _transport;
25 |
26 | ///
27 | /// Gets the transport layer used for communication.
28 | ///
29 | public JsonRpcTransportLayer Transport { get => _transport; }
30 |
31 | ///
32 | /// Gets the collection of JSON-RPC methods available in this handler.
33 | ///
34 | public JsonRpcMethodCollection Methods { get => _methodCollection; }
35 |
36 | ///
37 | /// Gets the JSON serializer options used for serialization and deserialization.
38 | ///
39 | public JsonOptions JsonSerializerOptions { get => _jsonOptions; }
40 |
41 | ///
42 | /// Initializes a new instance of the class.
43 | ///
44 | /// Defines the where the JSON-RPC instance will run on.
45 | public JsonRpcHandler ( HttpServer parentServer ) {
46 | _transport = new JsonRpcTransportLayer ( this );
47 | _jsonOptions = new JsonOptions ();
48 | _methodCollection = new JsonRpcMethodCollection ();
49 | _server = parentServer;
50 |
51 | _jsonOptions.PropertyNameComparer = new JsonSanitizedComparer ();
52 | _jsonOptions.Converters.Add ( new JsonRpcErrorConverter () );
53 | _jsonOptions.Converters.Add ( new JsonRpcRequestConverter () );
54 | _jsonOptions.Converters.Add ( new JsonRpcResponseConverter () );
55 | }
56 |
57 | ///
58 | /// Gets the documentation for this JSON-RPC handler.
59 | ///
60 | public JsonRpcDocumentation GetDocumentation () => GetDocumentation ( null! );
61 |
62 | ///
63 | /// Gets the documentation for this JSON-RPC handler.
64 | ///
65 | /// The to generate in the documentation.
66 | public JsonRpcDocumentation GetDocumentation ( JsonRpcDocumentationMetadata metadata ) {
67 | return DocumentationDescriptor.GetDocumentationDescriptor ( this, metadata );
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/extensions/Sisk.JsonRPC/JsonRpcRequest.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: JsonRpcRequest.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using LightJson;
11 |
12 | namespace Sisk.JsonRPC;
13 |
14 | ///
15 | /// Represents an JSON-RPC request message.
16 | ///
17 | public sealed class JsonRpcRequest {
18 | ///
19 | /// Gets the version used in the JSON-RPC message.
20 | ///
21 | public string Version { get; }
22 |
23 | ///
24 | /// Gets the method name of the JSON-RPC message.
25 | ///
26 | public string Method { get; }
27 |
28 | ///
29 | /// Gets the containing the message parameter values.
30 | ///
31 | public JsonValue Parameters { get; }
32 |
33 | ///
34 | /// Gets the ID of the JSON-RPC message.
35 | ///
36 | public JsonValue Id { get; }
37 |
38 | internal JsonRpcRequest ( string method, JsonValue parameters, string id ) {
39 | Version = "2.0";
40 | Method = method;
41 | Parameters = parameters;
42 | Id = id;
43 |
44 | if (string.IsNullOrEmpty ( Method ))
45 | throw new JsonRpcException ( "The JSON-RPC request Method cannot be null or an empty string." );
46 | if (Parameters.Type is not JsonValueType.Array &&
47 | Parameters.Type is not JsonValueType.Object) {
48 | throw new JsonRpcException ( "The JSON-RPC request parameters must be an array or an object." );
49 | }
50 | }
51 |
52 | internal JsonRpcRequest ( JsonObject rpcMessage ) {
53 | Version = rpcMessage [ "jsonrpc" ].GetString ();
54 | Method = rpcMessage [ "Method" ].GetString ();
55 | Parameters = rpcMessage [ "params" ];
56 | Id = rpcMessage [ "id" ];
57 |
58 | if (Id.Type != JsonValueType.String && Id.Type != JsonValueType.Number && Id.Type != JsonValueType.Null && Id.Type != JsonValueType.Undefined) {
59 | throw new JsonRpcException ( "The JSON-RPC request id must be an string, number or null." );
60 | }
61 |
62 | if (Version != "2.0")
63 | throw new JsonRpcException ( "The JSON-RPC request version must be \"2.0\"." );
64 | if (string.IsNullOrEmpty ( Method ))
65 | throw new JsonRpcException ( "The JSON-RPC request Method cannot be null or an empty string." );
66 | if (Parameters.Type is not JsonValueType.Array &&
67 | Parameters.Type is not JsonValueType.Object) {
68 | throw new JsonRpcException ( "The JSON-RPC request parameters must be an array or an object." );
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/extensions/Sisk.JsonRPC/JsonRpcResponse.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: JsonRpcResponse.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using LightJson;
11 |
12 | namespace Sisk.JsonRPC;
13 |
14 | ///
15 | /// Represents an JSON-RPC response message.
16 | ///
17 | public sealed class JsonRpcResponse {
18 | ///
19 | /// Gets the JSON-RPC response version. This property will always return "2.0".
20 | ///
21 | public string Version { get; } = "2.0";
22 |
23 | ///
24 | /// Gets the JSON-RPC response result.
25 | ///
26 | public JsonValue? Result { get; }
27 |
28 | ///
29 | /// Gets the JSON-RPC response error.
30 | ///
31 | public JsonRpcError? Error { get; }
32 |
33 | ///
34 | /// Gets the JSON-RPC response id.
35 | ///
36 | public JsonValue Id { get; }
37 |
38 | internal JsonRpcResponse ( JsonValue? result, JsonRpcError? error, JsonValue id ) {
39 | Result = result;
40 | Error = error;
41 | if (id.Type == JsonValueType.Undefined) {
42 | Id = JsonValue.Null;
43 | }
44 | else {
45 | Id = id;
46 | }
47 | }
48 |
49 | ///
50 | /// Creates an new success with given parameters.
51 | ///
52 | /// The JSON-RPC response id.
53 | /// The JSON-RPC response object.
54 | public static JsonRpcResponse CreateSuccessResponse ( JsonValue id, JsonValue result ) {
55 | return new JsonRpcResponse ( result, null, id );
56 | }
57 |
58 | ///
59 | /// Creates an new error with given parameters.
60 | ///
61 | /// The JSON-RPC response id.
62 | /// The JSON-RPC response error.
63 | public static JsonRpcResponse CreateErrorResponse ( JsonValue id, JsonRpcError error ) {
64 | return new JsonRpcResponse ( null, error, id );
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/extensions/Sisk.JsonRPC/JsonRpcServerHandler.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: JsonRpcServerHandler.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using Sisk.Core.Http;
11 | using Sisk.Core.Http.Handlers;
12 | using Sisk.Core.Routing;
13 |
14 | namespace Sisk.JsonRPC;
15 |
16 | ///
17 | /// Provides an for configuring the JSON-RPC handler
18 | /// for the HTTP server.
19 | ///
20 | public sealed class JsonRpcServerHandler : HttpServerHandler {
21 | private JsonRpcHandler? _handler;
22 |
23 | ///
24 | /// Gets or sets the action which will be called in the configuring
25 | /// with this handler.
26 | ///
27 | public event EventHandler? ConfigureAction;
28 |
29 | ///
30 | /// Creates an new instance of the class.
31 | ///
32 | public JsonRpcServerHandler () {
33 | }
34 |
35 | ///
36 | protected override void OnServerStarting ( HttpServer server ) {
37 | _handler = new JsonRpcHandler ( server );
38 | }
39 |
40 | ///
41 | protected override void OnSetupRouter ( Router router ) {
42 | base.OnSetupRouter ( router );
43 | if (ConfigureAction != null && _handler is not null)
44 | ConfigureAction ( this, new JsonRpcServerConfigurationEventArgs ( router, _handler ) );
45 | }
46 | }
47 |
48 | ///
49 | /// Represents the class which contains event data for the JSON-RPC configuration event.
50 | ///
51 | public sealed class JsonRpcServerConfigurationEventArgs : EventArgs {
52 | ///
53 | /// Gets the target which are being configured.
54 | ///
55 | public Router Router { get; }
56 |
57 | ///
58 | /// Gets the configuring .
59 | ///
60 | public JsonRpcHandler Handler { get; }
61 |
62 | internal JsonRpcServerConfigurationEventArgs ( Router router, JsonRpcHandler handler ) {
63 | Router = router;
64 | Handler = handler;
65 | }
66 | }
--------------------------------------------------------------------------------
/extensions/Sisk.JsonRPC/JsonRpcServerHandlerExtensions.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: JsonRpcServerHandlerExtensions.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using Sisk.Core.Http.Hosting;
11 |
12 | namespace Sisk.JsonRPC;
13 |
14 | ///
15 | /// Provides extensions methods for the HTTP server and JSON-RPC handler.
16 | ///
17 | public static class JsonRpcServerHandlerExtensions {
18 | ///
19 | /// Enables JSON-RPC in this HTTP server.
20 | ///
21 | /// The self for fluent chaining.
22 | /// The event handler callback that is called to configure routes and web methods for the JSON-RPC.
23 | public static HttpServerHostContextBuilder UseJsonRPC ( this HttpServerHostContextBuilder builder, EventHandler configure ) {
24 | JsonRpcServerHandler serverHandler = new JsonRpcServerHandler ();
25 | serverHandler.ConfigureAction += configure;
26 |
27 | builder.UseHandler ( serverHandler );
28 | return builder;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/extensions/Sisk.JsonRPC/RpcDelegate.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: RpcDelegate.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Reflection;
11 |
12 | namespace Sisk.JsonRPC;
13 |
14 | internal record class RpcDelegate ( string WebMethodName, MethodInfo Method, RpcDelegateMethodParameter [] Parameters, RpcDelegateMethodReturnInformation ReturnInformation, object? Target );
15 | internal record class RpcDelegateMethodParameter ( Type ParameterType, string? Name, bool IsOptional, object? DefaultValue );
16 | internal record class RpcDelegateMethodReturnInformation ( Type ReturnType, bool IsAsyncEnumerable, bool IsAsyncTask );
--------------------------------------------------------------------------------
/extensions/Sisk.JsonRPC/Sisk.JsonRPC.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | enable
6 | enable
7 | True
8 | True
9 |
10 | True
11 | true
12 |
13 | Sisk.JsonRpc
14 | Sisk.JsonRpc
15 |
16 | CypherPotato
17 | Project Principium
18 | Sisk.JsonRpc
19 | This package provides an JSON-RPC 2.0 interface for Sisk projects.
20 | https://sisk.proj.pw/
21 | Icon.png
22 | README.md
23 | https://github.com/sisk-http/core
24 | http-server,http,web framework
25 | git
26 |
27 | 1.4.1
28 | 1.4.1
29 | 1.4.1
30 |
31 | en
32 | LICENSE.txt
33 | True
34 |
35 |
36 |
37 | true
38 |
39 |
40 | $(NoWarn);SYSLIB0020
41 |
42 |
43 |
44 |
45 | True
46 | \
47 |
48 |
49 | True
50 | \
51 |
52 |
53 | True
54 | \
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/extensions/Sisk.ServiceProvider/.editorconfig:
--------------------------------------------------------------------------------
1 | [*.cs]
2 | file_header_template = The Sisk Framework source code\nCopyright (c) 2023 PROJECT PRINCIPIUM\n\nThe code below is licensed under the MIT license as\nof the date of its publication, available at\n\nFile name: {fileName}\nRepository: https://github.com/sisk-http/core
--------------------------------------------------------------------------------
/extensions/Sisk.ServiceProvider/RequestHandlerFactory.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2023 PROJECT PRINCIPIUM
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: RequestHandlerFactory.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Collections.Specialized;
11 |
12 | namespace Sisk.Core.Routing
13 | {
14 | ///
15 | /// Provides a class that instantiates request handlers.
16 | ///
17 | ///
18 | /// public abstract class RequestHandlerFactory
19 | ///
20 | ///
21 | /// Class
22 | ///
23 | ///
24 | /// Sisk.Core.Routing.Handlers
25 | ///
26 | public abstract class RequestHandlerFactory
27 | {
28 | ///
29 | /// Builds and gets the instance objects used later by an .
30 | ///
31 | ///
32 | /// public abstract IRequestHandler[] BuildRequestHandlers();
33 | ///
34 | ///
35 | /// Method
36 | ///
37 | ///
38 | /// Sisk.Core.Routing.Handlers
39 | ///
40 | public abstract IRequestHandler[] BuildRequestHandlers();
41 |
42 | ///
43 | /// Method that is called by the Agirax instantiator with the parameters defined in configuration before calling .
44 | ///
45 | /// Parameters that are defined in a configuration file.
46 | ///
47 | /// public abstract void Setup(NameValueCollection setupParameters);
48 | ///
49 | ///
50 | /// Method
51 | ///
52 | ///
53 | /// Sisk.Core.Routing.Handlers
54 | ///
55 | public abstract void Setup(NameValueCollection setupParameters);
56 | }
57 | }
--------------------------------------------------------------------------------
/extensions/Sisk.ServiceProvider/RouterFactory.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2023 PROJECT PRINCIPIUM
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: RouterFactory.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using Sisk.Core.Http;
11 | using System.Collections.Specialized;
12 |
13 | namespace Sisk.Core.Routing
14 | {
15 | ///
16 | /// Provides a class that instantiates a router, capable of porting applications for use with Agirax.
17 | ///
18 | ///
19 | /// public abstract class RouterFactory
20 | ///
21 | ///
22 | /// Class
23 | ///
24 | ///
25 | /// Sisk.Core.Routing
26 | ///
27 | public abstract class RouterFactory
28 | {
29 | ///
30 | /// Build and gets a router that will be used later by an .
31 | ///
32 | ///
33 | /// public abstract Router BuildRouter();
34 | ///
35 | ///
36 | /// Method
37 | ///
38 | ///
39 | /// Sisk.Core.Routing
40 | ///
41 | public abstract Router BuildRouter();
42 |
43 | ///
44 | /// Method that is called by the service instantiator with the parameters defined in configuration before calling .
45 | ///
46 | /// Parameters that are defined in a configuration file.
47 | ///
48 | /// public abstract void Setup(NameValueCollection setupParameters);
49 | ///
50 | ///
51 | /// Method
52 | ///
53 | ///
54 | /// Sisk.Core.Routing
55 | ///
56 | public abstract void Setup(NameValueCollection setupParameters);
57 |
58 | ///
59 | /// Method that is called immediately before initializing the service, after all configurations was parsed and set up.
60 | ///
61 | ///
62 | /// public abstract void Bootstrap();
63 | ///
64 | ///
65 | /// Method
66 | ///
67 | public abstract void Bootstrap();
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/extensions/Sisk.ServiceProvider/Sisk.ServiceProvider.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0;net7.0
5 | enable
6 | enable
7 | True
8 | True
9 | Sisk.ServiceProvider
10 | Sisk.ServiceProvider
11 | CypherPotato
12 | Project Principium
13 | Sisk.ServiceProvider
14 | This package includes tools for easily porting your Sisk service.
15 | https://sisk.proj.pw/
16 | Icon.png
17 | README.md
18 | https://github.com/sisk-http/core
19 | http-server,http,web framework
20 | git
21 |
22 | 0.15.0.47
23 | 0.15.0.47
24 | 0.15.0.47
25 |
26 | en
27 | LICENSE.txt
28 | True
29 |
30 |
31 |
32 |
33 | True
34 | \
35 |
36 |
37 | True
38 | \
39 |
40 |
41 | True
42 | \
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/extensions/Sisk.SslProxy/DnsUtil.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: DnsUtil.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Net;
11 | using System.Net.Sockets;
12 | using Sisk.Core.Http;
13 |
14 | namespace Sisk.Ssl;
15 |
16 | static class DnsUtil {
17 | public static IPEndPoint ResolveEndpoint ( ListeningPort port, bool onlyUseIPv4 = false ) {
18 | var hostEntry = Dns.GetHostEntry ( port.Hostname );
19 |
20 | if (hostEntry.AddressList.Length == 0)
21 | throw new InvalidOperationException ( $"Couldn't resolve any IP addresses for {port}." );
22 |
23 | IPAddress? resolvedAddress;
24 |
25 | if (onlyUseIPv4) {
26 | resolvedAddress =
27 | // only resolves IPv4
28 | hostEntry.AddressList.LastOrDefault ( a => a.AddressFamily == AddressFamily.InterNetwork );
29 | }
30 | else {
31 | resolvedAddress =
32 | // try to return the last IPv6 or IPv4
33 | hostEntry.AddressList.LastOrDefault ( a => a.AddressFamily == AddressFamily.InterNetwork || a.AddressFamily == AddressFamily.InterNetworkV6 );
34 | }
35 |
36 | if (resolvedAddress is null)
37 | throw new InvalidOperationException ( $"Couldn't resolve any IP addresses for {port}." );
38 |
39 | return new IPEndPoint ( resolvedAddress, port.Port );
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/extensions/Sisk.SslProxy/ProxyGateway.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: ProxyGateway.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Net;
11 |
12 | namespace Sisk.Ssl;
13 |
14 | class ProxyGateway : IDisposable {
15 | HttpClient client;
16 |
17 | public IPEndPoint GatewayEndpoint { get; }
18 |
19 | public ProxyGateway ( IPEndPoint endpoint ) {
20 | var httpHandler = new HttpClientHandler () {
21 | AllowAutoRedirect = false,
22 | AutomaticDecompression = DecompressionMethods.None,
23 | ServerCertificateCustomValidationCallback = ( message, cert, chain, errors ) => {
24 | return true;
25 | },
26 | };
27 |
28 | client = new HttpClient ( httpHandler );
29 | GatewayEndpoint = endpoint;
30 | }
31 |
32 | public Task SendMessageAsync ( HttpRequestMessage requestMessage, CancellationToken cancellationToken = default ) {
33 | return client.SendAsync ( requestMessage, HttpCompletionOption.ResponseHeadersRead, cancellationToken );
34 | }
35 |
36 | public void Dispose () {
37 | client.Dispose ();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/extensions/Sisk.SslProxy/Sisk.SslProxy.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0;net9.0
5 | enable
6 | enable
7 | True
8 | True
9 |
10 | Sisk.SslProxy
11 | Sisk.SslProxy
12 | Sisk.Ssl
13 |
14 | CypherPotato
15 | Project Principium
16 | Sisk.SslProxy
17 | This package provides an experimental SSL proxy for the Sisk Framework and other .NET projects.
18 | https://sisk.proj.pw/
19 | Icon.png
20 | README.md
21 | https://github.com/sisk-http/core
22 | http-server,http,web framework
23 | git
24 |
25 | 1.4.1.1-alpha10
26 | 1.4.1
27 | 1.4.1
28 |
29 | en
30 | LICENSE.txt
31 | True
32 |
33 |
34 |
35 | true
36 |
37 |
38 | $(NoWarn);SYSLIB0020
39 |
40 |
41 |
42 | $(DefineConstants)
43 |
44 |
45 |
46 | $(DefineConstants);VERBOSE
47 |
48 |
49 |
50 |
51 | True
52 | \
53 |
54 |
55 | True
56 | \
57 |
58 |
59 | True
60 | \
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/extensions/Sisk.SslProxy/SslProxyServerHandler.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: SslProxyServerHandler.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using Sisk.Core.Http;
11 | using Sisk.Core.Http.Handlers;
12 |
13 | namespace Sisk.Ssl;
14 |
15 | ///
16 | /// Provides event handlers and hooks for .
17 | ///
18 | public sealed class SslProxyServerHandler : HttpServerHandler {
19 | ///
20 | /// Gets the instance used in this server handler.
21 | ///
22 | public SslProxy SecureProxy { get; }
23 |
24 | ///
25 | /// Creates an new instance with the
26 | /// specified instance.
27 | ///
28 | /// The instance.
29 | public SslProxyServerHandler ( SslProxy secureProxy ) {
30 | SecureProxy = secureProxy;
31 | }
32 |
33 | ///
34 | ///
35 | protected override void OnServerStarted ( HttpServer server ) {
36 | SecureProxy.Start ();
37 | }
38 |
39 | ///
40 | ///
41 | protected override void OnServerStopping ( HttpServer server ) {
42 | SecureProxy.Dispose ();
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/Entity/CircularBuffer.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: CircularBuffer.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Collections;
11 |
12 | namespace Sisk.Core.Entity;
13 |
14 | ///
15 | /// Represents an thread-safe, fixed-capacity circular buffer that stores elements of .
16 | ///
17 | /// The type of elements stored in the buffer.
18 | ///
19 | public sealed class CircularBuffer : IEnumerable, IReadOnlyList {
20 | private T [] items;
21 |
22 | int capacity,
23 | addedItems;
24 |
25 | ///
26 | /// Creates an new instance of the with the specified
27 | /// capacity.
28 | ///
29 | /// The circular buffer capacity.
30 | public CircularBuffer ( int capacity ) {
31 | ArgumentOutOfRangeException.ThrowIfNegativeOrZero ( capacity );
32 |
33 | this.capacity = capacity;
34 | items = new T [ capacity ];
35 | }
36 |
37 | ///
38 | /// Adds an object of into the beginning of the circular buffer and pushes
39 | /// old items to end.
40 | ///
41 | /// The item to add.
42 | public void Add ( T item ) {
43 | lock (items) {
44 | for (int i = capacity - 1; i > 0; i--) {
45 | items [ i ] = items [ i - 1 ];
46 | }
47 |
48 | addedItems = Math.Min ( Capacity, addedItems + 1 );
49 | items [ 0 ] = item;
50 | }
51 | }
52 |
53 | ///
54 | /// Clears the circular buffer contents and recreates the array.
55 | ///
56 | public void Clear () {
57 | items = new T [ capacity ];
58 | addedItems = 0;
59 | }
60 |
61 | ///
62 | /// Changes the capacity of elements in this circular buffer to the specified new size.
63 | ///
64 | /// The new size for this circular buffer.
65 | public void Resize ( int capacity ) {
66 | ArgumentOutOfRangeException.ThrowIfNegativeOrZero ( capacity );
67 |
68 | Array.Resize ( ref items, capacity );
69 | this.capacity = capacity;
70 | }
71 |
72 | ///
73 | /// Returns an array representation of this items in their defined
74 | /// positions within the capacity.
75 | ///
76 | public T [] ToArray () => items;
77 |
78 | ///
79 | /// Creates an new over the circular buffer.
80 | ///
81 | public ReadOnlySpan ToSpan () => new ReadOnlySpan ( items );
82 |
83 | ///
84 | /// Gets the current capacity of this .
85 | ///
86 | public int Capacity { get => capacity; }
87 |
88 | ///
89 | /// Gets the amount of added items in this circular buffer.
90 | ///
91 | public int Count => addedItems;
92 |
93 | ///
94 | public T this [ int index ] => items [ index ];
95 |
96 | ///
97 | ///
98 | public IEnumerator GetEnumerator () {
99 | return ((IEnumerable) items).GetEnumerator ();
100 | }
101 |
102 | ///
103 | ///
104 | IEnumerator IEnumerable.GetEnumerator () {
105 | return items.GetEnumerator ();
106 | }
107 | }
--------------------------------------------------------------------------------
/src/Entity/MultipartObjectCommonFormat.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: MultipartObjectCommonFormat.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.Core.Entity;
11 |
12 | ///
13 | /// Represents an image format for Multipart objects.
14 | ///
15 | public enum MultipartObjectCommonFormat {
16 | ///
17 | /// Represents that the object is not a recognized image.
18 | ///
19 | Unknown = 0,
20 |
21 | ///
22 | /// Represents an JPEG/JPG image.
23 | ///
24 | JPEG = 100,
25 |
26 | ///
27 | /// Represents an GIF image.
28 | ///
29 | GIF = 101,
30 |
31 | ///
32 | /// Represents an PNG image.
33 | ///
34 | PNG = 102,
35 |
36 | ///
37 | /// Represents an TIFF image.
38 | ///
39 | TIFF = 103,
40 |
41 | ///
42 | /// Represents an bitmap image.
43 | ///
44 | BMP = 104,
45 |
46 | ///
47 | /// Represents an WebP image.
48 | ///
49 | WEBP = 105,
50 |
51 | ///
52 | /// Represents an PDF file.
53 | ///
54 | PDF = 200
55 | }
56 |
--------------------------------------------------------------------------------
/src/Entity/MultipartObjectCommonFormatByteMark.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: MultipartObjectCommonFormatByteMark.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.Core.Entity;
11 |
12 | static class MultipartObjectCommonFormatByteMark {
13 | public static readonly byte [] PNG = [ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A ];
14 |
15 | public static readonly byte [] PDF = [ 0x25, 0x50, 0x44, 0x46 ];
16 | public static readonly byte [] WEBP = [ 0x52, 0x49, 0x46, 0x46 ];
17 | public static readonly byte [] TIFF = [ 0x4D, 0x4D, 0x00, 0x2A ];
18 | public static readonly byte [] WEBM = [ 0x1A, 0x45, 0xDF, 0xA3 ];
19 |
20 | public static readonly byte [] JPEG = [ 0xFF, 0xD8, 0xFF ];
21 | public static readonly byte [] GIF = [ 0x47, 0x46, 0x49 ];
22 |
23 | public static readonly byte [] BMP = [ 0x42, 0x4D ];
24 | }
25 |
--------------------------------------------------------------------------------
/src/GlobalSuppressions.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: GlobalSuppressions.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Diagnostics.CodeAnalysis;
11 |
12 | [assembly: SuppressMessage ( "Usage", "CA2225:Operator overloads have named alternates", Scope = "member", Target = "~M:Sisk.Core.Http.HttpStatusInformation.op_Implicit(System.Net.HttpStatusCode)~Sisk.Core.Http.HttpStatusInformation" )]
13 | [assembly: SuppressMessage ( "Usage", "CA2225:Operator overloads have named alternates", Scope = "member", Target = "~M:Sisk.Core.Http.HttpStatusInformation.op_Implicit(System.Int32)~Sisk.Core.Http.HttpStatusInformation" )]
--------------------------------------------------------------------------------
/src/Helpers/CookieHelper.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: CookieHelper.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Net;
11 | using System.Web;
12 | using Sisk.Core.Internal;
13 |
14 | namespace Sisk.Core.Helpers;
15 |
16 | ///
17 | /// Provides a class that contains useful methods for working with cookies in HTTP responses.
18 | ///
19 | public static class CookieHelper {
20 | ///
21 | /// Builds the cookie header value and returns an string from it.
22 | ///
23 | /// The instance to build the cookie string.
24 | public static string BuildCookieHeaderValue ( Cookie cookie ) {
25 | return BuildCookieHeaderValue (
26 | name: cookie.Name,
27 | value: cookie.Value,
28 | expires: cookie.Expires,
29 | domain: cookie.Domain,
30 | path: cookie.Path,
31 | secure: cookie.Secure,
32 | httpOnly: cookie.HttpOnly
33 | );
34 | }
35 |
36 | ///
37 | /// Builds the cookie header value and returns an string from it.
38 | ///
39 | /// The cookie name.
40 | /// The cookie value.
41 | /// The cookie expirity date.
42 | /// The cookie max duration after being set.
43 | /// The domain where the cookie will be valid.
44 | /// The path where the cookie will be valid.
45 | /// Determines if the cookie will only be stored in an secure context.
46 | /// Determines if the cookie will be only available in the HTTP context.
47 | /// The cookie SameSite parameter.
48 | public static string BuildCookieHeaderValue (
49 | string name,
50 | string value,
51 | DateTime? expires = null,
52 | TimeSpan? maxAge = null,
53 | string? domain = null,
54 | string? path = null,
55 | bool? secure = null,
56 | bool? httpOnly = null,
57 | string? sameSite = null ) {
58 |
59 | List syntax = new List ();
60 | syntax.Add ( $"{HttpUtility.UrlEncode ( name )}={HttpUtility.UrlEncode ( value )}" );
61 |
62 | if (expires is not null) {
63 | syntax.Add ( $"Expires={expires.Value.ToUniversalTime ():r}" );
64 | }
65 | if (maxAge is not null) {
66 | syntax.Add ( $"Max-Age={maxAge.Value.TotalSeconds}" );
67 | }
68 | if (domain is not null) {
69 | string d = domain;
70 |
71 | d = d.RemoveStart ( "https://", StringComparison.OrdinalIgnoreCase );
72 | d = d.RemoveStart ( "http://", StringComparison.OrdinalIgnoreCase );
73 | d = d.TrimEnd ( '/' );
74 |
75 | syntax.Add ( $"Domain={d}" );
76 | }
77 | if (path is not null) {
78 | syntax.Add ( $"Path={path}" );
79 | }
80 | if (secure == true) {
81 | syntax.Add ( $"Secure" );
82 | }
83 | if (httpOnly == true) {
84 | syntax.Add ( $"HttpOnly" );
85 | }
86 | if (sameSite is not null) {
87 | syntax.Add ( $"SameSite={sameSite}" );
88 | }
89 |
90 | return string.Join ( "; ", syntax );
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/src/Helpers/HeaderHelper.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: HeaderHelper.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Net.Http.Headers;
11 |
12 | namespace Sisk.Core.Helpers;
13 |
14 | ///
15 | /// Provides helper methods for working with HTTP headers.
16 | ///
17 | public static class HeaderHelper {
18 |
19 | ///
20 | /// Copies HTTP headers from one instance to another.
21 | ///
22 | /// The source instance.
23 | /// The target instance.
24 | /// If set to , headers that are added will be validated (an exception can be throw if an header is invalid). If , invalid headers could be discarded, but no exception is thrown.
25 | public static void CopyHttpHeaders ( HttpContentHeaders from, HttpContentHeaders to, bool safe = true ) {
26 | foreach (var header in from) {
27 | if (safe) {
28 | to.Add ( header.Key, header.Value );
29 | }
30 | else {
31 | to.TryAddWithoutValidation ( header.Key, header.Value );
32 | }
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Helpers/MimeHelper.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: MimeHelper.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using Sisk.Core.Internal;
11 |
12 | namespace Sisk.Core.Helpers;
13 |
14 | ///
15 | /// Provides useful helper methods for resolving mime-types from common formats.
16 | ///
17 | public static class MimeHelper {
18 | static readonly int inlineContentTypesSize = MimeTypeList.InlineMimeTypes.Length;
19 |
20 | ///
21 | /// Gets or sets the default fallback mime-type.
22 | ///
23 | ///
24 | /// This property is not used by the HTTP server itself, only this helper class.
25 | ///
26 | public static string DefaultMimeType { get; set; } = "application/octet-stream";
27 |
28 | ///
29 | /// Gets the content mime-type from the specified file extension.
30 | ///
31 | /// The file extension, with or without the initial dot.
32 | /// Optional. The default mime-type when the file best mime-type is not found. If this argument is null, is used.
33 | /// The best matched mime-type, or the default if no mime-type was matched with the specified extension.
34 | public static string GetMimeType ( string fileExtension, string? fallback = null ) {
35 | return MimeTypeList.ResolveMimeType ( fileExtension.TrimStart ( '.' ).ToLowerInvariant () ) ?? fallback ?? DefaultMimeType;
36 | }
37 |
38 | ///
39 | /// Gets an boolean indicating if the specified file is an well-known plain text file.
40 | ///
41 | /// The file extension, with or without the initial dot.
42 | public static bool IsPlainTextFile ( string? fileExtension ) {
43 | if (fileExtension is null)
44 | return false;
45 | return PlainTextFileExtensions.IsTextFile ( fileExtension.TrimStart ( '.' ) );
46 | }
47 |
48 | ///
49 | /// Gets a value indicating whether the specified MIME type is a plain text MIME type.
50 | ///
51 | /// The MIME type to check.
52 | /// if the MIME type is a plain text MIME type; otherwise, .
53 | public static bool IsPlainTextMimeType ( string? mimeType ) {
54 | if (mimeType is null)
55 | return false;
56 | return
57 | mimeType.StartsWith ( "text/", StringComparison.OrdinalIgnoreCase ) ||
58 | mimeType.StartsWith ( "message/", StringComparison.OrdinalIgnoreCase ) ||
59 | PlainTextFileMimeTypes.PlainTextMimeTypes.Contains ( mimeType, StringComparer.OrdinalIgnoreCase );
60 | }
61 |
62 | ///
63 | /// Determines whether the specified mime-type is considered an inline content type
64 | /// that can be displayed directly in most browsers.
65 | ///
66 | /// The mime-type to evaluate.
67 | ///
68 | /// if the content type is an inline content type; otherwise, .
69 | ///
70 | public static bool IsBrowserKnownInlineMimeType ( string mimeType ) {
71 | for (int i = 0; i < inlineContentTypesSize; i++) {
72 | if (mimeType.Contains ( MimeTypeList.InlineMimeTypes [ i ], StringComparison.OrdinalIgnoreCase )) {
73 | return true;
74 | }
75 | }
76 | return false;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/Helpers/PathHelper.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: PathHelper.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using Sisk.Core.Internal;
11 |
12 | namespace Sisk.Core.Helpers;
13 |
14 | ///
15 | /// Provides useful path-dedicated helper members.
16 | ///
17 | public sealed class PathHelper {
18 | ///
19 | /// Combines the specified URL paths into one.
20 | ///
21 | /// The string array which contains parts that will be combined.
22 | public static string CombinePaths ( params string [] paths ) {
23 | return PathUtility.CombinePaths ( paths );
24 | }
25 |
26 | ///
27 | /// Normalizes and combines the specified file-system paths into one.
28 | ///
29 | /// Specifies if relative paths should be merged and ".." returns should be respected.
30 | /// Specifies the path separator character.
31 | /// Specifies the array of paths to combine.
32 | public static string FilesystemCombinePaths ( bool allowRelativeReturn, char separator, params string [] paths ) {
33 | return PathUtility.NormalizedCombine ( allowRelativeReturn, separator, paths );
34 | }
35 |
36 | ///
37 | /// Normalizes and combines the specified file-system paths into one.
38 | ///
39 | /// Specifies if relative paths should be merged and ".." returns should be respected.
40 | /// Specifies the path separator character.
41 | /// Specifies the array of paths to combine.
42 | public static string FilesystemCombinePaths ( bool allowRelativeReturn, char separator, ReadOnlySpan paths ) {
43 | return PathUtility.NormalizedCombine ( allowRelativeReturn, separator, paths );
44 | }
45 |
46 | ///
47 | /// Normalizes and combines the specified file-system paths into one, using the default environment directory separator char.
48 | ///
49 | /// Specifies the array of paths to combine.
50 | public static string FilesystemCombinePaths ( params string [] paths ) {
51 | return PathUtility.NormalizedCombine ( false, Path.DirectorySeparatorChar, paths );
52 | }
53 |
54 | private static readonly char [] pathNormalizationChars = new char [] { '/', '\\' };
55 |
56 | ///
57 | /// Normalize the given path to use the specified directory separator, trim the last separator and
58 | /// remove empty entries.
59 | ///
60 | /// The path to normalize.
61 | /// The directory separator.
62 | public static string NormalizePath ( string path, char directorySeparator = '/' ) {
63 | string [] parts = path.Split ( pathNormalizationChars, StringSplitOptions.RemoveEmptyEntries );
64 | string result = string.Join ( directorySeparator, parts );
65 | if (path.StartsWith ( '/' ) || path.StartsWith ( '\\' ))
66 | result = directorySeparator + result;
67 | return result;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/Helpers/SizeHelper.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: SizeHelper.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Runtime.CompilerServices;
11 |
12 | namespace Sisk.Core.Helpers;
13 |
14 | ///
15 | /// Provides useful size-dedicated helper members.
16 | ///
17 | public sealed class SizeHelper {
18 | ///
19 | /// Represents the number of bytes in one kibibyte (KiB).
20 | /// This is calculated as 1024 bytes.
21 | ///
22 | public const long UnitKb = 1024;
23 |
24 | ///
25 | /// Represents the number of bytes in one mebibyte (MiB).
26 | /// This is calculated as 1024 kibibytes.
27 | ///
28 | public const long UnitMb = 1_048_576;
29 |
30 | ///
31 | /// Represents the number of bytes in one gibibyte (GiB).
32 | /// This is calculated as 1024 mebibytes.
33 | ///
34 | public const long UnitGb = 1_073_741_824;
35 |
36 | ///
37 | /// Represents the number of bytes in one tebibyte (TiB).
38 | /// This is calculated as 1024 gibibytes.
39 | ///
40 | public const long UnitTb = 1_099_511_627_776;
41 |
42 | ///
43 | /// Represents the number of bytes in one pebibyte (PiB).
44 | /// This is calculated as 1024 tebibytes.
45 | ///
46 | public const long UnitPb = 1_125_899_906_842_624;
47 |
48 | ///
49 | /// Represents the number of bytes in one exibibyte (EiB).
50 | /// This is calculated as 1024 pebibytes.
51 | ///
52 | public const long UnitEb = 1_152_921_504_606_846_976;
53 |
54 | ///
55 | /// Converts a byte count into a human-readable string representation.
56 | ///
57 | /// The total number of bytes to convert.
58 | /// A string representing the byte count in a human-readable format.
59 | [MethodImpl ( MethodImplOptions.AggressiveInlining )]
60 | public static string HumanReadableSize ( long byteCount ) => HumanReadableSize ( (double) byteCount );
61 |
62 | ///
63 | /// Converts a byte count into a human-readable string representation.
64 | ///
65 | /// The total number of bytes to convert.
66 | /// A string representing the byte count in a human-readable format.
67 | [MethodImpl ( MethodImplOptions.AggressiveInlining )]
68 | public static string HumanReadableSize ( double byteCount ) {
69 | if (byteCount < UnitKb) {
70 | return $"{byteCount:n0} bytes";
71 | }
72 | else if (byteCount > UnitKb && byteCount <= UnitMb) {
73 | return $"{byteCount / UnitKb:n2} KB";
74 | }
75 | else if (byteCount > UnitMb && byteCount <= UnitGb) {
76 | return $"{byteCount / UnitMb:n2} MB";
77 | }
78 | else if (byteCount > UnitGb && byteCount <= UnitTb) {
79 | return $"{byteCount / UnitGb:n2} GB";
80 | }
81 | else if (byteCount > UnitTb && byteCount <= UnitPb) {
82 | return $"{byteCount / UnitTb:n2} TB";
83 | }
84 | else if (byteCount > UnitPb && byteCount <= UnitEb) {
85 | return $"{byteCount / UnitTb:n2} PB";
86 | }
87 | else {
88 | return $"{byteCount / UnitEb:n2} EB";
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/Http/BrotliContent.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: BrotliContent.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.IO.Compression;
11 | using Sisk.Core.Helpers;
12 |
13 | namespace Sisk.Core.Http;
14 |
15 | ///
16 | /// Represents an HTTP content that is compressed using the Brotli algorithm.
17 | ///
18 | public sealed class BrotliContent : CompressedContent {
19 |
20 | ///
21 | public BrotliContent ( HttpContent innerContent ) : base ( innerContent ) {
22 | }
23 |
24 | ///
25 | public BrotliContent ( byte [] byteArrayContent ) : base ( byteArrayContent ) {
26 | }
27 |
28 | ///
29 | public BrotliContent ( Stream baseContent ) : base ( baseContent ) {
30 | }
31 |
32 | ///
33 | public override Stream GetCompressingStream ( Stream outputStream ) {
34 | return new BrotliStream ( outputStream, CompressionMode.Compress, leaveOpen: true );
35 | }
36 |
37 | ///
38 | public override void Setup () {
39 | HeaderHelper.CopyHttpHeaders ( InnerContent.Headers, Headers );
40 | Headers.ContentEncoding.Add ( "br" );
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Http/DefaultMessagePage.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: DefaultMessagePage.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Web;
11 |
12 | namespace Sisk.Core.Http;
13 |
14 | ///
15 | /// Provides methods for creating informative static pages used by Sisk.
16 | ///
17 | public static class DefaultMessagePage {
18 | ///
19 | /// Gets or sets the page CSS string used by the page code.
20 | ///
21 | public static string DefaultPageCSS { get; set; } =
22 | """
23 | body {
24 | background-color: #eeeeee;
25 | font-family: sans-serif;
26 | }
27 |
28 | main {
29 | background-color: white;
30 | padding: 25px;
31 | border-radius: 10px;
32 | border: 1px solid #dddddd;
33 | display: block;
34 | margin: 30px auto 0 auto;
35 | max-width: 600px;
36 | }
37 |
38 | h1 {
39 | margin: 0;
40 | }
41 |
42 | hr {
43 | border-top: 1px solid #bbbbbb;
44 | border-bottom: none;
45 | }
46 |
47 | small {
48 | color: #777777;
49 | }
50 | """;
51 |
52 | ///
53 | /// Creates an static default page with given header and description.
54 | ///
55 | /// The static page header text.
56 | /// The static page description text.
57 | public static string CreateDefaultPageHtml ( string firstHeader, string description ) {
58 | firstHeader = HttpUtility.HtmlEncode ( firstHeader );
59 | description = HttpUtility.HtmlEncode ( description );
60 |
61 | return $$"""
62 |
63 |
64 |
65 |
66 |
67 | {{firstHeader}}
68 |
69 |
70 |
71 |
74 |
75 | {{firstHeader}}
76 | {{description}}
77 |
78 | Sisk/{{HttpServer.SiskVersion.ToString ( 3 )}}
79 |
80 |
81 |
82 | """;
83 | }
84 |
85 | ///
86 | /// Creates an static default page with given status code and description.
87 | ///
88 | /// The static page status code.
89 | /// The static page description text.
90 | public static HttpResponse CreateDefaultResponse ( in HttpStatusInformation status, string longDescription ) {
91 | string html = CreateDefaultPageHtml ( status.Description, longDescription );
92 | return new HttpResponse () {
93 | Status = status,
94 | Content = new HtmlContent ( html )
95 | };
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/src/Http/DeflateContent.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: DeflateContent.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.IO.Compression;
11 | using Sisk.Core.Helpers;
12 |
13 | namespace Sisk.Core.Http;
14 |
15 | ///
16 | /// Represents an HTTP content that is compressed using the Deflate algorithm.
17 | ///
18 | public sealed class DeflateContent : CompressedContent {
19 |
20 | ///
21 | public DeflateContent ( HttpContent innerContent ) : base ( innerContent ) {
22 | }
23 |
24 | ///
25 | public DeflateContent ( byte [] byteArrayContent ) : base ( byteArrayContent ) {
26 | }
27 |
28 | ///
29 | public DeflateContent ( Stream baseContent ) : base ( baseContent ) {
30 | }
31 |
32 | ///
33 | public override Stream GetCompressingStream ( Stream outputStream ) {
34 | return new DeflateStream ( outputStream, CompressionMode.Compress, leaveOpen: true );
35 | }
36 |
37 | ///
38 | public override void Setup () {
39 | HeaderHelper.CopyHttpHeaders ( InnerContent.Headers, Headers );
40 | Headers.ContentEncoding.Add ( "deflate" );
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Http/ForwardingResolver.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: ForwardingResolver.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Net;
11 |
12 | namespace Sisk.Core.Http;
13 |
14 | ///
15 | /// Provides HTTP forwarding resolving methods that can be used to resolving the client remote
16 | /// address, host and protocol of a proxy, load balancer or CDN, through the HTTP request.
17 | ///
18 | public abstract class ForwardingResolver {
19 | ///
20 | /// Method that is called when resolving the IP address of the client in the request.
21 | ///
22 | /// The object which contains parameters of the request.
23 | /// The original connecting endpoint.
24 | ///
25 | public virtual IPAddress OnResolveClientAddress ( HttpRequest request, IPEndPoint connectingEndpoint ) {
26 | return connectingEndpoint.Address;
27 | }
28 |
29 | ///
30 | /// Method that is called when resolving the client request host.
31 | ///
32 | /// The object which contains parameters of the request.
33 | /// The original requested host.
34 | ///
35 | public virtual string OnResolveRequestHost ( HttpRequest request, string requestedHost ) {
36 | return requestedHost;
37 | }
38 |
39 | ///
40 | /// Method that is called when resolving whether the HTTP request is using HTTPS or HTTP.
41 | ///
42 | /// The object which contains parameters of the request.
43 | /// The original security state of the request.
44 | ///
45 | public virtual bool OnResolveSecureConnection ( HttpRequest request, bool isSecure ) {
46 | return isSecure;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/Http/GZipContent.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: GZipContent.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.IO.Compression;
11 | using Sisk.Core.Helpers;
12 |
13 | namespace Sisk.Core.Http;
14 |
15 | ///
16 | /// Represents an HTTP content that is compressed using the GZip algorithm.
17 | ///
18 | public sealed class GZipContent : CompressedContent {
19 |
20 | ///
21 | public GZipContent ( HttpContent innerContent ) : base ( innerContent ) {
22 | }
23 |
24 | ///
25 | public GZipContent ( byte [] byteArrayContent ) : base ( byteArrayContent ) {
26 | }
27 |
28 | ///
29 | public GZipContent ( Stream baseContent ) : base ( baseContent ) {
30 | }
31 |
32 | ///
33 | public override Stream GetCompressingStream ( Stream outputStream ) {
34 | return new GZipStream ( outputStream, CompressionMode.Compress, leaveOpen: true );
35 | }
36 |
37 | ///
38 | public override void Setup () {
39 | HeaderHelper.CopyHttpHeaders ( InnerContent.Headers, Headers );
40 | Headers.ContentEncoding.Add ( "gzip" );
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Http/Handlers/DefaultHttpServerHandler.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: DefaultHttpServerHandler.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Diagnostics;
11 | using Sisk.Core.Http.Hosting;
12 | using Sisk.Core.Routing;
13 |
14 | namespace Sisk.Core.Http.Handlers;
15 |
16 | internal sealed class DefaultHttpServerHandler : HttpServerHandler {
17 |
18 | internal HttpServerHostContext? hostContext;
19 | internal Action? _routerSetup;
20 | internal List<(Action, string)> _serverBootstrapingFunctions = new ();
21 |
22 | protected override void OnServerStarting ( HttpServer server ) {
23 | for (int i = 0; i < _serverBootstrapingFunctions.Count; i++) {
24 | var func = _serverBootstrapingFunctions [ i ];
25 |
26 | Stopwatch sw = Stopwatch.StartNew ();
27 | if (hostContext?.verbose == true) {
28 | Console.Write ( $"Running server boostrapper <{func.Item2}>... " );
29 | }
30 |
31 | func.Item1 ();
32 |
33 | if (hostContext?.verbose == true) {
34 | Console.WriteLine ( $"OK! ({sw.ElapsedMilliseconds} ms)" );
35 | }
36 | }
37 | }
38 |
39 | protected override void OnSetupRouter ( Router router ) {
40 | _routerSetup?.Invoke ( router );
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Http/Hosting/ConfigurationContext.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: ConfigurationContext.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.Core.Http.Hosting;
11 |
12 | ///
13 | /// Represents a reading context for a portable configuration file.
14 | ///
15 | public sealed class ConfigurationContext {
16 | ///
17 | /// Gets the absolute path to the configuration file. The file is guaranteed to exist
18 | /// when getting this property value.
19 | ///
20 | public string ConfigurationFile { get; }
21 |
22 | ///
23 | /// Gets the which are configuring this context.
24 | ///
25 | public HttpServerHostContext Host { get; }
26 |
27 | ///
28 | /// Gets the target which are configuring this context.
29 | ///
30 | public ListeningHost TargetListeningHost { get; }
31 |
32 | ///
33 | /// Gets the collection for defining configuration parameters of the host application.
34 | ///
35 | public InitializationParameterCollection Parameters { get => Host.Parameters; }
36 |
37 | internal ConfigurationContext ( string configurationFile, HttpServerHostContext host, ListeningHost targetListeningHost ) {
38 | ConfigurationFile = configurationFile;
39 | Host = host;
40 | TargetListeningHost = targetListeningHost;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Http/Hosting/ConfigurationFileLookupDirectory.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: ConfigurationFileLookupDirectory.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.Core.Http.Hosting;
11 |
12 | ///
13 | /// Represents the base directory where the should search for the configuration
14 | /// file.
15 | ///
16 | [Flags]
17 | public enum ConfigurationFileLookupDirectory {
18 | ///
19 | /// The should search in the process current/base directory.
20 | ///
21 | CurrentDirectory = 1 << 1,
22 |
23 | ///
24 | /// The should search in the executable base directory.
25 | ///
26 | AppDirectory = 1 << 2
27 | }
28 |
--------------------------------------------------------------------------------
/src/Http/Hosting/HttpServerHostContextBuilderExceptionMode.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: HttpServerHostContextBuilderExceptionMode.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.Core.Http.Hosting;
11 |
12 | ///
13 | /// Represents how the builder event error message should be displayed.
14 | ///
15 | public enum HttpServerHostContextBuilderExceptionMode {
16 | ///
17 | /// No message should be displayed.
18 | ///
19 | Silent,
20 |
21 | ///
22 | /// Normal messages, including their exception type and message, should be displayed.
23 | ///
24 | Normal,
25 |
26 | ///
27 | /// Detailed messages, including detailed exception trace and information, should be displayed.
28 | ///
29 | Detailed,
30 |
31 | ///
32 | /// No message should be displayed and exceptions should be thrown instead being caughts.
33 | ///
34 | Throw
35 | }
36 |
--------------------------------------------------------------------------------
/src/Http/Hosting/IConfigurationReader.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: IConfigurationReader.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.Core.Http.Hosting;
11 |
12 | ///
13 | /// Represents an interface that reads and applies settings from a settings file.
14 | ///
15 | public interface IConfigurationReader {
16 | ///
17 | /// Represents the method that reads and applies settings from a settings file.
18 | ///
19 | /// The configuration context object.
20 | public void ReadConfiguration ( ConfigurationContext context );
21 | }
22 |
--------------------------------------------------------------------------------
/src/Http/HtmlContent.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: HtmlContent.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Text;
11 |
12 | namespace Sisk.Core.Http;
13 |
14 | ///
15 | /// Provides HTTP content based on HTML contents.
16 | ///
17 | public class HtmlContent : StringContent {
18 |
19 | ///
20 | /// Creates an new class with given HTML content and encoding.
21 | ///
22 | /// The HTML content string.
23 | /// The encoding which will encode the HTML contents.
24 | public HtmlContent ( string content, Encoding encoding ) : base ( content, encoding, "text/html" ) {
25 | }
26 |
27 | ///
28 | /// Creates an new class with given HTML content, using the environment default encoding.
29 | ///
30 | /// The HTML content string.
31 | public HtmlContent ( string content ) : this ( content, Encoding.Default ) { }
32 |
33 | ///
34 | /// Creates a new class with given HTML content as a byte span and encoding.
35 | ///
36 | /// The HTML content as a byte span.
37 | /// The encoding which will decode the HTML contents.
38 | public HtmlContent ( ReadOnlySpan contents, Encoding encoding ) : base ( encoding.GetString ( contents ), encoding, "text/html" ) {
39 | }
40 |
41 | ///
42 | /// Creates a new class with given HTML content as a UTF-8 encoded byte span.
43 | ///
44 | /// The HTML content as a UTF-8 encoded byte span.
45 | public HtmlContent ( ReadOnlySpan utf8Contents ) : this ( utf8Contents, Encoding.UTF8 ) {
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/Http/PrefixedLogStream.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: PrefixedLogStream.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 |
11 | namespace Sisk.Core.Http;
12 |
13 | ///
14 | /// Represents a log stream that prefixes log messages with a custom string.
15 | ///
16 | [System.Diagnostics.CodeAnalysis.SuppressMessage ( "Naming", "CA1711:Identifiers should not have incorrect suffix",
17 | Justification = "Breaking change." )]
18 | public sealed class PrefixedLogStream : LogStream {
19 |
20 | ///
21 | /// Gets or sets a function that returns the prefix to be added to log messages.
22 | ///
23 | public Func PrefixFunction { get; set; } = delegate { return string.Empty; };
24 |
25 | ///
26 | /// Initializes a new instance of the class with the specified prefix function.
27 | ///
28 | /// A function that returns the prefix to be added to log messages.
29 | public PrefixedLogStream ( Func prefixFunction ) {
30 | PrefixFunction = prefixFunction;
31 | }
32 |
33 | ///
34 | /// Initializes a new instance of the class with the specified prefix function and text writer.
35 | ///
36 | /// A function that returns the prefix to be added to log messages.
37 | /// The text writer to write log messages to.
38 | public PrefixedLogStream ( Func prefixFunction, TextWriter tw ) : base ( tw ) {
39 | PrefixFunction = prefixFunction;
40 | }
41 |
42 | ///
43 | /// Initializes a new instance of the class with the specified prefix function and file name.
44 | ///
45 | /// A function that returns the prefix to be added to log messages.
46 | /// The name of the file to write log messages to.
47 | public PrefixedLogStream ( Func prefixFunction, string filename ) : base ( filename ) {
48 | PrefixFunction = prefixFunction;
49 | }
50 |
51 | ///
52 | /// Initializes a new instance of the class with the specified prefix function, file name, and text writer.
53 | ///
54 | /// A function that returns the prefix to be added to log messages.
55 | /// The name of the file to write log messages to, or null to write to the text writer.
56 | /// The text writer to write log messages to, or null to write to the file.
57 | public PrefixedLogStream ( Func prefixFunction, string? filename, TextWriter? tw ) : base ( filename, tw ) {
58 | PrefixFunction = prefixFunction;
59 | }
60 |
61 | ///
62 | protected override void WriteLineInternal ( string line ) {
63 | string prefix = PrefixFunction ();
64 | base.WriteLineInternal ( string.Concat ( prefix, line ) );
65 | }
66 |
67 | ///
68 | protected override ValueTask WriteLineInternalAsync ( string line ) {
69 | string prefix = PrefixFunction ();
70 | return base.WriteLineInternalAsync ( string.Concat ( prefix, line ) );
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/Http/Streams/HttpStreamPingPolicy.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: HttpStreamPingPolicy.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.Core.Http.Streams;
11 |
12 | ///
13 | /// Provides an automatic ping sender for HTTP Event Source connections.
14 | ///
15 | public sealed class HttpStreamPingPolicy : IDisposable {
16 | private bool _disposed;
17 | private readonly HttpWebSocket? __ws_parent;
18 | private readonly HttpRequestEventSource? __sse_parent;
19 | private Timer? _timer;
20 |
21 | ///
22 | /// Gets or sets the payload message that is sent to the server as a ping message.
23 | ///
24 | public string DataMessage { get; set; } = "%ping%";
25 |
26 | ///
27 | /// Gets or sets the sending interval for each ping message.
28 | ///
29 | public TimeSpan Interval { get; set; } = TimeSpan.FromSeconds ( 5 );
30 |
31 | internal HttpStreamPingPolicy ( HttpRequestEventSource parent ) {
32 | __sse_parent = parent;
33 | }
34 |
35 | internal HttpStreamPingPolicy ( HttpWebSocket parent ) {
36 | __ws_parent = parent;
37 | }
38 |
39 | ///
40 | /// Starts sending periodic pings to the client.
41 | ///
42 | public void Start () {
43 | _timer = new Timer ( new TimerCallback ( OnCallback ), null, 0, (int) Interval.TotalMilliseconds );
44 | }
45 |
46 | ///
47 | /// Configures and starts sending periodic pings to the client.
48 | ///
49 | /// The payload message that is sent to the server as a ping message.
50 | /// The sending interval for each ping message.
51 | public void Start ( string dataMessage, TimeSpan interval ) {
52 | DataMessage = dataMessage;
53 | Interval = interval;
54 |
55 | Start ();
56 | }
57 |
58 | private async void OnCallback ( object? state ) {
59 | try {
60 | if (_disposed || _timer is null)
61 | return;
62 |
63 | if (__sse_parent != null) {
64 | if (!__sse_parent.IsActive) {
65 | _timer.Dispose ();
66 | return;
67 | }
68 | __sse_parent.Send ( $":{DataMessage}" );
69 | }
70 | else if (__ws_parent != null) {
71 | if (__ws_parent.IsClosed) {
72 | _timer.Dispose ();
73 | return;
74 | }
75 | await __ws_parent.SendAsync ( DataMessage );
76 | }
77 | }
78 | catch {
79 | _timer = null;
80 | Dispose ();
81 | }
82 | }
83 |
84 | ///
85 | public void Dispose () {
86 | if (_disposed)
87 | return;
88 |
89 | _timer?.Dispose ();
90 | _disposed = true;
91 |
92 | GC.SuppressFinalize ( this );
93 | }
94 |
95 | ///
96 | ~HttpStreamPingPolicy () {
97 | Dispose ();
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/src/Internal/ByteArrayAccessors.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: ByteArrayAccessors.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Runtime.CompilerServices;
11 |
12 | namespace Sisk.Core.Internal;
13 |
14 | static class ByteArrayAccessors {
15 | [UnsafeAccessor ( UnsafeAccessorKind.Field, Name = "_content" )]
16 | public extern static ref byte [] UnsafeGetContent ( ByteArrayContent bcontent );
17 |
18 | [UnsafeAccessor ( UnsafeAccessorKind.Field, Name = "_offset" )]
19 | public extern static ref int UnsafeGetOffset ( ByteArrayContent bcontent );
20 |
21 | [UnsafeAccessor ( UnsafeAccessorKind.Field, Name = "_count" )]
22 | public extern static ref int UnsafeGetCount ( ByteArrayContent bcontent );
23 | }
24 |
--------------------------------------------------------------------------------
/src/Internal/DiagnosticId.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: DiagnosticId.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.Core.Internal;
11 |
12 | static class DiagnosticId {
13 | public const string Sisk_HttpContext_Current_Experimental = "SISK0230";
14 | }
15 |
--------------------------------------------------------------------------------
/src/Internal/HttpStatusDescription.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: HttpStatusDescription.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | // The source code below was forked from the official dotnet runtime
11 | //
12 | // Licensed to the .NET Foundation under one or more agreements.
13 | // The .NET Foundation licenses this file to you under the MIT license.
14 |
15 | namespace Sisk.Core.Internal;
16 |
17 | static class HttpStatusDescription {
18 |
19 | internal static string? Get ( int code ) =>
20 | code switch {
21 | 100 => "Continue",
22 | 101 => "Switching Protocols",
23 | 102 => "Processing",
24 | 103 => "Early Hints",
25 |
26 | 200 => "OK",
27 | 201 => "Created",
28 | 202 => "Accepted",
29 | 203 => "Non-Authoritative Information",
30 | 204 => "No Content",
31 | 205 => "Reset Content",
32 | 206 => "Partial Content",
33 | 207 => "Multi-Status",
34 | 208 => "Already Reported",
35 | 226 => "IM Used",
36 |
37 | 300 => "Multiple Choices",
38 | 301 => "Moved Permanently",
39 | 302 => "Found",
40 | 303 => "See Other",
41 | 304 => "Not Modified",
42 | 305 => "Use Proxy",
43 | 307 => "Temporary Redirect",
44 | 308 => "Permanent Redirect",
45 |
46 | 400 => "Bad Request",
47 | 401 => "Unauthorized",
48 | 402 => "Payment Required",
49 | 403 => "Forbidden",
50 | 404 => "Not Found",
51 | 405 => "Method Not Allowed",
52 | 406 => "Not Acceptable",
53 | 407 => "Proxy Authentication Required",
54 | 408 => "Request Timeout",
55 | 409 => "Conflict",
56 | 410 => "Gone",
57 | 411 => "Length Required",
58 | 412 => "Precondition Failed",
59 | 413 => "Request Entity Too Large",
60 | 414 => "Request-Uri Too Long",
61 | 415 => "Unsupported Media Type",
62 | 416 => "Range Not Satisfiable",
63 | 417 => "Expectation Failed",
64 | 418 => "I'm a Teapot",
65 | 421 => "Misdirected Request",
66 | 422 => "Unprocessable Entity",
67 | 423 => "Locked",
68 | 424 => "Failed Dependency",
69 | 426 => "Upgrade Required", // RFC 2817
70 | 428 => "Precondition Required",
71 | 429 => "Too Many Requests",
72 | 431 => "Request Header Fields Too Large",
73 | 451 => "Unavailable For Legal Reasons",
74 |
75 | 500 => "Internal Server Error",
76 | 501 => "Not Implemented",
77 | 502 => "Bad Gateway",
78 | 503 => "Service Unavailable",
79 | 504 => "Gateway Timeout",
80 | 505 => "Http Version Not Supported",
81 | 506 => "Variant Also Negotiates",
82 | 507 => "Insufficient Storage",
83 | 508 => "Loop Detected",
84 | 510 => "Not Extended",
85 | 511 => "Network Authentication Required",
86 |
87 | _ => null
88 | };
89 | }
--------------------------------------------------------------------------------
/src/Internal/PathUtility.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: PathUtility.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Runtime.CompilerServices;
11 | using System.Text;
12 |
13 | namespace Sisk.Core.Internal;
14 |
15 | internal static class PathUtility {
16 | [MethodImpl ( MethodImplOptions.AggressiveInlining )]
17 | public static bool IsFullyRootedUri ( string uri ) {
18 | return uri.StartsWith ( "http://", StringComparison.OrdinalIgnoreCase )
19 | || uri.StartsWith ( "https://", StringComparison.OrdinalIgnoreCase )
20 | || uri.StartsWith ( "ws://", StringComparison.OrdinalIgnoreCase )
21 | || uri.StartsWith ( "wss://", StringComparison.OrdinalIgnoreCase );
22 | }
23 |
24 | public static string CombinePaths ( params string [] paths ) {
25 | StringBuilder sb = new StringBuilder ();
26 | bool hadFullyRootedUri = false;
27 |
28 | foreach (string part in paths) {
29 | if (IsFullyRootedUri ( part )) {
30 | hadFullyRootedUri = true;
31 | sb.Clear ();
32 | }
33 |
34 | if (sb.Length > 0 && !part.StartsWith ( '?' ))
35 | sb.Append ( '/' );
36 |
37 | sb.Append ( part.Trim ( '/' ) );
38 | }
39 |
40 | if (!hadFullyRootedUri)
41 | sb.Insert ( 0, '/' );
42 |
43 | return sb.ToString ();
44 | }
45 |
46 | public static string NormalizedCombine ( bool allowReturn, char environmentPathChar, ReadOnlySpan paths ) {
47 | if (paths.Length == 0)
48 | return "";
49 |
50 | bool startsWithSepChar = paths [ 0 ].StartsWith ( '/' ) || paths [ 0 ].StartsWith ( '\\' );
51 | List tokens = new List ();
52 |
53 | for (int ip = 0; ip < paths.Length; ip++) {
54 | string path = paths [ ip ]
55 | ?? throw new ArgumentNullException ( $"The path string at index {ip} is null." );
56 |
57 | string normalizedPath = path
58 | .Replace ( '/', environmentPathChar )
59 | .Replace ( '\\', environmentPathChar )
60 | .Trim ( environmentPathChar );
61 |
62 | string [] pathIdentities = normalizedPath.Split (
63 | environmentPathChar,
64 | StringSplitOptions.RemoveEmptyEntries
65 | );
66 |
67 | tokens.AddRange ( pathIdentities );
68 | }
69 |
70 | Stack insertedIndexes = new Stack ();
71 | StringBuilder pathBuilder = new StringBuilder ();
72 | foreach (string token in tokens) {
73 | if (token == ".") {
74 | continue;
75 | }
76 | else if (token == "..") {
77 | if (allowReturn) {
78 | pathBuilder.Length = insertedIndexes.Pop ();
79 | }
80 | }
81 | else {
82 | insertedIndexes.Push ( pathBuilder.Length );
83 | pathBuilder.Append ( token );
84 | pathBuilder.Append ( environmentPathChar );
85 | }
86 | }
87 |
88 | if (startsWithSepChar)
89 | pathBuilder.Insert ( 0, environmentPathChar );
90 |
91 | return pathBuilder.ToString ().TrimEnd ( environmentPathChar );
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/Internal/PlainTextFileMimeTypes.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: PlainTextFileMimeTypes.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System;
11 | using System.Collections.Generic;
12 | using System.Linq;
13 | using System.Text;
14 | using System.Threading.Tasks;
15 |
16 | namespace Sisk.Core.Internal;
17 |
18 | static class PlainTextFileMimeTypes {
19 |
20 | public static readonly string [] PlainTextMimeTypes = [
21 | "application/json",
22 | "application/javascript",
23 | "application/xml",
24 | "application/ld+json",
25 | "application/yaml",
26 | "application/graphql",
27 | "application/sql",
28 | "application/atom+xml",
29 | "application/rss+xml",
30 | "application/manifest+json"
31 | ];
32 | }
33 |
--------------------------------------------------------------------------------
/src/Internal/SharedChars.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: SharedChars.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 |
11 | namespace Sisk.Core.Internal;
12 |
13 | internal static class SharedChars {
14 | public const char Semicolon = ';';
15 | public const char Equal = '=';
16 | public const char DoubleQuote = '"';
17 | public const char Amp = '&';
18 | }
19 |
--------------------------------------------------------------------------------
/src/Internal/SpanHelpers.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: SpanHelpers.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Runtime.CompilerServices;
11 | using System.Runtime.InteropServices;
12 |
13 | namespace Sisk.Core.Internal;
14 | static class SpanHelpers {
15 |
16 | public static bool Contains ( in ReadOnlySpan search, T value, IEqualityComparer comparer ) {
17 |
18 | if (search.Length == 0)
19 | return false;
20 |
21 | ref T first = ref MemoryMarshal.GetReference ( search );
22 | return Contains ( ref first, value, search.Length, comparer );
23 | }
24 |
25 | // Adapted from System.Private.CoreLib/src/System/SpanHelpers.T.cs
26 | // checks if searchSpace contains value using comparer
27 | static bool Contains ( ref T searchSpace, T value, int length, IEqualityComparer comparer ) {
28 |
29 | nint index = 0; // Use nint for arithmetic to avoid unnecessary 64->32->64 truncations
30 |
31 | if (default ( T ) != null || value != null) {
32 |
33 | while (length >= 8) {
34 | length -= 8;
35 |
36 | if (comparer.Equals ( value, Unsafe.Add ( ref searchSpace, index + 0 ) ) ||
37 | comparer.Equals ( value, Unsafe.Add ( ref searchSpace, index + 1 ) ) ||
38 | comparer.Equals ( value, Unsafe.Add ( ref searchSpace, index + 2 ) ) ||
39 | comparer.Equals ( value, Unsafe.Add ( ref searchSpace, index + 3 ) ) ||
40 | comparer.Equals ( value, Unsafe.Add ( ref searchSpace, index + 4 ) ) ||
41 | comparer.Equals ( value, Unsafe.Add ( ref searchSpace, index + 5 ) ) ||
42 | comparer.Equals ( value, Unsafe.Add ( ref searchSpace, index + 6 ) ) ||
43 | comparer.Equals ( value, Unsafe.Add ( ref searchSpace, index + 7 ) )) {
44 | goto Found;
45 | }
46 |
47 | index += 8;
48 | }
49 |
50 | if (length >= 4) {
51 | length -= 4;
52 |
53 | if (comparer.Equals ( value, Unsafe.Add ( ref searchSpace, index + 0 ) ) ||
54 | comparer.Equals ( value, Unsafe.Add ( ref searchSpace, index + 1 ) ) ||
55 | comparer.Equals ( value, Unsafe.Add ( ref searchSpace, index + 2 ) ) ||
56 | comparer.Equals ( value, Unsafe.Add ( ref searchSpace, index + 3 ) )) {
57 | goto Found;
58 | }
59 |
60 | index += 4;
61 | }
62 |
63 | while (length > 0) {
64 | length--;
65 |
66 | if (comparer.Equals ( value, Unsafe.Add ( ref searchSpace, index ) ))
67 | goto Found;
68 |
69 | index += 1;
70 | }
71 | }
72 | else {
73 | nint len = length;
74 | for (index = 0; index < len; index++) {
75 | if ((object?) Unsafe.Add ( ref searchSpace, index ) is null) {
76 | goto Found;
77 | }
78 | }
79 | }
80 |
81 | return false;
82 |
83 | Found:
84 | return true;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/Internal/StringExtensions.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: StringExtensions.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Diagnostics.CodeAnalysis;
11 |
12 | namespace Sisk.Core.Internal;
13 |
14 | internal static class StringExtensions {
15 | [return: NotNullIfNotNull ( nameof ( s ) )]
16 | public static string? RemoveStart ( this string? s, string term, StringComparison comparisonType = StringComparison.Ordinal ) {
17 | if (s is null)
18 | return null;
19 | if (s.StartsWith ( term, comparisonType ))
20 | return s [ term.Length.. ];
21 |
22 | return s;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/Routing/AsyncRequestHandler.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: AsyncRequestHandler.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using Sisk.Core.Http;
11 |
12 | namespace Sisk.Core.Routing;
13 |
14 | ///
15 | /// Represents a class that implements and its execution method is asynchronous.
16 | ///
17 | public abstract class AsyncRequestHandler : IRequestHandler {
18 | ///
19 | public virtual RequestHandlerExecutionMode ExecutionMode { get; init; } = RequestHandlerExecutionMode.BeforeResponse;
20 |
21 | ///
22 | /// This method is called by the before executing a request when the instantiates an object that implements this interface. If it returns
23 | /// a object, the route action is not called and all execution of the route is stopped. If it returns "null", the execution is continued.
24 | ///
25 | /// The entry HTTP request.
26 | /// The HTTP request context. It may contain information from other .
27 | public abstract Task ExecuteAsync ( HttpRequest request, HttpContext context );
28 |
29 | HttpResponse? IRequestHandler.Execute ( HttpRequest request, HttpContext context ) {
30 | return ExecuteAsync ( request, context ).GetAwaiter ().GetResult ();
31 | }
32 |
33 | ///
34 | /// Returns an null reference, which points to the next request handler or route action.
35 | ///
36 | public HttpResponse? Next () {
37 | return null;
38 | }
39 |
40 | ///
41 | /// Gets an inline that resolves to the specified function.
42 | ///
43 | /// The function that the will run.
44 | /// Optional. Determines where the request handler will be executed.
45 | public static AsyncRequestHandler Create ( Func> execute, RequestHandlerExecutionMode executionMode = RequestHandlerExecutionMode.BeforeResponse ) {
46 | return new InlineAsyncRequestHandler ( execute, executionMode );
47 | }
48 | }
49 |
50 | sealed class InlineAsyncRequestHandler : AsyncRequestHandler {
51 | public Func> Handler { get; set; }
52 |
53 | public InlineAsyncRequestHandler ( Func> handler, RequestHandlerExecutionMode mode ) {
54 | Handler = handler ?? throw new ArgumentNullException ( nameof ( handler ) );
55 | base.ExecutionMode = mode;
56 | }
57 |
58 | public override async Task ExecuteAsync ( HttpRequest request, HttpContext context ) {
59 | return await Handler ( request, context );
60 | }
61 | }
--------------------------------------------------------------------------------
/src/Routing/IRequestHandler.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: IRequestHandler.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using Sisk.Core.Http;
11 |
12 | namespace Sisk.Core.Routing {
13 | ///
14 | /// Represents an interface that is executed before a request.
15 | ///
16 | public interface IRequestHandler {
17 |
18 | ///
19 | /// This method is called by the before executing a request when the instantiates an object that implements this interface. If it returns
20 | /// a object, the route action is not called and all execution of the route is stopped. If it returns "null", the execution is continued.
21 | ///
22 | /// The entry HTTP request.
23 | /// The HTTP request context. It may contain information from other .
24 | HttpResponse? Execute ( HttpRequest request, HttpContext context );
25 |
26 | ///
27 | /// Gets or sets when this should run.
28 | ///
29 | RequestHandlerExecutionMode ExecutionMode { get; init; }
30 | }
31 |
32 | ///
33 | /// Defines when the should be executed.
34 | ///
35 | [Flags]
36 | public enum RequestHandlerExecutionMode {
37 | ///
38 | /// Indicates that the request handler should be executed before the route action.
39 | ///
40 | BeforeResponse = 1 << 1,
41 |
42 | ///
43 | /// Indicates that the request handler should be executed after the route action.
44 | ///
45 | AfterResponse = 1 << 2,
46 |
47 | ///
48 | /// Indicates that the request handler should be executed before and after the route action.
49 | ///
50 | Both = BeforeResponse | AfterResponse
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/Routing/RegexRoute.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: RegexRoute.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Diagnostics.CodeAnalysis;
11 |
12 | namespace Sisk.Core.Routing;
13 |
14 | ///
15 | /// Represents an which it's implementation already enables
16 | /// .
17 | ///
18 | public sealed class RegexRoute : Route {
19 | ///
20 | /// Initializes a new instance of the class.
21 | ///
22 | /// The HTTP method for this route.
23 | /// The regular expression pattern for this route.
24 | /// The action to be executed when this route is matched.
25 | public RegexRoute ( RouteMethod method, [StringSyntax ( StringSyntaxAttribute.Regex )] string pattern, RouteAction action ) : base ( method, pattern, action ) {
26 | UseRegex = true;
27 | }
28 |
29 | ///
30 | /// Initializes a new instance of the class.
31 | ///
32 | /// The HTTP method for this route.
33 | /// The regular expression pattern for this route.
34 | /// The name of this route.
35 | /// The action to be executed when this route is matched.
36 | /// The callback to be executed before the action.
37 | public RegexRoute ( RouteMethod method, [StringSyntax ( StringSyntaxAttribute.Regex )] string pattern, string? name, RouteAction action, IRequestHandler []? beforeCallback ) : base ( method, pattern, name, action, beforeCallback ) {
38 | UseRegex = true;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/Routing/RequestCallback.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: RequestCallback.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using Sisk.Core.Http;
11 |
12 | namespace Sisk.Core.Routing {
13 | ///
14 | /// Represents the function that is called after the route is matched with the request.
15 | ///
16 | /// The received request on the router.
17 | public delegate object RouteAction ( HttpRequest request );
18 |
19 | ///
20 | /// Represents the function that is called after the route is matched with the request.
21 | ///
22 | public delegate object ParameterlessRouteAction ();
23 |
24 | ///
25 | /// Represents the function that is called when an request reaches an error on the
26 | /// router.
27 | ///
28 | public delegate HttpResponse RoutingErrorCallback ( HttpContext context );
29 |
30 | ///
31 | /// Represents the function that is called after the route action threw an exception.
32 | ///
33 | public delegate HttpResponse ExceptionErrorCallback ( Exception ex, HttpContext context );
34 |
35 | ///
36 | /// Represents the function that receives an object of the and returns an response from the informed object.
37 | ///
38 | /// The input object type. Cannot be nullable.
39 | /// The result router object.
40 | public delegate HttpResponse RouterActionHandlerCallback ( T input ) where T : notnull;
41 | }
42 |
--------------------------------------------------------------------------------
/src/Routing/RequestHandledAttribute.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: RequestHandledAttribute.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Diagnostics.CodeAnalysis;
11 |
12 | namespace Sisk.Core.Routing {
13 | ///
14 | /// Specifies that the method or class, when used on this attribute, will instantiate the type and call the with given parameters.
15 | ///
16 | public class RequestHandlerAttribute<[DynamicallyAccessedMembers ( DynamicallyAccessedMemberTypes.All )] T> : RequestHandlerAttribute where T : IRequestHandler {
17 | ///
18 | /// Creates an new instance of this class.
19 | ///
20 | public RequestHandlerAttribute () : base ( typeof ( T ) ) { }
21 |
22 | ///
23 | /// Creates an new instance of this class with the specified
24 | /// constructor arguments for .
25 | ///
26 | /// An optional array of objects which is passed to the request handler constructor.
27 | public RequestHandlerAttribute ( params object? [] constructorArguments ) : base ( typeof ( T ) ) {
28 | ConstructorArguments = constructorArguments;
29 | }
30 | }
31 |
32 | ///
33 | /// Specifies that the method or class, when used on this attribute, will instantiate the type and call the with given parameters.
34 | ///
35 | [AttributeUsage ( AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true )]
36 | public class RequestHandlerAttribute : Attribute {
37 | ///
38 | /// Gets or sets the type that implements which will be instantiated.
39 | ///
40 |
41 | [DynamicallyAccessedMembers ( DynamicallyAccessedMemberTypes.All )]
42 | public Type RequestHandlerType { get; set; }
43 |
44 | ///
45 | /// Specifies parameters for the given type's constructor.
46 | ///
47 | public object? [] ConstructorArguments { get; set; }
48 |
49 | ///
50 | /// Creates a new instance of this attribute with the informed parameters.
51 | ///
52 | /// The type that implements which will be instantiated.
53 | public RequestHandlerAttribute ( [DynamicallyAccessedMembers ( DynamicallyAccessedMemberTypes.All )] Type handledBy ) {
54 | RequestHandlerType = handledBy;
55 | ConstructorArguments = Array.Empty ();
56 | }
57 |
58 | internal IRequestHandler Activate () {
59 | if (Activator.CreateInstance ( RequestHandlerType, ConstructorArguments ) is not IRequestHandler rhandler) {
60 | throw new ArgumentException ( SR.Format ( SR.RequestHandler_ActivationException, RequestHandlerType.FullName, ConstructorArguments.Length ) );
61 | }
62 | return rhandler;
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/Routing/RequestHandler.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: RequestHandler.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using Sisk.Core.Http;
11 |
12 | namespace Sisk.Core.Routing;
13 |
14 | ///
15 | /// Represents an abstract class which implements .
16 | ///
17 | public abstract class RequestHandler : IRequestHandler {
18 | ///
19 | ///
20 | public virtual RequestHandlerExecutionMode ExecutionMode { get; init; } = RequestHandlerExecutionMode.BeforeResponse;
21 |
22 | ///
23 | ///
24 | public abstract HttpResponse? Execute ( HttpRequest request, HttpContext context );
25 |
26 | ///
27 | /// Returns an null reference, which points to the next request handler or route action.
28 | ///
29 | public HttpResponse? Next () {
30 | return null;
31 | }
32 |
33 | ///
34 | /// Gets an inline that resolves to the specified function.
35 | ///
36 | /// The function that the will run.
37 | /// Optional. Determines where the request handler will be executed.
38 | public static RequestHandler Create ( Func execute, RequestHandlerExecutionMode executionMode = RequestHandlerExecutionMode.BeforeResponse ) {
39 | return new InlineRequestHandler ( execute, executionMode );
40 | }
41 | }
42 |
43 | sealed class InlineRequestHandler : RequestHandler {
44 | public Func Handler { get; set; }
45 |
46 | public InlineRequestHandler ( Func handler, RequestHandlerExecutionMode mode ) {
47 | Handler = handler ?? throw new ArgumentNullException ( nameof ( handler ) );
48 | base.ExecutionMode = mode;
49 | }
50 |
51 | public override HttpResponse? Execute ( HttpRequest request, HttpContext context ) {
52 | return Handler ( request, context );
53 | }
54 | }
--------------------------------------------------------------------------------
/src/Routing/RouteMatch.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: RouteMatch.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Collections.Specialized;
11 |
12 | namespace Sisk.Core.Routing;
13 |
14 | ///
15 | /// Represents the result of a route matching operation.
16 | ///
17 | public sealed class RouteMatch {
18 |
19 | ///
20 | /// Gets a value indicating whether the route matching operation was successful.
21 | ///
22 | public bool Success { get; }
23 |
24 | ///
25 | /// Gets a collection of parameters extracted from the route, or if the route matching operation was not successful.
26 | ///
27 | public NameValueCollection? Parameters { get; }
28 |
29 | internal RouteMatch ( bool success, NameValueCollection? parameters ) {
30 | Success = success;
31 | Parameters = parameters;
32 | }
33 | }
--------------------------------------------------------------------------------
/src/Routing/RouteMethod.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: RouteMethod.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | namespace Sisk.Core.Routing {
11 | ///
12 | /// Represents an HTTP method to be matched in an .
13 | ///
14 | [Flags]
15 | public enum RouteMethod : int {
16 | ///
17 | /// Represents the HTTP GET method.
18 | ///
19 | Get = 2 << 0,
20 |
21 | ///
22 | /// Represents the HTTP POST method.
23 | ///
24 | Post = 2 << 1,
25 |
26 | ///
27 | /// Represents the HTTP PUT method.
28 | ///
29 | Put = 2 << 2,
30 |
31 | ///
32 | /// Represents the HTTP PATCH method.
33 | ///
34 | Patch = 2 << 3,
35 |
36 | ///
37 | /// Represents the HTTP DELETE method.
38 | ///
39 | Delete = 2 << 4,
40 |
41 | ///
42 | /// Represents the HTTP HEAD method.
43 | ///
44 | Head = 2 << 6,
45 |
46 | ///
47 | /// Represents the HTTP OPTIONS method.
48 | ///
49 | Options = 2 << 7,
50 |
51 | ///
52 | /// Represents any HTTP method.
53 | ///
54 | Any = Get | Post | Put | Patch | Delete | Head | Options
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/Routing/RoutePrefixAttribute.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: RoutePrefixAttribute.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Diagnostics.CodeAnalysis;
11 |
12 | namespace Sisk.Core.Routing;
13 |
14 | ///
15 | /// Represents an attribute that, when applied to an class containing routes, all child routes will start with
16 | /// the specified prefix.
17 | ///
18 | [AttributeUsage ( AttributeTargets.Class, AllowMultiple = false )]
19 | public sealed class RoutePrefixAttribute : Attribute {
20 | ///
21 | /// Gets or sets the route prefix.
22 | ///
23 | public string Prefix { get; set; }
24 |
25 | ///
26 | /// Initializes an new with given prefix.
27 | ///
28 | public RoutePrefixAttribute ( [StringSyntax ( StringSyntaxAttribute.Uri )] string prefix ) {
29 | if (string.IsNullOrEmpty ( prefix )) {
30 | throw new ArgumentNullException ( nameof ( prefix ) );
31 | }
32 | Prefix = prefix;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/Routing/RouterModule.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: RouterModule.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Runtime.CompilerServices;
11 |
12 | namespace Sisk.Core.Routing;
13 |
14 | ///
15 | /// Indicates that extended class supports router modules, which allows the management of routes,
16 | /// request handlers and prefixes.
17 | ///
18 | public abstract class RouterModule {
19 | internal bool _wasSetupCalled;
20 |
21 | ///
22 | /// Gets or sets an list of this runs.
23 | ///
24 | public IList RequestHandlers { get; set; } = new List ();
25 |
26 | ///
27 | /// Gets or sets the router prefix for this class. This property overrides any
28 | /// value defined by set in this class.
29 | ///
30 | public string? Prefix { get; set; }
31 |
32 | ///
33 | /// Registers an on all routes defined by this module.
34 | ///
35 | /// The instance which will be applied to all registered routes
36 | /// of this class.
37 | protected void HasRequestHandler ( IRequestHandler handler ) {
38 | RequestHandlers.Add ( handler );
39 | }
40 |
41 | ///
42 | /// Specifies a prefix for all routes defined by this module.
43 | ///
44 | /// The prefix to be applied to all registered routes of this class.
45 | ///
46 | /// This method allows for the specification of a common prefix for all routes defined by this module,
47 | /// which can be useful for organizing and structuring routes in a large application.
48 | ///
49 | protected void HasPrefix ( string prefix ) {
50 | Prefix = prefix;
51 | }
52 |
53 | ///
54 | /// Method that is called when an is defining routes from the current
55 | /// .
56 | ///
57 | ///
58 | /// The base method is mandatory to be called on all derived methods.
59 | ///
60 | /// The which is defining routes from the current .
61 | protected virtual void OnSetup ( Router parentRouter ) {
62 | _wasSetupCalled = true;
63 | }
64 |
65 | ///
66 | /// This method is called before a route is defined in the router and after it
67 | /// is created in this class, so its attributes and parameters can be modified. This method must
68 | /// be overloaded in the extending class and must not be called directly.
69 | ///
70 | /// The route being defined on the router.
71 | protected virtual void OnRouteCreating ( Route configuringRoute ) {
72 | }
73 |
74 | [MethodImpl ( MethodImplOptions.AggressiveInlining )]
75 | internal void CallRouteCreating ( Route configuringRoute ) => OnRouteCreating ( configuringRoute );
76 |
77 | [MethodImpl ( MethodImplOptions.AggressiveInlining )]
78 | internal void CallOnSetup ( Router parentRouter ) => OnSetup ( parentRouter );
79 | }
--------------------------------------------------------------------------------
/src/Routing/ValueResult.cs:
--------------------------------------------------------------------------------
1 | // The Sisk Framework source code
2 | // Copyright (c) 2024- PROJECT PRINCIPIUM and all Sisk contributors
3 | //
4 | // The code below is licensed under the MIT license as
5 | // of the date of its publication, available at
6 | //
7 | // File name: ValueResult.cs
8 | // Repository: https://github.com/sisk-http/core
9 |
10 | using System.Runtime.CompilerServices;
11 |
12 | namespace Sisk.Core.Routing;
13 |
14 | ///
15 | /// Represents a mutable type for boxing objects by value or reference in a response from a router.
16 | ///
17 | /// The type of object to be boxed.
18 | public sealed class ValueResult where T : notnull {
19 | //
20 | //
21 | private ValueResult () {
22 | }
23 |
24 | ///
25 | /// Implicitly gets the value from a given instance.
26 | ///
27 | /// The input instance.
28 | ///
29 | [MethodImpl ( MethodImplOptions.AggressiveInlining )]
30 | public static implicit operator T ( ValueResult box ) {
31 | return (T) (object) box;
32 | }
33 |
34 | ///
35 | /// Implicitly creates a new instance from a given value.
36 | ///
37 | /// The input value to wrap.
38 | ///
39 | [MethodImpl ( MethodImplOptions.AggressiveInlining )]
40 | public static implicit operator ValueResult ( T value ) {
41 | if (value is null)
42 | throw new InvalidOperationException ( SR.ValueResult_Null );
43 | return Unsafe.As> ( value )!;
44 | }
45 | }
--------------------------------------------------------------------------------
/tests/MSTestSettings.cs:
--------------------------------------------------------------------------------
1 | [assembly: Parallelize ( Scope = ExecutionScope.MethodLevel )]
2 |
--------------------------------------------------------------------------------
/tests/Server.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using Sisk.Core.Http;
3 | using Sisk.Core.Http.Hosting;
4 |
5 | namespace tests;
6 |
7 | [TestClass]
8 | public sealed class Server {
9 | public static HttpServerHostContext Instance = null!;
10 |
11 | public static HttpClient GetHttpClient () => new HttpClient () { BaseAddress = new Uri ( Instance.HttpServer.ListeningPrefixes [ 0 ] ) };
12 |
13 | [AssemblyInitialize]
14 | public static void AssemblyInit ( TestContext testContext ) {
15 |
16 | Instance = HttpServer.CreateBuilder ()
17 | .UseRouter ( router => {
18 |
19 | router.MapGet ( "/tests/plaintext", delegate ( HttpRequest request ) {
20 | return new HttpResponse () {
21 | Content = new StringContent ( "Hello, world!", Encoding.UTF8, "text/plain" ),
22 | Status = HttpStatusInformation.Ok
23 | };
24 | } );
25 | router.MapGet ( "/tests/plaintext/chunked", delegate ( HttpRequest request ) {
26 | return new HttpResponse () {
27 | Content = new StringContent ( "Hello, world!", Encoding.UTF8, "text/plain" ),
28 | Status = HttpStatusInformation.Ok,
29 | SendChunked = true
30 | };
31 | } );
32 | } )
33 | .Build ();
34 |
35 | Instance.Start ( verbose: false, preventHault: false );
36 | }
37 |
38 | [AssemblyCleanup]
39 | public static void AssemblyCleanup () {
40 | Instance.Dispose ();
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/tests/Tests/HttpResponseTests.cs:
--------------------------------------------------------------------------------
1 | namespace tests.Tests;
2 |
3 | [TestClass]
4 | public sealed class HttpResponseTests {
5 |
6 | [TestMethod]
7 | public async Task OkPlainText () {
8 | using (var client = Server.GetHttpClient ()) {
9 |
10 | var request = new HttpRequestMessage ( HttpMethod.Get, "tests/plaintext" );
11 | var response = await client.SendAsync ( request );
12 | var content = await response.Content.ReadAsStringAsync ();
13 |
14 | Assert.IsTrue ( response.IsSuccessStatusCode );
15 | Assert.AreEqual ( content, "Hello, world!", ignoreCase: true );
16 | Assert.AreEqual ( response.Content.Headers.ContentType?.MediaType, "text/plain" );
17 | Assert.AreEqual ( response.Content.Headers.ContentType?.CharSet, "utf-8" );
18 | }
19 | }
20 |
21 | [TestMethod]
22 | public async Task OkPlainTextChunked () {
23 | using (var client = Server.GetHttpClient ()) {
24 |
25 | var request = new HttpRequestMessage ( HttpMethod.Get, "tests/plaintext/chunked" );
26 | var response = await client.SendAsync ( request );
27 | var content = await response.Content.ReadAsStringAsync ();
28 |
29 | Assert.IsTrue ( response.IsSuccessStatusCode );
30 | Assert.IsTrue ( response.Headers.TransferEncodingChunked == true );
31 | Assert.AreEqual ( content, "Hello, world!", ignoreCase: true );
32 | Assert.AreEqual ( response.Content.Headers.ContentType?.MediaType, "text/plain" );
33 | Assert.AreEqual ( response.Content.Headers.ContentType?.CharSet, "utf-8" );
34 | }
35 | }
36 |
37 | [TestMethod]
38 | public async Task NotFound () {
39 | using (var client = Server.GetHttpClient ()) {
40 |
41 | var request = new HttpRequestMessage ( HttpMethod.Get, "tests/not-found" );
42 | var response = await client.SendAsync ( request );
43 | var content = await response.Content.ReadAsStringAsync ();
44 |
45 | Assert.IsTrue ( response.StatusCode == System.Net.HttpStatusCode.NotFound );
46 | }
47 | }
48 |
49 | [TestMethod]
50 | public async Task MethodNotAllowed () {
51 | using (var client = Server.GetHttpClient ()) {
52 |
53 | var request = new HttpRequestMessage ( HttpMethod.Post, "tests/plaintext" );
54 | var response = await client.SendAsync ( request );
55 | var content = await response.Content.ReadAsStringAsync ();
56 |
57 | Assert.IsTrue ( response.StatusCode == System.Net.HttpStatusCode.MethodNotAllowed );
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/tests/tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net9.0
5 | latest
6 | enable
7 | enable
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------