tusdfiber

package module
v1.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 16, 2026 License: MIT Imports: 25 Imported by: 0

README

tusdfiber

Native TUS resumable upload protocol for Go Fiber / fasthttp.

CI Go Reference Go Report Card License

tusdfiber implements the TUS resumable upload protocol natively on Go Fiber — no adaptor.HTTPHandler() wrapper needed. All handlers accept func(c *fiber.Ctx) error directly.

Includes TUS v1 and IETF Resumable Upload Draft (v2 protocol), Prometheus metrics, and full compatibility with tusd storage backends (FileStore, S3, GCS, Azure) and hook systems (file, HTTP, gRPC).


Features

  • TUS v1 — POST (create), HEAD (offset), PATCH (upload chunk), GET (download), DELETE (terminate), OPTIONS (discovery)
  • IETF Resumable Upload Draft (v2)Upload-Draft-Interop-Version 3–6, Upload-Complete/Incomplete, 104 Early Hints, Upload-Limit
  • Streaming body — reads PATCH body via fasthttp RequestBodyStream(), no full buffering
  • CORS — configurable origin allowlist, credentials, headers
  • Concatenation — partial & final uploads (Upload-Concat)
  • Deferred length — uploads with unknown size (Upload-Defer-Length)
  • Notifications — channels for complete, created, terminated, progress events
  • Callbacks — pre-create, pre-finish, pre-terminate hooks
  • Hooks system — file, HTTP, gRPC hooks via tusd HookHandler interface
  • Prometheus metrics — uploads created/finished/terminated, bytes, errors, active uploads
  • Locking — file-based or memory-based lock coordination
  • Method overrideX-HTTP-Method-Override for PATCH/DELETE in restricted environments
  • No adaptor — pure func(c *fiber.Ctx) error, no http.Handler bridge
  • 51 unit tests — CI on every push, including E2E example tests
  • E2E tested — full TUS upload cycle tested: POST → HEAD → PATCH → HEAD → GET → DELETE

Installation

go get github.com/maulanashalihin/tusdfiber

Storage backend and locker (both required):

go get github.com/tus/tusd/v2/pkg/filestore   # or: s3store, gcsstore, azurestore
go get github.com/tus/tusd/v2/pkg/filelocker  # always required

Note: filestore is one of several storage backends — pick one store that fits your infra (filestore for local, s3store for S3, gcsstore for GCS, azurestore for Azure). filelocker is always needed regardless of which store you choose.

⚠️ Important: Your Fiber app must set StreamRequestBody: true in fiber.Config. Without this, large uploads will hang because fasthttp tries to buffer the entire request body in memory instead of streaming it to the TUS handler. See Quick Start below.

⚠️ Notification channels: If you enable NotifyCompleteUploads, NotifyCreatedUploads, or NotifyTerminatedUploads, you must drain the corresponding channel (handler.CompleteUploads, etc.) in a goroutine. These channels are unbuffered — sending blocks until someone reads. See the example for the drain pattern.


Quick Start

package main

import (
	"log"

	"github.com/gofiber/fiber/v2"
	"github.com/maulanashalihin/tusdfiber"
	"github.com/tus/tusd/v2/pkg/filelocker"
	"github.com/tus/tusd/v2/pkg/filestore"
)

func main() {
	app := fiber.New(fiber.Config{
		StreamRequestBody: true,
	})

	// ── Storage ──────────────────────────────────────────────
	store := filestore.New("./uploads")
	locker := filelocker.New("./uploads")

	composer := tusdfiber.NewStoreComposer()
	store.UseIn(composer.StoreComposer)
	locker.UseIn(composer.StoreComposer)

	// ── TUS Handler ───────────────────────────────────────────
	handler, err := tusdfiber.NewHandler(tusdfiber.Config{
		StoreComposer: composer,
		BasePath:      "/files/",
		MaxSize:       1 * 1024 * 1024 * 1024, // 1 GB
	})
	if err != nil {
		log.Fatal(err)
	}

	// ── Middleware ────────────────────────────────────────────
	app.Use(tusdfiber.DefaultMiddlewareStack(nil)...)

	// ── Routes ───────────────────────────────────────────────
	handler.Register(app)

	// ── Events (optional) ────────────────────────────────────
	go func() {
		for ev := range handler.CompleteUploads {
			log.Printf("Upload selesai: %s (%d bytes)", ev.Upload.ID, ev.Upload.Size)
		}
	}()

	log.Fatal(app.Listen(":8080"))
}
Client Example (using tus-js-client)
import * as tus from 'tus-js-client'

