Description

Gin does not support negotiation of the protobuf MIME type. As of 1.9.1, only [json, html, xml, yaml, toml] are supported.

Relevant source: https://github.com/gin-gonic/gin/blob/v1.9.1/context.go#L1116

How to reproduce

package main

import (
    "github.com/gin-gonic/gin"
    "github.com/gin-gonic/gin/binding"
    "google.golang.org/protobuf/types/known/structpb"
)

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

    testData, _ := structpb.NewStruct(map[string]interface{}{
        "key": "value",
    })

    g.GET("/negotiate", func(c *gin.Context) {
        c.Negotiate(200, gin.Negotiate{
            Offered: []string{
                binding.MIMEJSON,
                binding.MIMEPROTOBUF,
            },
            Data: testData,
        })
    })

    g.Run(":8080")
}

Expectations

$ curl -H 'Accept: application/x-protobuf' localhost:8080/negotiate
<binary protobuf encoding>

Actual result

$ curl -v -H 'Accept: application/x-protobuf' localhost:8080/negotiate
*   Trying 127.0.0.1:8080...                                                                                                                                                                                                                                                      
* Connected to localhost (127.0.0.1) port 8080 (#0)                                                                                                                                                                                                                               
> GET /negotiate HTTP/1.1                                                                                                                                                                                                                                                         
> Host: localhost:8080                                                                                                                                                                                                                                                            
> User-Agent: curl/7.88.1                                                                                                                                                                                                                                                         
> Accept: application/x-protobuf                                                                                                                                                                                                                                                  
>                                                                                                                                                                                                                                                                                 
< HTTP/1.1 406 Not Acceptable                                                                                                                                                                                                                                                     
< Date: Tue, 12 Dec 2023 19:04:22 GMT                                                                                                                                                                                                                                             
< Content-Length: 0                                                                                                                                                                                                                                                               
<                                                                                                                                                                                                                                                                                 
* Connection #0 to host localhost left intact

Environment

  • go version: 1.21.1
  • gin version (or commit ref): 1.9.1 (latest)
  • operating system: Debian Bookworm

Comment From: kkoehler

I've created a pull request for that. see link

Comment From: kkoehler

The following sample works with the pull request

package main

import (
    "github.com/gin-gonic/gin"
    "github.com/gin-gonic/gin/binding"
    "google.golang.org/protobuf/types/known/structpb"
)

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

    testData, _ := structpb.NewStruct(map[string]interface{}{
        "key": "value",
    })

    negotiate := gin.NewNegotiate([]string{
        binding.MIMEJSON,
        binding.MIMEPROTOBUF,
    })
    g.GET("/negotiate", func(c *gin.Context) {
        c.Negotiate(200, negotiate.WithData(testData))
    })

    g.Run(":8080")
}