@@ -20,6 +20,7 @@ import (
2020 "compress/gzip"
2121 "fmt"
2222 "io"
23+ "mime/multipart"
2324 "net/http"
2425 "os"
2526 "path"
@@ -29,6 +30,7 @@ import (
2930 "github.com/schollz/progressbar/v3"
3031
3132 "github.com/livekit/livekit-cli/v2/pkg/util"
33+ "github.com/livekit/protocol/livekit"
3234 "github.com/livekit/protocol/logger"
3335
3436 "github.com/moby/patternmatcher"
5153 }
5254)
5355
54- func UploadTarball (directory string , presignedUrl string , excludeFiles []string , projectType ProjectType ) error {
56+ func UploadTarball (
57+ directory string ,
58+ presignedUrl string ,
59+ presignedPostRequest * livekit.PresignedPostRequest ,
60+ excludeFiles []string ,
61+ projectType ProjectType ,
62+ ) error {
5563 excludeFiles = append (excludeFiles , defaultExcludePatterns ... )
5664
5765 loadExcludeFiles := func (filename string ) (bool , string , error ) {
@@ -274,25 +282,73 @@ func UploadTarball(directory string, presignedUrl string, excludeFiles []string,
274282 }),
275283 )
276284
277- req , err := http .NewRequest ("PUT" , presignedUrl , io .TeeReader (& buffer , uploadProgress ))
285+ if presignedPostRequest != nil {
286+ if err := multipartUpload (presignedPostRequest .Url , presignedPostRequest .Values , & buffer ); err != nil {
287+ return fmt .Errorf ("multipart upload failed: %w" , err )
288+ }
289+ } else {
290+ if err := upload (presignedUrl , & buffer , uploadProgress ); err != nil {
291+ return fmt .Errorf ("upload failed: %w" , err )
292+ }
293+ }
294+
295+ return nil
296+ }
297+
298+ func upload (presignedUrl string , buffer * bytes.Buffer , uploadProgress * progressbar.ProgressBar ) error {
299+ req , err := http .NewRequest ("PUT" , presignedUrl , io .TeeReader (buffer , uploadProgress ))
278300 if err != nil {
279301 return fmt .Errorf ("failed to create request: %w" , err )
280302 }
281303 req .Header .Set ("Content-Type" , "application/gzip" )
282304 req .ContentLength = int64 (buffer .Len ())
283-
284- client := & http.Client {}
285- resp , err := client .Do (req )
305+ resp , err := http .DefaultClient .Do (req )
286306 if err != nil {
287307 return fmt .Errorf ("failed to upload tarball: %w" , err )
288308 }
289309 defer resp .Body .Close ()
290-
291310 if resp .StatusCode != http .StatusOK {
292311 body , _ := io .ReadAll (resp .Body )
293312 return fmt .Errorf ("failed to upload tarball: %d: %s" , resp .StatusCode , body )
294313 }
314+ return nil
315+ }
295316
296- fmt .Println ()
317+ func multipartUpload (presignedURL string , fields map [string ]string , buf * bytes.Buffer ) error {
318+ var b bytes.Buffer
319+ w := multipart .NewWriter (& b )
320+ fileName , ok := fields ["key" ]
321+ if ! ok {
322+ fileName = "upload.tar.gz"
323+ }
324+ for k , v := range fields {
325+ if err := w .WriteField (k , v ); err != nil {
326+ return err
327+ }
328+ }
329+ part , err := w .CreateFormFile ("file" , fileName )
330+ if err != nil {
331+ return err
332+ }
333+ if _ , err := io .Copy (part , buf ); err != nil {
334+ return err
335+ }
336+ if err := w .Close (); err != nil {
337+ return err
338+ }
339+ req , err := http .NewRequest ("POST" , presignedURL , & b )
340+ if err != nil {
341+ return err
342+ }
343+ req .Header .Set ("Content-Type" , w .FormDataContentType ())
344+ resp , err := http .DefaultClient .Do (req )
345+ if err != nil {
346+ return err
347+ }
348+ defer resp .Body .Close ()
349+ if resp .StatusCode != http .StatusOK && resp .StatusCode != http .StatusCreated && resp .StatusCode != http .StatusNoContent {
350+ respBody , _ := io .ReadAll (resp .Body )
351+ return fmt .Errorf ("failed to upload tarball: %d: %s" , resp .StatusCode , respBody )
352+ }
297353 return nil
298354}
0 commit comments