0

I'm writing my first golang api with aws lambda. The idea being to be able to record audio from a browser and save as an object in s3. I've gotten to the point of being able to save an object in the desired location in the s3 bucket, but the file is always size 0 / 0 kbs. But when I create a file and write to it, it has size.

Here's my go code:

func Handler(ctx context.Context, event PutAudiosEvent) (string, error) {
    decoded, err := base64.StdEncoding.DecodeString(event.FileContents)
    if err != nil {
        fmt.Println("Error decoding string")
        return "", err
    }
    //fmt.Println("Decoded is:", decoded)

    f, err := os.Create("/tmp/" + event.FileName)
    if err != nil {
        fmt.Println("Error creating file")
        return "", err
    }
    defer f.Close()

    numBytes, err := f.Write(decoded)
    fmt.Println("Num bytes:", numBytes)
    if err != nil {
        fmt.Println("Error writing")
        return "", err
    }

    if err = f.Sync(); err != nil {
        fmt.Println("Error syncing")
        return "", err
    }

    fileInfo, err := f.Stat()
    fmt.Println("Size:", fileInfo.Size())
    fmt.Println("Name:", fileInfo.Name())
    fmt.Println("Is dir:", fileInfo.IsDir())
    fmt.Println("Mode:", fileInfo.Mode())
    fmt.Println("Modtime", fileInfo.ModTime())
    fmt.Println("fileSys:", fileInfo.Sys())

    fmt.Println(event.UserName + "/" + event.Course + "/" + event.FileName)
    resp, err := s3Uploader.Upload(&s3manager.UploadInput{
        Bucket: aws.String(BUCKET_NAME),
        Key: aws.String(event.UserName + "/" + event.Course + "/" + event.Type + "/" + event.FileName),
        Body: f,
        ContentType: aws.String("audio/mpeg"),
    })

    if err != nil {
        fmt.Println("Error uploading", err)
        fmt.Println("Resp is:", resp)
        return "Error2", nil
    }

    return "File named '" + event.FileName + "' successfully uploaded", nil
}

Here's some of the output from cloudwatch: enter image description here

And here's the empty object:

enter image description here

So what am I doing wrong?

5
  • 3
    Try Seek before upload? Commented Feb 26, 2021 at 14:05
  • That was it, thanks! Commented Feb 26, 2021 at 14:31
  • 2
    Simplify the code by reading directly from memory: Body: bytes.NewReader(decoded), Commented Feb 26, 2021 at 16:24
  • 1
    …but should you ever need to actually have a temp. file, please use io/ioutil.TempFile. Commented Feb 26, 2021 at 16:27
  • ...or, as of Go 1.16, for a temp file, os.CreateTemp Commented Feb 28, 2021 at 1:48

1 Answer 1

4

You have just created and written to the file f, and then you're using it as the upload Body. What happens is that the current position in the file is in the very end — this means that there are 0 bytes to read.

You need to Seek to the beginning of the file, so that there's data to be read.

Either way, for this use case it's unnecessary to write the file to storage prior to the upload — you can just upload it directly to S3 using the in-memory representation you already have in decoded.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.