{"id":16761601,"url":"https://github.com/tus/tus-go-client","last_synced_at":"2025-04-10T17:52:22.384Z","repository":{"id":65819161,"uuid":"587875534","full_name":"tus/tus-go-client","owner":"tus","description":"Full-featured Go client for TUS resumable upload protocol","archived":false,"fork":false,"pushed_at":"2024-11-10T08:57:29.000Z","size":178,"stargazers_count":12,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-17T20:21:20.786Z","etag":null,"topics":["golang","tus","tus-protocol"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-01-11T19:46:20.000Z","updated_at":"2025-02-27T11:12:09.000Z","dependencies_parsed_at":"2024-11-24T13:26:28.095Z","dependency_job_id":"d6e67cb1-7a1c-4cb9-9039-3680a86214ae","html_url":"https://github.com/tus/tus-go-client","commit_stats":{"total_commits":56,"total_committers":1,"mean_commits":56.0,"dds":0.0,"last_synced_commit":"4c38cbbdda71fa882fae227c8bce18680d64b0d4"},"previous_names":["tus/tus-go-client","bdragon300/tusgo"],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tus%2Ftus-go-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tus%2Ftus-go-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tus%2Ftus-go-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tus%2Ftus-go-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tus","download_url":"https://codeload.github.com/tus/tus-go-client/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248262434,"owners_count":21074308,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["golang","tus","tus-protocol"],"created_at":"2024-10-13T04:43:00.169Z","updated_at":"2025-04-10T17:52:22.360Z","avatar_url":"https://github.com/tus.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# tusgo\n\n[![codecov](https://codecov.io/gh/bdragon300/tusgo/branch/master/graph/badge.svg?token=ZLI69A7FHO)](https://codecov.io/gh/bdragon300/tusgo)\n[![Go Report Card](https://goreportcard.com/badge/github.com/bdragon300/tusgo)](https://goreportcard.com/report/github.com/bdragon300/tusgo)\n![GitHub Workflow Status (with branch)](https://img.shields.io/github/actions/workflow/status/bdragon300/tusgo/run-tests.yml?branch=master)\n[![Go reference](https://pkg.go.dev/badge/github.com/bdragon300/tusgo)](https://pkg.go.dev/github.com/bdragon300/tusgo)\n![GitHub go.mod Go version (subdirectory of monorepo)](https://img.shields.io/github/go-mod/go-version/bdragon300/tusgo)\n\nFull-featured Go client for [TUS](https://tus.io), a protocol for resumable uploads built on HTTP.\n\nDocumentation is available at [pkg.go.dev](https://pkg.go.dev/github.com/bdragon300/tusgo)\n\n## Features\n\n* Resumable Upload writer with chunked and streamed mode support. Conforms the `io.Writer`/`io.ReaderFrom`, which allows \n  to use the standard utils such as `io.Copy`\n* Client for Upload manipulation such as creation, deletion, concatenation, etc.\n* Intermediate data store (for chunked Uploads) now is only in-memory\n* Server extensions are supported:\n\t* `creation` extension -- upload creation\n\t* `creation-defer-length` -- upload creation without size. Its size is set on the first data transfer\n\t* `creation-with-upload` -- upload creation and data transferring in one HTTP request\n\t* `expiration` -- parsing the upload expiration info\n\t* `checksum` -- data integrity verification for chunked uploads. Many checksum algorithms from Go stdlib are\n\t  supported\n\t* `checksum-trailer` -- data integrity verification for streamed uploads. Checksum hash is calculated for all data\n\t  in stream and is put to HTTP trailer\n\t* `termination` -- deleting uploads from server\n\t* `concatenation` -- merge finished uploads into one\n\t* `concatenation-unfinished` -- merge unfinished uploads (data streams) into one upload\n\n## Installation\n\n```shell\ngo get github.com/bdragon300/tusgo\n```\n\nGo v1.18 or newer is required\n\n## Examples\n\n### Minimal file transfer example\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n)\nimport \"github.com/bdragon300/tusgo\"\n\nfunc main() {\n\tbaseURL, _ := url.Parse(\"http://example.com/files\")\n\tcl := tusgo.NewClient(http.DefaultClient, baseURL)\n\n\t// Assume that the Upload has been created on server earlier with size 1KiB\n\tu := tusgo.Upload{Location: \"http://example.com/files/foo/bar\", RemoteSize: 1024 * 1024}\n\t// Open a file we want to upload\n\tf, err := os.Open(\"/tmp/file.txt\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer f.Close()\n\n\ts := tusgo.NewUploadStream(cl, \u0026u)\n\t// Set stream and file pointers to be equal to the remote pointer\n\tif _, err = s.Sync(); err != nil {\n\t\tpanic(err)\n\t}\n\tif _, err = f.Seek(s.Tell(), io.SeekStart); err != nil {\n\t\tpanic(err)\n\t}\n\t\n\twritten, err := io.Copy(s, f)\n\tif err != nil {\n\t\tpanic(fmt.Sprintf(\"Written %d bytes, error: %s, last response: %v\", written, err, s.LastResponse))\n\t}\n\tfmt.Printf(\"Written %d bytes\\n\", written)\n}\n```\n\n### Create an Upload and transfer the file with retrying on error\n\n```go\npackage main\n\nimport (\n\t\"errors\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\t\"time\"\n)\nimport \"github.com/bdragon300/tusgo\"\n\nfunc UploadWithRetry(dst *tusgo.UploadStream, src *os.File) error {\n\t// Set stream and file pointer to be equal to the remote pointer\n\t// (if we resume the upload that was interrupted earlier)\n\tif _, err := dst.Sync(); err != nil {\n\t\treturn err\n\t}\n\tif _, err := src.Seek(dst.Tell(), io.SeekStart); err != nil {\n\t\treturn err\n\t}\n\n\t_, err := io.Copy(dst, src)\n\tattempts := 10\n\tfor err != nil \u0026\u0026 attempts \u003e 0 {\n\t\tif _, ok := err.(net.Error); !ok \u0026\u0026 !errors.Is(err, tusgo.ErrChecksumMismatch) {\n\t\t\treturn err // Permanent error, no luck\n\t\t}\n\t\ttime.Sleep(5 * time.Second)\n\t\tattempts--\n\t\t_, err = io.Copy(dst, src) // Try to resume the transfer again\n\t}\n\tif attempts == 0 {\n\t\treturn errors.New(\"too many attempts to upload the data\")\n\t}\n\treturn nil\n}\n\nfunc CreateUploadFromFile(f *os.File, cl *tusgo.Client) *tusgo.Upload {\n\tfinfo, err := f.Stat()\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tu := tusgo.Upload{}\n\tif _, err = cl.CreateUpload(\u0026u, finfo.Size(), false, nil); err != nil {\n\t\tpanic(err)\n\t}\n\treturn \u0026u\n}\n\nfunc main() {\n\tbaseURL, _ := url.Parse(\"http://example.com/files\")\n\tcl := tusgo.NewClient(http.DefaultClient, baseURL)\n\n\tf, err := os.Open(\"/tmp/file.txt\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer f.Close()\n\tu := CreateUploadFromFile(f, cl)\n\n\tstream := tusgo.NewUploadStream(cl, u)\n\tif err = UploadWithRetry(stream, f); err != nil {\n\t\tpanic(err)\n\t}\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftus%2Ftus-go-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftus%2Ftus-go-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftus%2Ftus-go-client/lists"}