const upload = new tus.Upload(file, {
  endpoint: 'http://localhost:8080/files',
  retryDelays: [0, 1000, 3000, 5000],
  chunkSize: 5 * 1024 * 1024, // 5MB — responsive progress for large files
  metadata: { filename: file.name, filetype: file.type },
  onError: (err) => console.error(err),
  onProgress: (bytesSent, bytesTotal) => console.log(`${bytesSent}/${bytesTotal}`),
  onSuccess: () => console.log('Done!'),
})
upload.start()

Tip: Set chunkSize to a value like 5MB so progress updates frequently during large uploads. Without it, the entire file is sent in one PATCH request and progress jumps from 0% to 100%.


Protocol Versions: TUS v1 vs IETF Draft (v2)

TUS v1 IETF Draft (v2)
Status ✅ Stable, production-ready ⚠️ Experimental draft
Use when All production uploads Interop testing, draft compliance
Client support All TUS clients (tus-js-client, tusd, etc.) Limited (draft-specific clients)
Header detection Tus-Resumable: 1.0.0 Upload-Draft-Interop-Version
Why v2 exists

The IETF (Internet Engineering Task Force) is standardizing resumable uploads as an official RFC, similar to how HTTP/2 and HTTP/3 were standardized. TUS v1 is a community protocol — the IETF draft aims to make it an official web standard with cleaner HTTP semantics.

Key improvements in v2 over v1:

  • Standard HTTP semantics — Uses standard headers like Content-Type: application/partial-upload instead of custom application/offset+octet-stream
  • Upload-Complete/Incomplete — Clearer signaling for upload completion via boolean flags
  • Upload-Limit — Standardized way for servers to advertise limits (min/max size)
  • Interim 1xx responses — 104 Early Hints for better performance (not supported by fasthttp)

Recommendation: Use TUS v1 for everything. The v2 draft is experimental and may change before final standardization. Enable v2 only if you need to test interop with other draft-compliant implementations.

Enabling v2

Set EnableExperimentalProtocol: true in Config. The handler auto-detects Upload-Draft-Interop-Version headers and routes to the v2 protocol implementation.

handler, _ := tusdfiber.NewHandler(tusdfiber.Config{
    StoreComposer:              composer,
    BasePath:                   "/files/",
    EnableExperimentalProtocol: true, // ← enables v2 protocol
})

The v2 protocol supports:

Header Purpose
Upload-Draft-Interop-Version Protocol version (3, 4, 5, 6)
Upload-Complete: ?1 / Upload-Incomplete: ?0 Upload completion signal
Upload-Limit: min-size=0,max-size=N Server-enforced limits
Content-Type: application/partial-upload Chunk content type (v4+)

HEAD responses return 204 No Content instead of 200 OK for v2 requests.

Note: The draft spec recommends sending 104 Early Hints before processing the request body, but fasthttp does not support sending interim 1xx responses. Instead, all response headers (including Location) are sent in the final 201 Created response. This has no impact on client compatibility — tus-js-client and other implementations handle both patterns correctly.


Prometheus Metrics

m := tusdfiber.NewMetrics(nil)

// Count requests & active uploads
app.Use(m.Middleware())

// Expose metrics endpoint (Fiber-native, no adaptor)
app.Get("/metrics", tusdfiber.PrometheusHandler())
Available Metrics
Metric Type Labels
tusdfiber_uploads_created_total Counter
tusdfiber_uploads_finished_total Counter
tusdfiber_uploads_terminated_total Counter
tusdfiber_bytes_received_total Counter
tusdfiber_errors_total CounterVec code
tusdfiber_requests_total CounterVec method
tusdfiber_active_uploads Gauge
tusdfiber_hook_invocations_total CounterVec hooktype
tusdfiber_hook_errors_total CounterVec hooktype

Hooks System

Use tusd's file, HTTP, or gRPC hooks with NewHandlerWithHooks:

File Hooks
import "github.com/tus/tusd/v2/pkg/hooks/file"

handler, err := tusdfiber.NewHandlerWithHooks(config, &file.FileHook{
    Directory: "./hooks",
}, tusdfiber.AvailableHooks)
HTTP Hooks
import "github.com/tus/tusd/v2/pkg/hooks/http"

