GridLab TUS Resumable Upload Protocol - Skills Guide¶
Skill Type: File Upload & Transfer
Technology Stack: .NET, ASP.NET Core, TUS Protocol, HTTP
Complexity Level: Intermediate
Last Updated: 2024
📋 Overview¶
The GridLab TUS module implements the TUS (Transloadit Upload Server) protocol, an open standard for resumable file uploads built on HTTP, enabling reliable large file transfers with automatic resume capability.
Key Capabilities¶
- ✅ Resumable file uploads
- ✅ Large file support
- ✅ Network interruption recovery
- ✅ Progress tracking
- ✅ Configurable upload limits
- ✅ File expiration management
- ✅ CORS support
TUS Protocol Benefits¶
- Reliability: Automatic resume on connection failure
- Efficiency: Upload only missing chunks
- Scalability: Handle large files without memory issues
- Standardization: Open protocol with client library support
Prerequisites¶
- .NET 9.0 or higher
- ASP.NET Core application
- NuGet package manager
- Disk space for file storage
🚀 Quick Start¶
Step 1: Install NuGet Package¶
Install the GridLab.Abp.TUS package from NuGet:
Install-Package GridLab.Abp.TUS
Package Information:
- Package Name: GridLab.Abp.TUS
- Repository: GitLab - GridLab ABP Framework
- NuGet: GridLab.Abp.TUS
- Protocol Spec: TUS Protocol Specification
Step 2: Add Module Dependency¶
Add the AbpGridLabTusModule to your ABP module's dependency list:
[DependsOn(
//...other dependencies
typeof(AbpGridLabTusModule)
)]
public class YourModule : AbpModule
{
}
Step 3: Configure Middleware¶
Configure TUS in your API host module. Important: Place UseTus after UseCors and before UseRouting and UseAuthorization:
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var app = context.GetApplicationBuilder();
// ... other middleware
app.UseCors();
// Configure TUS
ITusConfiguration configuration = context.ServiceProvider.GetRequiredService<ITusConfiguration>();
app.UseTus(httpContext => Task.FromResult(configuration.CreateTusConfiguration()));
app.UseRouting();
app.UseAuthentication();
if (MultiTenancyConsts.IsEnabled)
{
app.UseMultiTenancy();
}
app.UseAbpRequestLocalization();
app.UseAuthorization();
// ... other middleware
}
Step 4: Enable TUS in Configuration¶
Configure TUS options in your module:
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpTusConfigurationOptions>(options =>
{
options.IsEnabled = true; // TUS is disabled by default
options.UrlPath = "/file-management/upload"; // Custom upload endpoint
options.MaxAllowedUploadSizeInBytesLong = 5L * 1024 * 1024 * 1024; // 5 GB
});
}
⚙️ Configuration Reference¶
TUS Configuration Options¶
| Property | Description | Default Value | Type |
|---|---|---|---|
| IsEnabled | Enable/disable TUS service | false | bool |
| AbsolutePath | File storage directory path | {AppDirectory}/files | string |
| UrlPath | Upload endpoint URL path | /file-management/upload | string |
| Expiration | Incomplete file expiration time | 5 minutes | TimeSpan |
| MetadataParsingStrategy | Metadata parsing approach | AllowEmptyValues | enum |
| AllowedExtensions | Allowed TUS extensions | TusExtensions.All | flags |
| MaxAllowedUploadSizeInBytes | Max upload size (int) | null (unlimited) | int? |
| MaxAllowedUploadSizeInBytesLong | Max upload size (long) | null (unlimited) | long? |
Complete Configuration Example¶
Configure<AbpTusConfigurationOptions>(options =>
{
// Enable TUS
options.IsEnabled = true;
// Custom storage path
options.AbsolutePath = Path.Combine(
Directory.GetCurrentDirectory(),
"uploads",
"tus"
);
// Custom endpoint
options.UrlPath = "/api/uploads/resumable";
// File expiration (incomplete uploads)
options.Expiration = AbsoluteExpiration.Create(TimeSpan.FromHours(24));
// Metadata parsing
options.MetadataParsingStrategy = MetadataParsingStrategy.AllowEmptyValues;
// Limit extensions
options.AllowedExtensions = TusExtensions.Creation |
TusExtensions.Termination |
TusExtensions.Expiration;
// Max file size: 10 GB
options.MaxAllowedUploadSizeInBytesLong = 10L * 1024 * 1024 * 1024;
});
💡 Client Integration¶
JavaScript/TypeScript Client¶
import * as tus from 'tus-js-client';
function uploadFile(file) {
const upload = new tus.Upload(file, {
endpoint: 'https://your-api.com/file-management/upload',
retryDelays: [0, 3000, 5000, 10000, 20000],
metadata: {
filename: file.name,
filetype: file.type
},
onError: function(error) {
console.error('Upload failed:', error);
},
onProgress: function(bytesUploaded, bytesTotal) {
const percentage = (bytesUploaded / bytesTotal * 100).toFixed(2);
console.log(`Progress: ${percentage}%`);
},
onSuccess: function() {
console.log('Upload completed successfully!');
}
});
upload.start();
}
C# Client¶
public class TusClientService
{
private readonly HttpClient _httpClient;
public TusClientService(HttpClient httpClient)
{
_httpClient = httpClient;
}
public async Task<string> UploadFileAsync(Stream fileStream, string fileName)
{
var tusClient = new TusClient();
var fileUrl = await tusClient.CreateAsync(
"https://your-api.com/file-management/upload",
fileStream,
metadata: new Dictionary<string, string>
{
{ "filename", fileName }
}
);
await tusClient.UploadAsync(fileUrl, fileStream);
return fileUrl;
}
}
🔧 Advanced Scenarios¶
Post-Upload Processing¶
public class TusUploadHandler : ITransientDependency
{
private readonly ILogger<TusUploadHandler> _logger;
public TusUploadHandler(ILogger<TusUploadHandler> logger)
{
_logger = logger;
}
public async Task OnUploadCompleteAsync(string fileId, string filePath)
{
_logger.LogInformation(
"Upload complete for file {FileId} at {FilePath}",
fileId,
filePath
);
// Move file to permanent storage
var permanentPath = GetPermanentStoragePath(fileId);
File.Move(filePath, permanentPath);
// Process file (virus scan, thumbnail generation, etc.)
await ProcessFileAsync(permanentPath);
}
}
Custom File Validation¶
Configure<AbpTusConfigurationOptions>(options =>
{
options.IsEnabled = true;
// Add custom validation
options.OnAuthorizeAsync = async context =>
{
// Check user permissions
var authService = context.HttpContext.RequestServices
.GetRequiredService<IAuthorizationService>();
var result = await authService.AuthorizeAsync(
context.HttpContext.User,
"FileUpload.Create"
);
return result.Succeeded;
};
});
📚 Best Practices¶
✅ Do's¶
- Enable TUS for files larger than 100 MB
- Set appropriate file size limits
- Implement file expiration for incomplete uploads
- Use virus scanning on completed uploads
- Monitor disk space usage
- Implement proper error handling
- Use HTTPS for security
❌ Don'ts¶
- Don't use TUS for small files (< 10 MB)
- Don't store sensitive files without encryption
- Don't ignore file expiration settings
- Don't allow unlimited file sizes
- Don't skip authentication/authorization
- Don't forget to clean up incomplete uploads
🔍 Troubleshooting¶
Common Issues¶
Issue: Upload fails immediately
- Solution: Verify
IsEnabled = truein configuration - Solution: Check CORS settings allow TUS headers
- Solution: Ensure storage directory exists and is writable
Issue: Upload doesn't resume after interruption
- Solution: Verify client supports TUS protocol
- Solution: Check that file ID is being preserved
- Solution: Ensure file hasn't expired
Issue: 413 Payload Too Large error
- Solution: Increase
MaxAllowedUploadSizeInBytesLong - Solution: Check web server (IIS/Kestrel) upload limits
- Solution: Verify reverse proxy settings