tus

package module
v0.0.0-...-7827b12 Latest Latest
Warning

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

Go to latest
Published: Jun 12, 2025 License: MIT Imports: 11 Imported by: 70

README

go-tus Build Status Go Report Card GoDoc

A pure Go client for the tus resumable upload protocol

Example

package main

import (
    "os"
    "github.com/eventials/go-tus"
)

func main() {
    f, err := os.Open("my-file.txt")

    if err != nil {
        panic(err)
    }

    defer f.Close()

    // create the tus client.
    client, _ := tus.NewClient("https://tus.example.org/files", nil)

    // create an upload from a file.
    upload, _ := tus.NewUploadFromFile(f)

    // create the uploader.
    uploader, _ := client.CreateUpload(upload)

    // start the uploading process.
    uploader.Upload()
}

Example with resume

package main

import (
	"fmt"
	"os"
	"time"

	"github.com/eventials/go-tus"
	"github.com/eventials/go-tus/memorystore"
)

func main() {
	// Open the file
	file, err := os.Open(`/path/to/your/file.txt`)
	if err != nil {
		panic(err)
	}
	defer file.Close()
	// Create a MemoryStore also can be LeveldbStore or you can implement your own store
	store, err := memorystore.NewMemoryStore()
	if err != nil {
		panic(err)
	}
	// Create a Client
	client, err := tus.NewClient("http://tus.example.org/files/", &tus.Config{
		Resume:    true,    // Important to resume uploads
		Store:     store,   // Important to resume uploads
		ChunkSize: 4 << 20, // 4 Mb
	})
	if err != nil {
		panic(err)
	}
	// (Optional) Create a chan to notify upload status
	uploadChan := make(chan tus.Upload, 1)
	go func() {
		for uploadStatus := range uploadChan {
			// Print the upload status
			fmt.Printf("Completed %v%% %v Bytes of %v Bytes\n",
				uploadStatus.Progress(),
				uploadStatus.Offset(),
				uploadStatus.Size())
		}
	}()
	// Create new upload
	upload, err := tus.NewUploadFromFile(file)
	if err != nil {
		panic(err)
	}
	// Declare number of attempts
	const attemps = 50
	for i := 1; i <= attemps; i++ {
		fmt.Printf("Attemp %v of %v\n", i, attemps)
		// Create an uploader
		uploader, err := client.CreateOrResumeUpload(upload)
		if err != nil {
			fmt.Println("Error", err)
			fmt.Println("Trying again in 10 seg")
			time.Sleep(time.Second * 10)
			continue
		}
		// (Optional) Notify Upload Status
		uploader.NotifyUploadProgress(uploadChan)
		// Start upload to server
		err = uploader.Upload()
		if err != nil {
			fmt.Println("Error", err)
			fmt.Println("Trying again in 10 seg")
			time.Sleep(time.Second * 10)
			continue
		}
		break
	}
	// If after all attemps there's an error panic!
	if err != nil {
		panic(err)
	}
	fmt.Println("Finished!")
}

Features

This is not a full protocol client implementation.

Checksum, Termination and Concatenation extensions are not implemented yet.

This client allows to resume an upload if a Store is used.

Built in Store

Store is used to map an upload's fingerprint with the corresponding upload URL.

Name Backend Dependencies
MemoryStore In-Memory None
LeveldbStore LevelDB goleveldb

Future Work

  • SQLite store
  • Redis store
  • Memcached store
  • Checksum extension
  • Termination extension
  • Concatenation extension

Documentation

Overview

Package tus provides a client to tus protocol version 1.0.0.

