tus / tusd

Reference server implementation in Go of tus: the open protocol for resumable file uploads
https://tus.github.io/tusd
MIT License
3.04k stars 475 forks source link

Trying to use tusd as a package and getting a 'method not allowed' error on upload #1053

Closed adrianocr closed 9 months ago

adrianocr commented 9 months ago

Describe the bug I'm trying to use tusd as a package so I can integrate it into my current environment and make use of the hooks functionality without needing a separate plugin file or bash scripts. I based my setup from the tusd "use as a package" docs along with what is going on in /cmd/tusd/cli/composer.go

My main.go file is the following:

package main

import (
    "context"
    "fmt"
    "log"
    "net/http"
    "os"

    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
    tusd "github.com/tus/tusd/v2/pkg/handler"
    "github.com/tus/tusd/v2/pkg/s3store"
)

func main() {
    bucket := os.Getenv("S3_BUCKET")
    endpoint := "https://" + os.Getenv("S3_ENDPOINT")
    s3Config, err := config.LoadDefaultConfig(context.Background())
    if err != nil {
        log.Fatalf("Unable to load S3 configuration: %s", err)
    }

    s3Client := s3.NewFromConfig(s3Config, func(o *s3.Options) {
        o.BaseEndpoint = &endpoint
        o.UsePathStyle = true
        o.EndpointOptions.DisableHTTPS = true
    })

    store := s3store.New(bucket, s3Client)
    store.ObjectPrefix = ""
    store.PreferredPartSize = 50 * 1024 * 1024
    store.MaxBufferedParts = 20
    store.DisableContentHashes = false
    store.SetConcurrentPartUploads(10)

    // A storage backend for tusd may consist of multiple different parts which
    // handle upload creation, locking, termination and so on. The composer is a
    // place where all those separated pieces are joined together. In this example
    // we only use the file store but you may plug in multiple.
    composer := tusd.NewStoreComposer()
    store.UseIn(composer)

    // Create a new HTTP handler for the tusd server by providing a configuration.
    // The StoreComposer property must be set to allow the handler to function.
    handler, err := tusd.NewHandler(tusd.Config{
        BasePath:              "/files/",
        StoreComposer:         composer,
        NotifyCompleteUploads: true,
    })
    if err != nil {
        panic(fmt.Errorf("unable to create handler: %s", err))
    }

    // Start another goroutine for receiving events from the handler whenever
    // an upload is completed. The event will contains details about the upload
    // itself and the relevant HTTP request.
    go func() {
        for {
            event := <-handler.CompleteUploads
            fmt.Printf("Upload %s finished\n", event.Upload.ID)
        }
    }()

    // Right now, nothing has happened since we need to start the HTTP server on
    // our own. In the end, tusd will start listening on and accept request at
    // http://localhost:8080/files
    http.Handle("/files/", http.StripPrefix("/files/", handler))
    err = http.ListenAndServe(":8080", nil)
    if err != nil {
        panic(fmt.Errorf("Unable to listen: %s", err))
    }
}

When I run it, everything seems to be fine. But when uppy tries to upload files to http://localhost:8080/files/ I get the following errors:

2023/12/22 21:47:00 INFO RequestIncoming method=OPTIONS path="" requestId=""
2023/12/22 21:47:00 INFO ResponseOutgoing method=OPTIONS path="" requestId="" status=200 body=""
2023/12/22 21:47:00 INFO RequestIncoming method=POST path="" requestId=""
2023/12/22 21:47:00 ERROR InternalServerError method=POST path="" requestId="" message="s3store: unable to create multipart upload:\noperation error S3: CreateMultipartUpload, https response error StatusCode: 405, RequestID: 4387F83A653F0C18:A, HostID: TU45y96Is9fkMqUV6um5rWF5I/xYUwc8XPs5IxnX197J3kcCZuFoK+G8P64pYQlLdiSlizIgGtV9, api error MethodNotAllowed: The specified method is not allowed against this resource."
2023/12/22 21:47:00 INFO ResponseOutgoing method=POST path="" requestId="" status=500 body="ERR_INTERNAL_SERVER_ERROR: s3store: unable to create multipart upload:\noperation error S3: CreateMultipartUpload, https response error StatusCode: 405, RequestID: 4387F83A653F0C18:A, HostID: TU45y96Is9fkMqUV6um5rWF5I/xYUwc8XPs5IxnX197J3kcCZuFoK+G8P64pYQlLdiSlizIgGtV9, api error MethodNotAllowed: The specified method is not allowed against this resource.\n"

Is something wrong in my setup or config?

adrianocr commented 9 months ago

Oddly I somehow resolved this. I believe it had something to do with the AWS packages. I zeroed out my go.mod file and then reinstalled the tus package and s3store package and then... viola. Everything works now 🤷🏻‍♂️