handler, err := tusdfiber.NewHandlerWithHooks(config, &http.HttpHook{
    Endpoint: "https://example.com/hooks",
}, tusdfiber.AvailableHooks)
gRPC Hooks
import "github.com/tus/tusd/v2/pkg/hooks/grpc"

handler, err := tusdfiber.NewHandlerWithHooks(config, &grpc.GrpcHook{
    Endpoint: "localhost:50051",
}, tusdfiber.AvailableHooks)
Available Hook Types
Hook When Can Reject
HookPreCreate Before upload creation
HookPostCreate After upload creation
HookPostReceive During chunk upload ✅ (stop)
HookPreFinish Before upload completion
HookPostFinish After upload completion
HookPreTerminate Before upload termination
HookPostTerminate After upload termination

API

tusdfiber.NewHandler(config)

Creates a routed TUS handler (TUS v1 + auto-detection of v2 draft).

tusdfiber.NewHandlerWithHooks(config, hookHandler, enabledHooks)

Creates a routed handler with tusd-compatible hook integration.

tusdfiber.NewUnroutedHandler(config)

Creates an unrouted handler for manual route wiring:

Method Description
PostFile Create upload (routes to v2 if draft detected)
HeadFile Get offset
PatchFile Upload chunk
GetFile Download
DelFile Terminate
Options Protocol discovery
handler.Register(router)
Route Method Purpose
{BasePath} POST Create upload
{BasePath} OPTIONS Protocol discovery
{BasePath}:id HEAD Get offset/info
{BasePath}:id PATCH Upload chunk
{BasePath}:id GET Download
{BasePath}:id DELETE Terminate
tusdfiber.DefaultMiddlewareStack(corsConfig)
app.Use(tusdfiber.DefaultMiddlewareStack(nil)...)
  1. MethodOverrideMiddleware()X-HTTP-Method-Override
  2. CORSMiddleware(cfg) — CORS headers & preflight
  3. TusResumableMiddleware()Tus-Resumable: 1.0.0 / Upload-Draft-Interop-Version

Configuration

type Config struct {
    StoreComposer                 *StoreComposer
    MaxSize                       int64
    BasePath                      string
    DisableDownload               bool
    DisableTermination            bool
    DisableConcatenation          bool
    EnableExperimentalProtocol    bool  // v2 IETF draft
    NotifyCompleteUploads         bool
    NotifyTerminatedUploads       bool
    NotifyUploadProgress          bool
    NotifyCreatedUploads          bool
    UploadProgressInterval        time.Duration
    RespectForwardedHeaders       bool
    PreUploadCreateCallback       func(HookEvent) (HTTPResponse, FileInfoChanges, error)
    PreFinishResponseCallback     func(HookEvent) (HTTPResponse, error)
    PreUploadTerminateCallback    func(HookEvent) (HTTPResponse, error)
    GracefulRequestCompletionTimeout time.Duration
    AcquireLockTimeout            time.Duration
    NetworkTimeout                time.Duration
    CORS                          *CORSConfig
}

⚠️ Important: When creating your Fiber app, always enable StreamRequestBody: true:

app := fiber.New(fiber.Config{
    StreamRequestBody: true, // required for TUS
})

Without this, fasthttp buffers the entire request body in memory, causing large uploads to hang or exhaust server memory.


Storage Backends

All tusd data stores work out of the box:

Store Import
FileStore github.com/tus/tusd/v2/pkg/filestore
S3Store github.com/tus/tusd/v2/pkg/s3store
GCSStore github.com/tus/tusd/v2/pkg/gcsstore
AzureStore github.com/tus/tusd/v2/pkg/azurestore

Troubleshooting

Symptom Cause Fix
Upload hangs / request pending StreamRequestBody: true not set in fiber.Config Add StreamRequestBody: true (see Quick Start)
Upload hangs with notifications enabled Notification channels are unbuffered and nobody is draining them Set Notify* to false, or drain channels in a goroutine
PATCH returns 404 BasePath doesn't match actual route path when using Fiber groups Register directly on app (not a group), or set BasePath to include the group prefix
CORS preflight (OPTIONS) blocked Auth middleware rejecting OPTIONS before CORS middleware runs Make sure auth middleware skips MethodOptions requests

Comparison

