Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
65932e9
Add generated TUS protocol contract canary
kvz May 26, 2026
177b8f8
Regenerate TUS protocol contract fixture
kvz May 26, 2026
e91f12a
Regenerate TUS feature contract fixture
kvz May 26, 2026
15d1231
Regenerate upload body protocol fixture
kvz May 27, 2026
4e92795
Assert generated TUS upload events
kvz May 28, 2026
deab9a5
Cover TUS request lifecycle conformance
kvz May 28, 2026
50a702f
Cover TUS abort conformance
kvz May 29, 2026
ed1f367
Cover TUS URL storage conformance
kvz May 29, 2026
af4d6ca
Cover TUS relative Location conformance
kvz May 29, 2026
907218a
Refresh TUS input source contract
kvz May 29, 2026
d9ca945
Refresh TUS retry state contract
kvz May 29, 2026
74cee7c
Refresh TUS URL storage contract
kvz May 29, 2026
f8a871b
Refresh TUS protocol selection contract
kvz May 29, 2026
95952fe
Refresh TUS start validation contract
kvz May 29, 2026
8da958d
Update detailed error conformance
kvz May 29, 2026
8883866
Add generated URL storage backend
kvz May 30, 2026
290220e
Add generated URL storage resume flow
kvz May 30, 2026
f009da6
Add generated URL storage create flow
kvz May 30, 2026
618236d
Add generated file upload helper
kvz May 30, 2026
9a30c6a
Add generated file-backed upload helper
kvz May 30, 2026
1274cd6
Add generated retry offset recovery flow
kvz May 30, 2026
e5db73f
Add generated termination retry flow
kvz May 30, 2026
9096f2d
Add generated request lifecycle hooks
kvz May 30, 2026
de17f62
Add generated upload event hooks
kvz May 30, 2026
a03bc15
Add generated upload success hooks
kvz May 30, 2026
86eef80
Add generated upload abort context
kvz May 30, 2026
7a4045e
Add generated abort termination flow
kvz May 30, 2026
90c44a0
Add generated parallel upload flow
kvz May 30, 2026
c002eec
Add generated parallel cleanup flow
kvz May 31, 2026
b305045
Add generated creation extension flows
kvz May 31, 2026
300ee80
Add generated creation continuation validation
kvz May 31, 2026
de35f87
Add generated request policy flows
kvz May 31, 2026
a2660c6
Add generated abort request policy
kvz May 31, 2026
66248b7
Add generated parallel cleanup request policy
kvz May 31, 2026
262b456
Regenerate TUS protocol fixture
kvz May 31, 2026
4b9898b
Emit creation upload chunk completion
kvz Jun 1, 2026
a265686
Use generated TUS event policies
kvz Jun 1, 2026
27d2214
Assert generated TUS retry events
kvz Jun 1, 2026
a3c66e0
Use generated TUS termination execution hints
kvz Jun 1, 2026
30df86e
Use generated TUS request-start cancellation hints
kvz Jun 1, 2026
cb24023
Use generated TUS parallel request gates
kvz Jun 1, 2026
69eb89d
Expose TUS managed upload contract
kvz Jun 1, 2026
55a8567
Expose managed upload proof cases
kvz Jun 1, 2026
5cd3279
Update managed upload proof fixture
kvz Jun 1, 2026
bf1a839
Update managed upload proof fixture
kvz Jun 1, 2026
64583ef
Update managed upload proof fixture
kvz Jun 1, 2026
b812d95
Update managed upload proof fixture
kvz Jun 1, 2026
ab13e22
Update generated protocol contract fixture
kvz Jun 1, 2026
ac05505
Update generated managed upload contract
kvz Jun 1, 2026
6f075b9
Add devdock Transloadit upload example
kvz Jun 1, 2026
2df2b65
Use prepared Assembly in devdock example
kvz Jun 1, 2026
21f47ca
Regenerate TUS URL storage proofs
kvz Jun 3, 2026
fd9cd69
Use generated TUS header defaults
kvz Jun 3, 2026
f27b23f
Use generated protocol header defaults
kvz Jun 3, 2026
9e80f85
Add generated TUS request ID proof
kvz Jun 4, 2026
2371b94
Use generated TUS method override table
kvz Jun 4, 2026
efe9d87
Derive parallel TUS header assertions
kvz Jun 4, 2026
1e9b633
Derive creation and deferred TUS headers
kvz Jun 4, 2026
41f8c9f
Derive retry TUS header assertions
kvz Jun 4, 2026
2ed094f
Derive event TUS header assertions
kvz Jun 4, 2026
e03d996
Derive create TUS header assertions
kvz Jun 4, 2026
b0ee935
Derive remaining TUS header assertions
kvz Jun 4, 2026
9c12c19
Regenerate TUS deferred length proofs
kvz Jun 4, 2026
ac042de
Regenerate Go TUS event key helpers
kvz Jun 4, 2026
79729d9
Regenerate Go TUS per-proof event prefixes
kvz Jun 4, 2026
888a1fb
Use generic TUS extra event matching policy
kvz Jun 4, 2026
06883d9
Regenerate TUS event key helpers
kvz Jun 4, 2026
f48657e
Regenerate contract TUS flow tests
kvz Jun 4, 2026
0ae7f60
Regenerate TUS termination retry contract test
kvz Jun 5, 2026
ae0b4a7
Assert abort termination headers
kvz Jun 5, 2026
81605c6
Assert parallel cleanup termination headers
kvz Jun 5, 2026
03f40b3
Regenerate TUS transport fixture
kvz Jun 5, 2026
b1d0e4e
Regenerate TUS protocol response fixtures
kvz Jun 6, 2026
f7a43f0
Add termination devdock example
kvz Jun 6, 2026
c149ad7
Add resume devdock example
kvz Jun 6, 2026
112299d
Fix resume devdock URL storage proof
kvz Jun 6, 2026
b1eb712
Add Go TUS devdock coverage for creation and retry
kvz Jun 7, 2026
828c82f
Add request lifecycle devdock proof
kvz Jun 7, 2026
5f8f15c
Add API2 upload callback proof
kvz Jun 7, 2026
f8bf320
Add API2 custom request headers proof
kvz Jun 7, 2026
309646e
Add API2 request ID headers proof
kvz Jun 7, 2026
a1b364f
Add API2 upload body headers proof
kvz Jun 7, 2026
f6c53c3
Add deferred-length TUS devdock proof
kvz Jun 7, 2026
73cf8f4
Add API2 file URL storage proof
kvz Jun 8, 2026
c4fae1b
Add API2 abort upload proof
kvz Jun 8, 2026
172a7ec
Add API2 override PATCH proof
kvz Jun 8, 2026
6e62371
Add API2 relative Location proof
kvz Jun 8, 2026
cd429da
Add API2 parallel upload proof
kvz Jun 8, 2026
7b5703a
Add API2 retry state proof
kvz Jun 8, 2026
14c4ecd
Match conformance requests by facts
kvz Jun 8, 2026
3370dc3
Add API2 start validation proof
kvz Jun 8, 2026
2321ad3
Add API2 protocol version proof
kvz Jun 8, 2026
6c42eaf
Add Go node path input source proof
kvz Jun 8, 2026
009fbb9
Add Go detailed error proof
kvz Jun 9, 2026
f2a1680
Make repo gofmt-clean
kvz Jun 13, 2026
ff0526b
Use generated Go TUS endpoint paths
kvz Jun 13, 2026
cde1474
Use generated Go TUS request counts
kvz Jun 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion checksum/hash_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,3 @@ var _ = Describe("HashBase64ReadWriter", func() {
})
})
})

