using Best.HTTP.Hosts.Connections; namespace Best.HTTP.Request.Upload { // [Request Creation] --> [Request Queued] --> [UploadStream.SetupRequestHeaders call] --> [Send Request Headers] --> [UploadStream.PrepareToSend call] --> [UploadStream.Read to Send Request Body] -> [Dispose UploadStream] public static class UploadReadConstants { public static int WaitForMore = -1; public static int Completed = 0; } /// /// Abstract class to serve as a base for non-conventional streams used in HTTP requests. /// /// /// The return value of is treated specially in the plugin: /// /// /// Less than zero(-1) /// indicates that no data is currently available but more is expected in the future. In this case, when new data becomes available the IThreadSignaler object must be signaled. /// /// /// Zero (0) /// means that the stream is closed, no more data can be expected. /// /// Otherwise it must return with the number bytes copied to the buffer. /// /// A zero value to signal stream closure can follow a less than zero value. /// public abstract class UploadStreamBase : System.IO.Stream { /// /// Gets the object for signaling when new data is available. /// public IThreadSignaler Signaler { get; private set; } /// /// Length in bytes that the stream will upload. /// /// /// The return value of Length is treated specially in the plugin: /// /// -2The stream's length is unknown and the plugin have to send data with 'chunked' transfer-encoding. /// -1The stream's length is unknown and the plugin have to send data as-is, without any encoding. /// 0No content to send. The content-length header will contain zero (0). /// >0Length of the content is known, will be sent as-is, without any encoding. The content-length header will contain zero (0). /// /// Constants for the first three points can be found in . /// public override long Length => throw new System.NotImplementedException(); /// /// Called before sending out the request's headers. Perform content processing to calculate the final length if possible. /// In this function the implementor can set headers and other parameters to the request. /// /// Typically called on a thread. /// The associated with the stream. public abstract void BeforeSendHeaders(HTTPRequest request); /// /// Called just before sending out the request's body, and saves the for signaling when new data is available. /// /// The HTTPRequest associated with the stream. /// The object to be used for signaling. /// Typically called on a separate thread. /// /// Called just before sending out the request's body, saves the that can be used for signaling when new data is available. /// /// The HTTPRequest associated with the stream. /// The object to be used for signaling. /// Typically called on a separate thread. public virtual void BeforeSendBody(HTTPRequest request, IThreadSignaler threadSignaler) => this.Signaler = threadSignaler; protected override void Dispose(bool disposing) { base.Dispose(disposing); this.Signaler = null; } } }