Feature tusd (net/http) tusdfiber (Fiber)
Native Fiber handler
Streaming body
TUS v1 protocol
IETF draft protocol
Storage backends ✅ (same, via import)
File / HTTP / gRPC hooks ✅ (same, via import)
Prometheus metrics
Callback hooks
Unit tests ✅ (51 tests)
Dependencies net/http only Fiber + fasthttp

Architecture

┌──────────────────────────────────────────────────┐
│                  Fiber App                        │
│  ┌────────────────────────────────────────────┐   │
│  │  DefaultMiddlewareStack                     │   │
│  │  ├─ MethodOverrideMiddleware()              │   │
│  │  ├─ CORSMiddleware()                        │   │
│  │  └─ TusResumableMiddleware()                │   │
│  │  ┌─ MetricsMiddleware()         (optional)  │   │
│  └────────────────────────────────────────────┘   │
│  ┌────────────────────────────────────────────┐   │
│  │  Handler.Register()                        │   │
│  │  POST   /files     → PostFile / PostFileV2 │   │
│  │  HEAD   /files/:id → HeadFile              │   │
│  │  PATCH  /files/:id → PatchFile             │   │
│  │  GET    /files/:id → GetFile               │   │
│  │  DELETE /files/:id → DelFile               │   │
│  │  OPTIONS /files    → Options               │   │
│  └────────────────────────────────────────────┘   │
│  ┌────────────────────────────────────────────┐   │
│  │  UnroutedHandler                           │   │
│  │  ├─ BodyReader (fasthttp streaming)        │   │
│  │  ├─ Context  (delayed cancellation)        │   │
│  │  ├─ Hooks    (file/HTTP/gRPC via tusd)     │   │
│  │  └─ StoreComposer → tusd DataStore         │   │
│  └────────────────────────────────────────────┘   │
│  ┌────────────────────────────────────────────┐   │
│  │  /metrics  →  Prometheus                   │   │
│  └────────────────────────────────────────────┘   │
└──────────────────────────────────────────────────┘

Testing

# All tests (unit + integration)
go test -v -count=1 -race ./...

# Just helper tests
go test -v -count=1 -run 'Test(Parse|Serialize|Validate|Body|Config|New|TUSError)' .

# Just HTTP integration tests
go test -v -count=1 -run 'TestHandler_' .

# Just E2E example tests (uses filestore, real TUS upload cycle)
go test -v -count=1 ./example/

Tests cover:

Layer File Tests
Helpers — metadata, concat, upload length, content-type tusdfiber_test.go 20
Body reader — streaming, limits, error handling tusdfiber_test.go 4
Config validation — defaults, missing fields, path normalization tusdfiber_test.go 4
Handler integration — POST, HEAD, PATCH, GET, DELETE via fiber.Test() handler_test.go 11
Draft protocol — v2 OPTIONS with Upload-Draft-Interop-Version handler_test.go 1
E2E example — full TUS cycle + chunked upload + OPTIONS example/example_test.go 3

License

MIT — see LICENSE.