21 changes: 17 additions & 4 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
// headed to
func NewClient(client *http.Client, baseURL *url.URL) *Client {
c := &Client{
ProtocolVersion: "1.0.0",
ProtocolVersion: DefaultProtocolVersion,
GetRequest: newRequest,
client: client,
BaseURL: baseURL,
Expand Down Expand Up @@ -49,7 +49,7 @@ type Client struct {
// BaseURL is base url the client making queries to. For example, "http://example.com/files"
BaseURL *url.URL

// ProtocolVersion is TUS protocol version will be used in requests. Default is "1.0.0"
// ProtocolVersion is TUS protocol version will be used in requests. Default is DefaultProtocolVersion.
ProtocolVersion string

// Server capabilities and settings. Use UpdateCapabilities to query the capabilities from a server
Expand Down Expand Up @@ -237,6 +237,9 @@ func (c *Client) CreateUploadWithData(u *Upload, data []byte, remoteSize int64,
s.ChunkSize = int64(len(data)) // Data must be uploaded in one request
s.uploadMethod = http.MethodPost
headers := map[string]string{"Upload-Length": strconv.Itoa(int(remoteSize)), "Upload-Offset": ""}
if headerName, value, ok := protocolUploadCompleteHeader(c.ProtocolVersion, true); ok {
headers[headerName] = value
}
if partial {
headers["Upload-Concat"] = "partial"
}
Expand Down Expand Up @@ -429,8 +432,18 @@ func (c *Client) UpdateCapabilities() (response *http.Response, err error) {
}

func (c *Client) tusRequest(ctx context.Context, req *http.Request) (response *http.Response, err error) {
if req.Method != http.MethodOptions && req.Header.Get("Tus-Resumable") == "" {
req.Header.Set("Tus-Resumable", c.ProtocolVersion)
if req.Method != http.MethodOptions {
requestHeaders, ok := protocolRequestHeaders(c.ProtocolVersion)
if !ok {
err = ErrProtocol.WithText(fmt.Sprintf("unsupported protocol version %q", c.ProtocolVersion))
return
}
for headerName, value := range requestHeaders {
if req.Header.Get(headerName) != "" {
continue
}
req.Header.Set(headerName, value)
}
}
if ctx != nil {
req = req.WithContext(ctx)
Expand Down
90 changes: 90 additions & 0 deletions examples/api2-devdock-transloadit-assembly-upload/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
//go:build api2devdock

package main

import (
"context"
"fmt"
"net/http"
"time"

tusgo "github.com/bdragon300/tusgo"
"github.com/bdragon300/tusgo/examples/api2devdock"
)

func uploadWithTus(
ctx context.Context,
scenario map[string]interface{},
createResponse map[string]interface{},
) (string, error) {
endpointURL, err := api2devdock.TusURL(scenario, createResponse)
if err != nil {
return "", err
}
content, err := api2devdock.ScenarioBytes(scenario)
if err != nil {
return "", err
}
if err := api2devdock.RequireFullFileChunkSize(scenario); err != nil {
return "", err
}
metadata, err := api2devdock.UploadMetadata(scenario, createResponse)
if err != nil {
return "", err
}

client := tusgo.NewClient(http.DefaultClient, endpointURL).WithContext(ctx)
upload := tusgo.Upload{}
if _, err := client.CreateUpload(&upload, int64(len(content)), false, metadata); err != nil {
return "", err
}
if upload.Location == "" {
return "", fmt.Errorf("created upload did not include a Location")
}

stream := tusgo.NewUploadStream(client, &upload)
stream.ChunkSize = tusgo.NoChunked
written, err := stream.Write(content)
if err != nil {
return "", err
}
if written != len(content) {
return "", fmt.Errorf("wrote %d bytes, expected %d", written, len(content))
}
if upload.RemoteOffset != int64(len(content)) {
return "", fmt.Errorf("remote offset %d, expected %d", upload.RemoteOffset, len(content))
}

return upload.Location, nil
}

func main() {
ctx, cancel := context.WithTimeout(context.Background(), 90*time.Second)
defer cancel()

scenario, err := api2devdock.LoadScenario(
"examples/api2-devdock-transloadit-assembly-upload/api2-scenario.json",
)
if err != nil {
api2devdock.Fail("load scenario: %v", err)
}

createResponse, err := api2devdock.CreateResponseFromScenario(scenario)
if err != nil {
api2devdock.Fail("read prepared create response: %v", err)
}

uploadURL, err := uploadWithTus(ctx, scenario, createResponse)
if err != nil {
api2devdock.Fail("upload: %v", err)
}
if err := api2devdock.WriteResult(map[string]interface{}{"uploadUrl": uploadURL}); err != nil {
api2devdock.Fail("write result: %v", err)
}

scenarioID, err := api2devdock.ScenarioID(scenario)
if err != nil {
api2devdock.Fail("read scenario id: %v", err)
}
fmt.Printf("Go TUS SDK devdock scenario %s uploaded to %s\n", scenarioID, uploadURL)
}
Loading
Loading