tus is a protocol based on HTTP for resumable file uploads. Resumable means that an upload can be interrupted at any moment and can be resumed without re-uploading the previous data again. An interruption may happen willingly, if the user wants to pause, or by accident in case of an network issue or server outage (http://tus.io).

Index

Constants

View Source
const (
	ProtocolVersion = "1.0.0"
)

Variables

View Source
var (
	ErrChuckSize         = errors.New("chunk size must be greater than zero.")
	ErrNilLogger         = errors.New("logger can't be nil.")
	ErrNilStore          = errors.New("store can't be nil if Resume is enable.")
	ErrNilUpload         = errors.New("upload can't be nil.")
	ErrLargeUpload       = errors.New("upload body is to large.")
	ErrVersionMismatch   = errors.New("protocol version mismatch.")
	ErrOffsetMismatch    = errors.New("upload offset mismatch.")
	ErrUploadNotFound    = errors.New("upload not found.")
	ErrResumeNotEnabled  = errors.New("resuming not enabled.")
	ErrFingerprintNotSet = errors.New("fingerprint not set.")
)

Functions

This section is empty.

Types

type Client

type Client struct {
	Config  *Config
	Url     string
	Version string
	Header  http.Header
	// contains filtered or unexported fields
}

Client represents the tus client. You can use it in goroutines to create parallels uploads.

func NewClient

func NewClient(url string, config *Config) (*Client, error)

NewClient creates a new tus client.

func (*Client) CreateOrResumeUpload

func (c *Client) CreateOrResumeUpload(u *Upload) (*Uploader, error)

CreateOrResumeUpload resumes the upload if already created or creates a new upload in the server.

func (*Client) CreateUpload

func (c *Client) CreateUpload(u *Upload) (*Uploader, error)

CreateUpload creates a new upload in the server.

func (*Client) Do

func (c *Client) Do(req *http.Request) (*http.Response, error)

func (*Client) ResumeUpload

func (c *Client) ResumeUpload(u *Upload) (*Uploader, error)

ResumeUpload resumes the upload if already created, otherwise it will return an error.

type ClientError

type ClientError struct {
	Code int
	Body []byte
}

func (ClientError) Error

func (c ClientError) Error() string

type Config

type Config struct {
	// ChunkSize divide the file into chunks.
	ChunkSize int64
	// Resume enables resumable upload.
	Resume bool
	// OverridePatchMethod allow to by pass proxies sendind a POST request instead of PATCH.
	OverridePatchMethod bool
	// Store map an upload's fingerprint with the corresponding upload URL.
	// If Resume is true the Store is required.
	Store Store
	// Set custom header values used in all requests.
	Header http.Header
	// HTTP Client
	HttpClient *http.Client
}

Config provides a way to configure the Client depending on your needs.

func DefaultConfig

func DefaultConfig() *Config

DefaultConfig return the default Client configuration.

func (*Config) Validate

func (c *Config) Validate() error

Validate validates the custom configuration.

type Metadata

type Metadata map[string]string

type Store

type Store interface {
	Get(fingerprint string) (string, bool)
	Set(fingerprint, url string)
	Delete(fingerprint string)
	Close()
}

type Upload

type Upload struct {
	Fingerprint string
	Metadata    Metadata
	// contains filtered or unexported fields
}

func NewUpload

func NewUpload(reader io.Reader, size int64, metadata Metadata, fingerprint string) *Upload

NewUpload creates a new upload from an io.Reader.

func NewUploadFromBytes

func NewUploadFromBytes(b []byte) *Upload

NewUploadFromBytes creates a new upload from a byte array.

func NewUploadFromFile

func NewUploadFromFile(f *os.File) (*Upload, error)

NewUploadFromFile creates a new Upload from an os.File.

func (*Upload) EncodedMetadata

func (u *Upload) EncodedMetadata() string

EncodedMetadata encodes the upload metadata.

func (*Upload) Finished

func (u *Upload) Finished() bool

Returns whether this upload is finished or not.

func (*Upload) Offset

func (u *Upload) Offset() int64

Returns the current upload offset.

func (*Upload) Progress

func (u *Upload) Progress() int64

Returns the progress in a percentage.

func (*Upload) Size

func (u *Upload) Size() int64

Returns the size of the upload body.

type Uploader

type Uploader struct {
	// contains filtered or unexported fields
}

func NewUploader

func NewUploader(client *Client, url string, upload *Upload, offset int64) *Uploader

NewUploader creates a new Uploader.

func (*Uploader) Abort

func (u *Uploader) Abort()

Abort aborts the upload process. It doens't abort the current chunck, only the remaining.

func (*Uploader) IsAborted

func (u *Uploader) IsAborted() bool

IsAborted returns true if the upload was aborted.

func (*Uploader) NotifyUploadProgress

func (u *Uploader) NotifyUploadProgress(c chan Upload)

Subscribes to progress updates.

func (*Uploader) Offset

func (u *Uploader) Offset() int64

Offset returns the current offset uploaded.

func (*Uploader) Upload

func (u *Uploader) Upload() error

Upload uploads the entire body to the server.

func (*Uploader) UploadChunck

func (u *Uploader) UploadChunck() error

UploadChunck uploads a single chunck.

func (*Uploader) Url

func (u *Uploader) Url() string

Url returns the upload url.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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