Built on top of tusd by Transloadit and contributors.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrUnsupportedVersion               = NewError("ERR_UNSUPPORTED_VERSION", "missing, invalid or unsupported Tus-Resumable header", http.StatusPreconditionFailed)
	ErrMaxSizeExceeded                  = NewError("ERR_MAX_SIZE_EXCEEDED", "maximum size exceeded", http.StatusRequestEntityTooLarge)
	ErrInvalidContentType               = NewError("ERR_INVALID_CONTENT_TYPE", "missing or invalid Content-Type header", http.StatusBadRequest)
	ErrInvalidUploadLength              = NewError("ERR_INVALID_UPLOAD_LENGTH", "missing or invalid Upload-Length header", http.StatusBadRequest)
	ErrInvalidOffset                    = NewError("ERR_INVALID_OFFSET", "missing or invalid Upload-Offset header", http.StatusBadRequest)
	ErrNotFound                         = NewError("ERR_UPLOAD_NOT_FOUND", "upload not found", http.StatusNotFound)
	ErrFileLocked                       = NewError("ERR_UPLOAD_LOCKED", "file currently locked", http.StatusLocked)
	ErrLockTimeout                      = NewError("ERR_LOCK_TIMEOUT", "failed to acquire lock before timeout", http.StatusInternalServerError)
	ErrMismatchOffset                   = NewError("ERR_MISMATCHED_OFFSET", "mismatched offset", http.StatusConflict)
	ErrSizeExceeded                     = NewError("ERR_UPLOAD_SIZE_EXCEEDED", "upload's size exceeded", http.StatusRequestEntityTooLarge)
	ErrNotImplemented                   = NewError("ERR_NOT_IMPLEMENTED", "feature not implemented", http.StatusNotImplemented)
	ErrUploadNotFinished                = NewError("ERR_UPLOAD_NOT_FINISHED", "one of the partial uploads is not finished", http.StatusBadRequest)
	ErrInvalidConcat                    = NewError("ERR_INVALID_CONCAT", "invalid Upload-Concat header", http.StatusBadRequest)
	ErrConcatenationUnsupported         = NewError("ERR_CONCATENATION_UNSUPPORTED", "Upload-Concat header is not supported by server", http.StatusBadRequest)
	ErrModifyFinal                      = NewError("ERR_MODIFY_FINAL", "modifying a final upload is not allowed", http.StatusForbidden)
	ErrUploadLengthAndUploadDeferLength = NewError("ERR_AMBIGUOUS_UPLOAD_LENGTH", "provided both Upload-Length and Upload-Defer-Length", http.StatusBadRequest)
	ErrInvalidUploadDeferLength         = NewError("ERR_INVALID_UPLOAD_LENGTH_DEFER", "invalid Upload-Defer-Length header", http.StatusBadRequest)
	ErrUploadStoppedByServer            = NewError("ERR_UPLOAD_STOPPED", "upload has been stopped by server", http.StatusBadRequest)
	ErrUploadRejectedByServer           = NewError("ERR_UPLOAD_REJECTED", "upload creation has been rejected by server", http.StatusBadRequest)
	ErrUploadTerminationRejected        = NewError("ERR_UPLOAD_TERMINATION_REJECTED", "upload termination has been rejected by server", http.StatusBadRequest)
	ErrUploadInterrupted                = NewError("ERR_UPLOAD_INTERRUPTED", "upload has been interrupted by another request for this upload resource", http.StatusBadRequest)
	ErrServerShutdown                   = NewError("ERR_SERVER_SHUTDOWN", "request has been interrupted because the server is shutting down", http.StatusServiceUnavailable)
	ErrOriginNotAllowed                 = NewError("ERR_ORIGIN_NOT_ALLOWED", "request origin is not allowed", http.StatusForbidden)
	ErrUnexpectedEOF                    = NewError("ERR_UNEXPECTED_EOF", "server expected to receive more bytes", http.StatusBadRequest)
	ErrReadTimeout                      = NewError("ERR_READ_TIMEOUT", "timeout while reading request body", http.StatusInternalServerError)
	ErrConnectionReset                  = NewError("ERR_CONNECTION_RESET", "TCP connection reset by peer", http.StatusInternalServerError)
)

Standard TUS protocol errors.

AvailableHooks lists all supported hook types.

View Source
var DefaultCORSConfig = CORSConfig{
	Disable:          false,
	AllowOrigin:      regexp.MustCompile(".*"),
	AllowCredentials: false,
	AllowMethods:     "POST, HEAD, PATCH, OPTIONS, GET, DELETE",
	AllowHeaders: "Authorization, Origin, X-Requested-With, X-Request-ID, " +
		"X-HTTP-Method-Override, Content-Type, Upload-Length, Upload-Offset, " +
		"Tus-Resumable, Upload-Metadata, Upload-Defer-Length, Upload-Concat, " +
		"Upload-Incomplete, Upload-Complete, Upload-Draft-Interop-Version",
	MaxAge: "86400",
	ExposeHeaders: "Upload-Offset, Location, Upload-Length, Tus-Version, " +
		"Tus-Resumable, Tus-Max-Size, Tus-Extension, Upload-Metadata, " +
		"Upload-Defer-Length, Upload-Concat, Upload-Incomplete, " +
		"Upload-Complete, Upload-Draft-Interop-Version",
}

DefaultCORSConfig is used when Config.CORS is nil.

Functions

func CORSMiddleware

func CORSMiddleware(cfg *CORSConfig) fiber.Handler

CORSMiddleware returns a Fiber handler that adds CORS headers and handles preflight OPTIONS requests according to the TUS protocol. If cfg is nil, the DefaultCORSConfig is used.

func CompileAllowOrigin

func CompileAllowOrigin(pattern string) *regexp.Regexp

CompileAllowOrigin compiles a regex string into a *regexp.Regexp. Useful when building config from user input.

