Today request/response body is always encoded in JSON.
Should accept application/x-www-form-urlencoded too.
Is this supported or still open?
I'm implementing an OAuth2 server and the RFC requires the request Content-Type to be application/x-www-form-urlencoded.
we ended up rewriting application/x-www-form-urlencoded requests as JSON prior to the grpc-gateway receiving them like this:
formWrapper := func(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Printf("Got request: %#v\n", r)
if strings.ToLower(strings.Split(r.Header.Get("Content-Type"), ";")[0]) == "application/x-www-form-urlencoded" {
log.Println("Rewriting form data as json")
if err := r.ParseForm(); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
log.Println("Bad form request", err.Error())
return
}
jsonMap := make(map[string]interface{}, len(r.Form))
for k, v := range r.Form {
if len(v) > 0 {
jsonMap[k] = v[0]
}
}
jsonBody, err := json.Marshal(jsonMap)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
}
r.Body = ioutil.NopCloser(bytes.NewReader(jsonBody))
r.ContentLength = int64(len(jsonBody))
r.Header.Set("Content-Type", "application/json")
}
mux.ServeHTTP(w, r)
})
}
if err := http.ListenAndServe(":8080", formWrapper(mux)); err != nil {
log.Fatalf("failed to start gateway server on 8080: %v", err)
}
+1 It would be useful to have it built-in!
After one afternoon reading the f**king source code.
This solution is not good.
The good solution is:
post && form use get logic.- func request_Example_GetForm_0(ctx context.Context, marshaler runtime.Marshaler, client ExampleClient, req *http.Request, pathPar
| var protoReq FormRequest
| var metadata runtime.ServerMetadata
|
| ---------------------------from form data to genrate : req.URL.Query() ------------------------------
| if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_Example_GetForm_0); err != nil {
| return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
| }
|
| msg, err := client.GetForm(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
| return msg, metadata, err
|
| }
PopulateQueryParameters(msg proto.Message, values url.Values, filter *utilities.DoubleArray)
Most helpful comment
we ended up rewriting
application/x-www-form-urlencodedrequests as JSON prior to the grpc-gateway receiving them like this: