本篇按照以下結構翻譯html
自定義功能git
相關技術github
tusdotnet附帶一個存儲庫TusDiskStore,它將文件保存在磁盤上的一個目錄中。你能夠經過實現如下一個或多個接口(在「接口」這一節中列出來的接口)來實現本身的存儲。tusdotnet將自動處理請求並根據用於請求的存儲所實現的接口將信息添加到Tus-Extension頭部。緩存
請注意有一些方法會在請求執行期間屢次調用,這取決於倉儲正確的緩存數據。服務器
要實現的最多見接口是ITusStore、ITusCreationStore和ITusReadableStore。這將容許倉儲(store)建立和上傳文件,並讀取文件以進行處理或下載。架構
如下涉及到的名詞請查看個人關於tus協議的翻譯。ide
必須實現的接口,在Tus-Extension中的值:<none>this
這是tus核心協議的接口,自定義的倉儲必須實現。spa
http://tus.io/protocols/resumable-upload.html#core-protocol或請查看我翻譯的tus協議的相關內容。翻譯
public interface ITusStore { /// <summary> /// 使用提供的流將數據寫入文件 /// 若是流的長度超過了上傳文件的長度,必須拋出<exception cref="TusStoreException"></exception>異常/// </summary> /// <param name="fileId">要寫入的文件Id</param> /// <param name="stream">來自客戶端的輸入流</param> /// <param name="cancellationToken">取消令牌</param> /// <returns>寫入的字節長度</returns> Task<long> AppendDataAsync(string fileId, Stream stream, CancellationToken cancellationToken); /// <summary> /// 檢索一個文件是否存在 /// </summary> /// <param name="fileId">要檢查的文件Id</param> /// <param name="cancellationToken">取消令牌.</param> /// <returns></returns> Task<bool> FileExistAsync(string fileId, CancellationToken cancellationToken); /// <summary> /// Returns the upload length specified when the file was created or null if Defer-Upload-Lenght was used. /// </summary> /// <param name="fileId">The id of the file to check.</param> /// <param name="cancellationToken">Cancellation token to use when cancelling.</param> /// <returns>The upload length of the file</returns> Task<long?> GetUploadLengthAsync(string fileId, CancellationToken cancellationToken); /// <summary> /// Returns the current size of the file a.k.a. the upload offset. /// </summary> /// <param name="fileId">The id of the file to check.</param> /// <param name="cancellationToken">Cancellation token to use when cancelling.</param> /// <returns>The size of the current file</returns> Task<long> GetUploadOffsetAsync(string fileId, CancellationToken cancellationToken); }
非必須實現的接口,在Tus-Extension中的值:checksum
支持checksum擴展的接口,用於文件校驗和(checksum)的檢查。
http://tus.io/protocols/resumable-upload.html#checksum 或請查看我翻譯的tus協議的相關內容。
public interface ITusChecksumStore { /// <summary> /// Returns a collection of hash algorithms that the store supports (e.g. sha1). /// </summary> /// <param name="cancellationToken">Cancellation token to use when cancelling</param> /// <returns>The collection of hash algorithms</returns> Task<IEnumerable<string>> GetSupportedAlgorithmsAsync(CancellationToken cancellationToken); /// <summary> /// Verify that the provided checksum matches the file checksum. /// </summary> /// <param name="fileId">The id of the file to check</param> /// <param name="algorithm">The checksum algorithm to use when checking. This algorithm must be supported by the store.</param> /// <param name="checksum">The checksom to use for verification</param> /// <param name="cancellationToken">Cancellation token to use when cancelling</param> /// <returns>True if the checksum matches otherwise false</returns> Task<bool> VerifyChecksumAsync(string fileId, string algorithm, byte[] checksum, CancellationToken cancellationToken); }
非必須實現的接口,Tus-Extension中的值:concatenation
注意:要實現這個接口必須保證ITusCreationStore也被實現。
這個接口添加了對concatenation擴展的支持,這個擴展的做用在於在一個POST請求中將多個文件串聯而後獲得一個最終文件。
http://tus.io/protocols/resumable-upload.html#concatenation或查看我關於tus協議的相關翻譯
public interface ITusConcatenationStore { /// <summary> /// Returns the type of Upload-Concat header that was used when creating the file. /// Returns null if no Upload-Concat was used. /// </summary> /// <param name="fileId">The file to check</param> /// <param name="cancellationToken">Cancellation token to use when cancelling</param> /// <returns>FileConcatPartial, FileConcatFinal or null</returns> Task<FileConcat> GetUploadConcatAsync(string fileId, CancellationToken cancellationToken); /// <summary> /// Create a partial file. This method is called when a Upload-Concat header is present and when its value is "partial". /// </summary> /// <param name="uploadLength">The length of the upload in bytes</param> /// <param name="metadata">The Upload-Metadata request header or null if no header was provided</param> /// <param name="cancellationToken">Cancellation token to use when cancelling</param> /// <returns>The id of the newly created file</returns> Task<string> CreatePartialFileAsync(long uploadLength, string metadata, CancellationToken cancellationToken); /// <summary> /// Creates a final file by concatenating multiple files together. This method is called when a Upload-Concat header /// is present with a "final" value. /// </summary> /// <param name="partialFiles">List of file ids to concatenate</param> /// <param name="metadata">The Upload-Metadata request header or null if no header was provided</param> /// <param name="cancellationToken">Cancellation token to use when cancelling</param> /// <returns>The id of the newly created file</returns> Task<string> CreateFinalFileAsync(string[] partialFiles, string metadata, CancellationToken cancellationToken); }
非必須實現的接口,Tus-Extension的值爲:creation
這個接口處理tus協議的建立擴展,並用於建立文件引用,稍後能夠利用tus核心協議,使用這個建立的文件引用將數據上載。
http://tus.io/protocols/resumable-upload.html#creation 或查看個人tus協議的相關翻譯。
public interface ITusCreationStore { /// <summary> /// Create a file upload reference that can later be used to upload data. /// </summary> /// <param name="uploadLength">The length of the upload in bytes</param> /// <param name="metadata">The Upload-Metadata request header or null if no header was provided</param> /// <param name="cancellationToken">Cancellation token to use when cancelling</param> /// <returns></returns> Task<string> CreateFileAsync(long uploadLength, string metadata, CancellationToken cancellationToken); /// <summary> /// Get the Upload-Metadata header as it was provided to <code>CreateFileAsync</code>. /// </summary> /// <param name="fileId">The id of the file to get the header for</param> /// <param name="cancellationToken">Cancellation token to use when cancelling</param> /// <returns>The Upload-Metadata header</returns> Task<string> GetUploadMetadataAsync(string fileId, CancellationToken cancellationToken); }
非必須實現的接口,Tus-Extension中的值: creation-defer-length
注意:要實現這個接口必須保證ITusCreationStore接口同時被實現。
creation-defer-length是creation擴展的子擴展,它容許用戶在不預先知道上傳文件大小的狀況下建立文件。
若是實現了這個接口,而且用戶選擇使用這個特性,那麼對CreateFileAsync (ITusCreationStore)和CreatePartialFileAsync (ITusConcatenationStore)的調用將使用-1做爲文件長度。
http://tus.io/protocols/resumable-upload.html#upload-defer-length或查看個人tus文檔
public interface ITusCreationDeferLengthStore { /// <summary> /// Set the upload length (in bytes) of the provided file. /// </summary> /// <param name="fileId">The id of the file to set the upload length for</param> /// <param name="uploadLength">The length of the upload in bytes</param> /// <param name="cancellationToken">Cancellation token to use when cancelling</param> /// <returns>Task</returns> Task SetUploadLengthAsync(string fileId, long uploadLength, CancellationToken cancellationToken); }
非必須實現的接口,Tus-Extensions中的值:termination
這個接口支持了tus協議中的termination擴展,用於刪除文件。
http://tus.io/protocols/resumable-upload.html#termination 或查看個人tus文檔
public interface ITusTerminationStore { /// <summary> /// Delete a file from the data store. /// </summary> /// <param name="fileId">The id of the file to delete</param> /// <param name="cancellationToken">Cancellation token to use when cancelling</param> /// <returns>Task</returns> Task DeleteFileAsync(string fileId, CancellationToken cancellationToken); }
非必須實現的接口,Tus-Extension中的值:<none>
ITusReadableStore是一個不屬於tus規範的簡單接口,它用於幫助從數據存儲中讀取數據,使下載文件或處理上傳文件變得更容易。如何使用該接口的示例能夠在我以前翻譯的tusdotnet文檔的下載文件小結中找到。或者查看英文文檔:Downloading files
public interface ITusReadableStore { /// <summary> /// Get the file with the specified id. /// Returns null if the file was not found. /// </summary> /// <param name="fileId">The id of the file to get</param> /// <param name="cancellationToken">Cancellation token to use when cancelling</param> /// <returns>The file or null if the file was not found</returns> Task<ITusFile> GetFileAsync(string fileId, CancellationToken cancellationToken); }
非必須實現的接口,Tus-Extension中的值:expiration
這個接口實現了expiration擴展,用於服務端刪除那些過了一段時間後未完成上傳的文件。過時的文件將經過tusdotnet返回404。服務器仍然可使用倉儲(store)的方法訪問文件。
http://tus.io/protocols/resumable-upload.html#expiration
https://github.com/smatsson/tusdotnet/wiki/Removing-expired-incomplete-files 介紹了更多關於如何配置文件清理的信息。
public interface ITusExpirationStore { /// <summary> /// Set the expiry date of the provided file. /// This method will be called once during creation if absolute expiration is used. /// This method will be called once per patch request if sliding expiration is used. /// </summary> /// <param name="fileId">The id of the file to update the expiry date for</param> /// <param name="expires">The datetime offset when the file expires</param> /// <param name="cancellationToken">Cancellation token to use when cancelling</param> /// <returns>Task</returns> Task SetExpirationAsync(string fileId, DateTimeOffset expires, CancellationToken cancellationToken); /// <summary> /// Get the expiry date of the provided file (set by <code>SetExpirationAsync</code>). /// If the datetime offset returned has passed an error will be returned to the client. /// If no expiry date exist for the file, this method returns null. /// </summary> /// <param name="fileId">The id of the file to get the expiry date for</param> /// <param name="cancellationToken">Cancellation token to use when cancelling</param> /// <returns></returns> Task<DateTimeOffset?> GetExpirationAsync(string fileId, CancellationToken cancellationToken); /// <summary> /// Returns a list of ids of incomplete files that have expired. /// This method can be used to do batch processing of incomplete, expired files before removing them. /// </summary> /// <param name="cancellationToken">Cancellation token to use when cancelling</param> /// <returns>A list of ids of incomplete files that have expired</returns> Task<IEnumerable<string>> GetExpiredFilesAsync(CancellationToken cancellationToken); /// <summary> /// Remove all incomplete files that have expired. /// </summary> /// <param name="cancellationToken">Cancellation token to use when cancelling</param> /// <returns>The number of files that were removed</returns> Task<int> RemoveExpiredFilesAsync(CancellationToken cancellationToken); }
這部分描述了tusdonet的架構和它的整體概念。
tusdotnet包含了三個主要的部分:
這是負責處理全部請求並返回正確響應的OWIN中間件。中間件的功能取決於所使用的數據存儲所實現的接口。
要設置中間件,請使用UseTus擴展方法併爲其提供配置工廠。使用這種方法,tusdotnet支持爲不一樣的請求(例如不一樣的用戶、租戶等)使用不一樣的配置。
中間件將轉發它不能處理的全部請求,例如GET請求或其餘缺乏Tus-Resumable頭的請求。這樣,即便客戶機不支持tus協議,開發人員仍然能夠處理上傳。
用於配置的對象告訴Tus中間件有哪些選項可用。它目前支持設置要偵聽的URL、要使用的數據存儲和在請求處理期間運行的自定義回調。
相關信息在這裏:Configure tusdotnet 或者你能夠查看我翻譯的文檔。
數據存儲是tusdotnet存儲數據的地方,也是決定運行tusdotnet的服務器功能的地方。存儲庫能夠實現許多接口,每一個接口都賦予系統更多的功能。tusdotnet附帶了一個存儲庫實現TusDiskStore,這是一個簡單的存儲,將數據保存在服務器磁盤上的文件夾中。支持自定義數據(Custom data stores)存儲。