func DefaultMiddlewareStack

func DefaultMiddlewareStack(cfg *CORSConfig) []fiber.Handler

DefaultMiddlewareStack returns the standard TUS middleware chain: MethodOverride → CORS → TusResumable. You can use this if you need to compose the middleware manually.

func MethodOverrideMiddleware

func MethodOverrideMiddleware() fiber.Handler

MethodOverrideMiddleware allows clients to override the HTTP method using the X-HTTP-Method-Override header. Required for environments that do not support PATCH / DELETE (e.g. older browsers, Flash).

func PrometheusHandler added in v1.0.2

func PrometheusHandler() fiber.Handler

PrometheusHandler returns a Fiber-native handler that renders Prometheus metrics in text format. No adaptor needed.

app.Get("/metrics", m.Middleware(), tusdfiber.PrometheusHandler())

func RegisterStopCallback

func RegisterStopCallback(id string, fn func(HTTPResponse))

RegisterStopCallback stores a callback that can stop an upload mid-stream. The callback is invoked when a hook returns StopUpload: true.

func TusResumableMiddleware

func TusResumableMiddleware() fiber.Handler

TusResumableMiddleware checks that the Tus-Resumable header is present on mutating requests (POST, PATCH, DELETE), or that Upload-Draft-Interop-Version is present if the experimental protocol is enabled. GET and HEAD are allowed without it.

func UnregisterStopCallback

func UnregisterStopCallback(id string)

UnregisterStopCallback removes a previously registered stop callback.

func ValidateCORSOrigin

func ValidateCORSOrigin(cfg *CORSConfig) fiber.Handler

ValidateCORSOrigin checks if the Origin header matches the allowed pattern.

Types

type CORSConfig

type CORSConfig struct {
	// Disable skips all CORS handling.
	Disable bool

	// AllowOrigin is a regex that the Origin header must match.
	AllowOrigin *regexp.Regexp

	// AllowCredentials includes Access-Control-Allow-Credentials: true.
	AllowCredentials bool

	// AllowMethods is the value of Access-Control-Allow-Methods.
	AllowMethods string

	// AllowHeaders is the value of Access-Control-Allow-Headers.
	AllowHeaders string

	// MaxAge is the value of Access-Control-Max-Age.
	MaxAge string

	// ExposeHeaders is the value of Access-Control-Expose-Headers.
	ExposeHeaders string
}

CORSConfig controls Cross-Origin Resource Sharing behaviour.

type ConcatableUpload

type ConcatableUpload = tusd.ConcatableUpload

Type aliases for core tusd types.

type ConcaterDataStore

type ConcaterDataStore = tusd.ConcaterDataStore

Type aliases for core tusd types.

type Config

type Config struct {
	// StoreComposer composes the core data store and optional extensions.
	StoreComposer *StoreComposer

	// MaxSize is the maximum upload size in bytes (0 = no limit).
	MaxSize int64

	// BasePath is the URL prefix for uploads, e.g. "/files/".
	// If no trailing slash is present, one will be added.
	BasePath string

	// DisableDownload removes the GET / download endpoint.
	DisableDownload bool

	// DisableTermination removes the DELETE endpoint.
	DisableTermination bool

	// DisableConcatenation rejects Upload-Concat headers.
	DisableConcatenation bool

	// NotifyCompleteUploads enables the CompleteUploads notification channel.
	NotifyCompleteUploads bool

	// NotifyTerminatedUploads enables the TerminatedUploads notification channel.
	NotifyTerminatedUploads bool

	// NotifyUploadProgress enables the UploadProgress notification channel.
	NotifyUploadProgress bool

	// NotifyCreatedUploads enables the CreatedUploads notification channel.
	NotifyCreatedUploads bool

	// UploadProgressInterval controls how often progress notifications are emitted.
	UploadProgressInterval time.Duration

	// RespectForwardedHeaders makes the handler read X-Forwarded-* / Forwarded headers.
	RespectForwardedHeaders bool

	// PreUploadCreateCallback is called before a new upload is created.
	// Return an error to reject the upload.
	PreUploadCreateCallback func(hook HookEvent) (HTTPResponse, FileInfoChanges, error)

	// PreFinishResponseCallback is called after an upload is completed.
	PreFinishResponseCallback func(hook HookEvent) (HTTPResponse, error)

	// PreUploadTerminateCallback is called before an upload is terminated.
	PreUploadTerminateCallback func(hook HookEvent) (HTTPResponse, error)

	// GracefulRequestCompletionTimeout is the time given to stores after a request ends.
	GracefulRequestCompletionTimeout time.Duration

	// AcquireLockTimeout is the maximum time to wait for an upload lock.
	AcquireLockTimeout time.Duration

	// NetworkTimeout is the read deadline for individual body reads.
	NetworkTimeout time.Duration

	// EnableExperimentalProtocol enables the IETF resumable upload draft
	// (Upload-Draft-Interop-Version) next to the TUS v1 protocol.
	EnableExperimentalProtocol bool

	// CORS configuration. If nil, DefaultCORSConfig is used.
	CORS *CORSConfig
	// contains filtered or unexported fields
}

