0
votes

I'm trying to upload an image to the s3 bucket using GoLang. I have mentioned function body of program. Which takes an image file as multipart form data and a file name which I should to save the image in s3.

func uploadImage(res http.ResponseWriter, req *http.Request) {
file, handler, err := req.FormFile("uploaded_file") // uploaded_file is the key(input field name) of the form-data
if err != nil {
    fmt.Println(err)
    return
}

type Resp struct {
    Status   string `json:"status"`
    Filename string `json:"filename"`
}
filename := req.Form.Get("filename")

rnd := render.New()
var Response Resp
Response.Status = "failed"
if filename != "" {
    // define credentials
    awsAccessKey := "KEY"
    awsSecret := "SECRET"
    token := ""
    // set credentials
    creds := credentials.NewStaticCredentials(awsAccessKey, awsSecret, token)
    credentials, err := creds.Get()
    if err != nil {
        fmt.Printf("bad credentials: %s", err)
    }
    fmt.Println(credentials)
    //setup config and s3 settings
    cfg := aws.NewConfig().WithRegion("ap-southeast-1").WithCredentials(creds)

    //create s3 credentail
    svc := s3.New(session.New(), cfg)
    type Sizer interface {
        Size() int64
    }

    size := file.(Sizer).Size()
    // create a buffer of size = images size
    buffer := make([]byte, size)
    file.Read(buffer)
    fileBytes := bytes.NewReader(buffer)
    fileType := http.DetectContentType(buffer)

    path := "mybucketname/" + filename
    params := &s3.PutObjectInput{
        Bucket:        aws.String("mybucketname"),
        Key:           aws.String(path),
        Body:          fileBytes,
        ContentLength: aws.Int64(size),
        ContentType:   aws.String(fileType),
        ACL:           aws.String("public-read"),
    }
    resp, err := svc.PutObject(params)
    if err != nil {
        fmt.Printf("bad response: %s", err)
    }
    fmt.Printf("response %s", awsutil.StringValue(resp))

    Response.Status = "success"
    Response.Filename = awsutil.StringValue(resp)

}

defer file.Close()
res.Header().Set("Content-Type", "application/json")
rnd.JSON(res, http.StatusOK, Response)
}

This function returns the status as success on successful upload of the image and the file name as http response.

In console I can see some response as :

response {
ETag: "\"bd9be6ada974e66a154552edc78b4a81\""
}

I've no clue on what ETag means, but I understood that the image is uploaded and I got some positive response from s3. But I'm unable to find the image that I've uploaded in s3.

I need some help to solve this. Thanks in advance.

2
Next, I'd use something along the lines of this answer to 1) enumerate the buckets on your account and verifying "mybucketname" is there, and, if successful, 2) listing the contents of that bucket. - kostix

2 Answers

1
votes

You can retrieve the uploaded s3 object like this:

svc := s3.New(session.New(), cfg)

path := "mybucketname/" + filename
input := &s3.GetObjectInput{
    Bucket: aws.String("mybucketname"),
    Key:    aws.String(path),
}

result, err := svc.GetObject(input)
if err != nil {
    if aerr, ok := err.(awserr.Error); ok {
        switch aerr.Code() {
        case s3.ErrCodeNoSuchKey:
            fmt.Println(s3.ErrCodeNoSuchKey, aerr.Error())
        default:
            fmt.Println(aerr.Error())
        }
    } else {
        // Print the error, cast err to awserr.Error to get the Code and
        // Message from an error.
        fmt.Println(err.Error())
    }
    return
}

fmt.Println(result)

Shameless plug: You can also use the command line tool I created from the below link to view the object.

https://github.com/bharath-srinivas/nephele

You just have to do:

$ nephele s3 list <bucket-name> --prefix <prefix of the key/filename>

You can refer to the official documentation of aws-sdk-go here: https://docs.aws.amazon.com/sdk-for-go/api/service/s3/#S3.GetObject

0
votes

Check result.Location.

Start with the documentation @ https://docs.aws.amazon.com/sdk-for-go/api/service/s3/ and change it line by line until you get what you want.