/*
* Copyright (c) 2022 Vaughn Nugent
*
* Library: VNLib
* Package: VNLib.Net.Http
* File: AlternateProtocolBase.cs
*
* AlternateProtocolBase.cs is part of VNLib.Net.Http which is part of the larger
* VNLib collection of libraries and utilities.
*
* VNLib.Net.Http is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* VNLib.Net.Http is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using VNLib.Net.Http.Core;
namespace VNLib.Net.Http
{
///
/// A base class for all non-http protocol handlers
///
public abstract class AlternateProtocolBase : MarshalByRefObject, IAlternateProtocol
{
///
/// A cancelation source that allows for canceling running tasks, that is linked
/// to the server that called .
///
///
/// This property is only available while the
/// method is executing
///
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
protected CancellationTokenSource CancelSource { get; private set; }
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
///
async Task IAlternateProtocol.RunAsync(Stream transport, CancellationToken handlerToken)
{
//Create new cancel source
CancelSource ??= new();
//Register the token to cancel the source and save the registration for unregister on dispose
CancellationTokenRegistration Registration = handlerToken.Register(CancelSource.Cancel);
try
{
//Call child initialize method
await RunAsync(new AlternateProtocolTransportStreamWrapper(transport));
CancelSource.Cancel();
}
finally
{
//dispose the cancelation registration
await Registration.DisposeAsync();
//Dispose cancel source
CancelSource.Dispose();
}
}
///
/// Is the current socket connected using transport security
///
public virtual bool IsSecure { get; init; }
///
/// Determines if the instance is pending cancelation
///
public bool IsCancellationRequested => CancelSource.IsCancellationRequested;
///
/// Cancels all pending operations. This session will be unusable after this function is called
///
public virtual void CancelAll() => CancelSource?.Cancel();
///
/// Called when the protocol swtich handshake has completed and the transport is
/// available for the new protocol
///
/// The transport stream
/// A task that represents the active use of the transport, and when complete all operations are unwound
protected abstract Task RunAsync(Stream transport);
}
}