Config configures the TUS handler for Fiber.

type ContentServerDataStore

type ContentServerDataStore = tusd.ContentServerDataStore

Type aliases for core tusd types.

type DataStore

type DataStore = tusd.DataStore

Type aliases for core tusd types.

type FileInfo

type FileInfo = tusd.FileInfo

Type aliases for core tusd types.

type FileInfoChanges

type FileInfoChanges = tusd.FileInfoChanges

Type aliases for core tusd types.

type HTTPHeader

type HTTPHeader = tusd.HTTPHeader

All HTTP types are aliased from tusd for full compatibility.

type HTTPRequest

type HTTPRequest = tusd.HTTPRequest

All HTTP types are aliased from tusd for full compatibility.

type HTTPResponse

type HTTPResponse = tusd.HTTPResponse

All HTTP types are aliased from tusd for full compatibility.

type Handler

type Handler struct {
	*UnroutedHandler
	// contains filtered or unexported fields
}

Handler wraps an UnroutedHandler with Fiber-native route registration. Create one via NewHandler, then call Register() or use Middleware().

func NewHandler

func NewHandler(config Config) (*Handler, error)

NewHandler creates a TUS Handler that auto-registers all TUS protocol routes on a Fiber router when you call Register().

func NewHandlerWithHooks

func NewHandlerWithHooks(cfg Config, hookHandler HookHandler, enabledHooks []HookType) (*Handler, error)

NewHandlerWithHooks creates a TUS Fiber handler whose callbacks and notification channels are wired to invoke the given HookHandler. It accepts the same Config as NewHandler.

This lets you use tusd's file hooks, HTTP hooks, gRPC hooks, or plugin hooks.

Example (file hooks):

hookHandler := &filehook.FileHook{Directory: "./hooks"}
handler, err := tusdfiber.NewHandlerWithHooks(config, hookHandler, tusdfiber.AvailableHooks)

func (*Handler) Middleware

func (h *Handler) Middleware() fiber.Handler

Middleware returns a Fiber handler that routes TUS requests internally. It is a convenience for cases where you want to mount it on a sub-router:

sub := app.Group("/files")
sub.Use("/", handler.Middleware())

func (*Handler) Register

func (h *Handler) Register(base fiber.Router)

Register mounts all TUS protocol endpoints on the given Fiber router (app, group, or custom router) at the configured BasePath.

Example:

app := fiber.New()
handler, _ := tusdfiber.NewHandler(config)
handler.Register(app)   // routes under /files/

type HookEvent

type HookEvent struct {
	Upload      FileInfo
	HTTPRequest HTTPRequest
}

HookEvent is an event from tusd that can be handled by the application.

type HookHandler

type HookHandler = tusdhooks.HookHandler

Re-export tusd hook types for convenience.

type HookRequest

type HookRequest = tusdhooks.HookRequest

Re-export tusd hook types for convenience.

type HookResponse

type HookResponse = tusdhooks.HookResponse

Re-export tusd hook types for convenience.

type HookType

type HookType = tusdhooks.HookType

Re-export tusd hook types for convenience.

const (
	HookPostFinish    HookType = "post-finish"
	HookPostTerminate HookType = "post-terminate"
	HookPostReceive   HookType = "post-receive"
	HookPostCreate    HookType = "post-create"
	HookPreCreate     HookType = "pre-create"
	HookPreFinish     HookType = "pre-finish"
	HookPreTerminate  HookType = "pre-terminate"
)

Standard hook types.

type LengthDeclarableUpload

type LengthDeclarableUpload = tusd.LengthDeclarableUpload

Type aliases for core tusd types.

type LengthDeferrerDataStore

type LengthDeferrerDataStore = tusd.LengthDeferrerDataStore

Type aliases for core tusd types.

type Lock

type Lock = tusd.Lock

Type aliases for core tusd types.

type Locker

type Locker = tusd.Locker

Type aliases for core tusd types.

type MetaData

type MetaData = tusd.MetaData

Type aliases for core tusd types.

type Metrics

type Metrics struct {
	UploadsCreated    prometheus.Counter
	UploadsFinished   prometheus.Counter
	UploadsTerminated prometheus.Counter
	BytesReceived     prometheus.Counter
	ErrorsTotal       *prometheus.CounterVec
	RequestsTotal     *prometheus.CounterVec
	ActiveUploads     prometheus.Gauge
}

Metrics holds Prometheus collectors for TUS operations.

func NewMetrics

func NewMetrics(reg prometheus.Registerer) *Metrics

NewMetrics registers and returns TUS metrics with the given Prometheus registerer.

func (*Metrics) Middleware

func (m *Metrics) Middleware() fiber.Handler

Middleware returns a Fiber handler that counts requests and active uploads.

type ServableUpload

type ServableUpload = tusd.ServableUpload

Type aliases for core tusd types.

type StoreComposer

type StoreComposer struct {
	*tusd.StoreComposer
}

StoreComposer is a thin wrapper around tusd's StoreComposer. It composes core data stores with optional extensions (locker, terminator, etc.).

func NewStoreComposer

func NewStoreComposer() *StoreComposer

NewStoreComposer creates a fresh StoreComposer.

func (*StoreComposer) Capabilities

func (sc *StoreComposer) Capabilities() string

Capabilities returns a human-readable string of supported extensions.

type TUSError

type TUSError struct {
	Code         string
	Message      string
	HTTPResponse HTTPResponse
}

TUSError represents a TUS protocol error with an associated HTTP status code.

func NewError

func NewError(code, message string, statusCode int) *TUSError

NewError creates a new TUS protocol error.

func (*TUSError) Error

func (e *TUSError) Error() string

type TerminatableUpload

type TerminatableUpload = tusd.TerminatableUpload

Type aliases for core tusd types.

type TerminaterDataStore

type TerminaterDataStore = tusd.TerminaterDataStore

Type aliases for core tusd types.

type UnroutedHandler

type UnroutedHandler struct {

	// Notification channels (mirror tusd's interface)
	CompleteUploads   chan HookEvent
	TerminatedUploads chan HookEvent
	UploadProgress    chan HookEvent
	CreatedUploads    chan HookEvent
	// contains filtered or unexported fields
}

UnroutedHandler provides TUS protocol methods (PostFile, HeadFile, PatchFile, …) that you can wire into any router. Use NewUnroutedHandler to create one.

func NewUnroutedHandler

func NewUnroutedHandler(config Config) (*UnroutedHandler, error)

NewUnroutedHandler creates an UnroutedHandler with the given config.

func (*UnroutedHandler) DelFile

func (h *UnroutedHandler) DelFile(c *fiber.Ctx) error

DelFile terminates an upload.

func (*UnroutedHandler) Extensions

func (h *UnroutedHandler) Extensions() string

Extensions returns a comma-separated list of supported tus extensions.

func (*UnroutedHandler) GetFile

func (h *UnroutedHandler) GetFile(c *fiber.Ctx) error

GetFile serves the uploaded content for download.

func (*UnroutedHandler) HeadFile

func (h *UnroutedHandler) HeadFile(c *fiber.Ctx) error

HeadFile returns the upload offset and metadata.

func (*UnroutedHandler) Options

func (h *UnroutedHandler) Options(c *fiber.Ctx) error

Options handles OPTIONS requests for protocol discovery.

func (*UnroutedHandler) PatchFile

func (h *UnroutedHandler) PatchFile(c *fiber.Ctx) error

PatchFile appends a chunk to an upload.

func (*UnroutedHandler) PostFile

func (h *UnroutedHandler) PostFile(c *fiber.Ctx) error

PostFile creates a new upload resource.

func (*UnroutedHandler) PostFileV2

func (h *UnroutedHandler) PostFileV2(c *fiber.Ctx) error

PostFileV2 creates an upload using the IETF resumable upload draft protocol.

type Upload

type Upload = tusd.Upload

Type aliases for core tusd types.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL