0

I am getting a 204 with OPTIONS method, but the end-point doesn't seem to be hit enter image description here

Just building a simple file-upload endpoint like this:

package main

import  (
    "cloud.google.com/go/storage"
    "github.com/gin-gonic/gin"
    "github.com/gin-contrib/cors"
    "google.golang.org/api/option"
    "io"
    "log"
)

 const uploadBucket = "some-cool-bucket-name"
 const uploadApiKey = "some-advanced-key"

func main() {
    router := gin.Default()

    rg := router.Group("api/v1/photo")
    {
        rg.PATCH("/", uploadFile)
    }

    router.Use(cors.Default())

    router.Run()
}

func uploadFile(c *gin.Context) {
    mr, e := c.Request.MultipartReader()
    if e != nil {
        panic("Error reading request")
    }

    client, e := storage.NewClient(c, option.WithAPIKey(uploadApiKey))
    bucket := client.Bucket(uploadBucket)

    for {
        p, e := mr.NextPart()

        if e == io.EOF {
            break
        } else if e != nil {
            panic("Error processing file")
        }

        w := bucket.Object(p.FileName()).NewWriter(c)

        if _, e := io.Copy(w, p); e != nil {
            panic("Error during chunk upload")
        } else if e := w.Close(); e != nil {
            panic("Could not finalize chunk writing")
        }

    }
}

Any ideas why?

FailedUnitTest
  • 1,637
  • 3
  • 20
  • 43

2 Answers2

5

Use below CORS:

func CORS() gin.HandlerFunc {
    // TO allow CORS
    return func(c *gin.Context) {
        c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
        c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
        c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE")
        if c.Request.Method == "OPTIONS" {
            c.AbortWithStatus(204)
            return
        }
        c.Next()
    }
}

Next, you have to add cors to your routes:

    router := gin.Default()
    router.Use(CORS())

Plus it will be better to use POST method instead of PATCH. I am quite sure it will solve your problem.

Umar Hayat
  • 4,300
  • 1
  • 12
  • 27
0

You may be able to achieve this by using a POST method instead of PATCH.

For example:

func main() {
    router := gin.Default()

    rg := router.Group("api/v1/photo")
    {
        rg.POST("/", uploadFile)
    }

    router.Use(cors.Default())

    router.Run()
}

Potential CORS Issue

You may need to setup proper Cross-Origin Resource Sharing in your Go service.

Some additional references

SO answer on differences between common HTTP methods - What is the difference between PUT, POST and PATCH?.

PATCH: Submits a partial modification to a resource. If you only need to update one field for the resource, you may want to use the PATCH method.

How does HTTP file upload work?

segFault
  • 3,887
  • 1
  • 19
  • 31
  • I changed everything to POST. Exactly same result unfortunately. – FailedUnitTest Feb 22 '20 at 13:00
  • So the `OPTIONS` request is being made automatically client-side. You need to handle that as well on your server. It might be helpful to see the POST request you are sending to the server from the form. Is the go service running from the same domain/host as the form/client? – segFault Feb 22 '20 at 13:07
  • 1
    gin handle `OPTIONS` request automatically. – Roman Kiselenko Feb 22 '20 at 13:12