Created
May 22, 2019 15:39
-
-
Save mwf/ee7bed621f00f7aabb9a6821d39e48a0 to your computer and use it in GitHub Desktop.
github.com/utrack/clay "application/x-www-form-urlencoded" marshaller
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
syntax = "proto3"; | |
import "google/api/annotations.proto"; | |
service Foo { | |
rpc ParseForm (FormData) returns (FormData) { | |
option (google.api.http) = { | |
post: "/form" | |
body: "*" | |
}; | |
}; | |
} | |
message FormData { | |
string b = 1; | |
int32 a = 2; | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package strings | |
import ( | |
"fmt" | |
"io" | |
"io/ioutil" | |
"net/url" | |
"reflect" | |
"github.com/gogo/protobuf/proto" | |
"github.com/grpc-ecosystem/grpc-gateway/runtime" | |
"github.com/grpc-ecosystem/grpc-gateway/utilities" | |
"github.com/pkg/errors" | |
"github.com/utrack/clay/v2/transport/httpruntime" | |
) | |
const ( | |
maxFormSize = int64(10 << 20) // 10 MB is a lot of text. | |
) | |
type MarshalerFormUrlencoded struct{} | |
var _ httpruntime.Marshaler = MarshalerFormUrlencoded{} | |
func (MarshalerFormUrlencoded) ContentType() string { | |
return "application/x-www-form-urlencoded" | |
} | |
func (m MarshalerFormUrlencoded) Unmarshal(reader io.Reader, dst interface{}) error { | |
var msg proto.Message | |
var ok bool | |
// We need this dirty hack because `dst` contains double pointer to real struct. | |
// And we can't extract an interface from a double pointer without some reflection | |
v := reflect.ValueOf(dst) | |
for { | |
if kind := v.Kind(); kind != reflect.Ptr && kind != reflect.Interface { | |
break | |
} | |
vv := v.Interface() | |
msg, ok = vv.(proto.Message) | |
if ok { | |
break | |
} | |
v = v.Elem() | |
} | |
if msg == nil { | |
return fmt.Errorf("Form unmarshaller supports only `proto.Message` request type, got %T", dst) | |
} | |
reader = io.LimitReader(reader, maxFormSize+1) | |
b, err := ioutil.ReadAll(reader) | |
if err != nil { | |
return err | |
} | |
if int64(len(b)) > maxFormSize { | |
return errors.New("http: POST too large") | |
} | |
vs, err := url.ParseQuery(string(b)) | |
if err != nil { | |
return err | |
} | |
filter := &utilities.DoubleArray{} | |
err = runtime.PopulateQueryParameters(msg, vs, filter) | |
if err != nil { | |
return err | |
} | |
return nil | |
} | |
func (m MarshalerFormUrlencoded) Marshal(w io.Writer, src interface{}) error { | |
return errors.New("not implemented") | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Code generated by protoc-gen-goclay, but your can (must) modify it. | |
// source: strings.proto | |
package strings | |
import ( | |
"context" | |
"github.com/utrack/clay/v2/transport/httpruntime" | |
desc "<path to pb package>" | |
) | |
func init() { | |
httpruntime.OverrideMarshaler("application/x-www-form-urlencoded", MarshalerFormUrlencoded{}) | |
} | |
func (i *Implementation) ParseForm(ctx context.Context, req *desc.FormData) (*desc.FormData, error) { | |
return req, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment