Change the default func to public (#966)

pull/970/head
Tony Chen 4 years ago committed by GitHub
parent 4cb3fd62e3
commit e7ddc1ba1e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 43
      transport/http/client.go
  2. 47
      transport/http/handle.go
  3. 6
      transport/http/server.go

@ -20,7 +20,7 @@ import (
"github.com/go-kratos/kratos/v2/transport/http/balancer/random" "github.com/go-kratos/kratos/v2/transport/http/balancer/random"
) )
// Client is http client // Client is an HTTP client.
type Client struct { type Client struct {
cc *http.Client cc *http.Client
r *resolver r *resolver
@ -36,11 +36,6 @@ type Client struct {
discovery registry.Discovery discovery registry.Discovery
} }
const (
// errNodeNotFound represents service node not found.
errNodeNotFound = "NODE_NOT_FOUND"
)
// DecodeErrorFunc is decode error func. // DecodeErrorFunc is decode error func.
type DecodeErrorFunc func(ctx context.Context, res *http.Response) error type DecodeErrorFunc func(ctx context.Context, res *http.Response) error
@ -132,7 +127,7 @@ func WithBalancer(b balancer.Balancer) ClientOption {
} }
} }
// Client is a HTTP transport client. // Client is an HTTP transport client.
type clientOptions struct { type clientOptions struct {
ctx context.Context ctx context.Context
transport http.RoundTripper transport http.RoundTripper
@ -154,11 +149,10 @@ func NewClient(ctx context.Context, opts ...ClientOption) (*Client, error) {
ctx: ctx, ctx: ctx,
scheme: "http", scheme: "http",
timeout: 1 * time.Second, timeout: 1 * time.Second,
encoder: defaultRequestEncoder, encoder: DefaultRequestEncoder,
decoder: defaultResponseDecoder, decoder: DefaultResponseDecoder,
errorDecoder: defaultErrorDecoder, errorDecoder: DefaultErrorDecoder,
transport: http.DefaultTransport, transport: http.DefaultTransport,
discovery: nil,
balancer: random.New(), balancer: random.New(),
} }
for _, o := range opts { for _, o := range opts {
@ -259,18 +253,18 @@ func (client *Client) invoke(ctx context.Context, req *http.Request, args interf
if client.r != nil { if client.r != nil {
nodes := client.r.fetch(ctx) nodes := client.r.fetch(ctx)
if len(nodes) == 0 { if len(nodes) == 0 {
return nil, errors.ServiceUnavailable(errNodeNotFound, "fetch error") return nil, errors.ServiceUnavailable("NODE_NOT_FOUND", "fetch error")
} }
var node *registry.ServiceInstance var node *registry.ServiceInstance
var err error var err error
node, done, err = client.b.Pick(ctx, c.pathPattern, nodes) node, done, err = client.b.Pick(ctx, c.pathPattern, nodes)
if err != nil { if err != nil {
return nil, errors.ServiceUnavailable(errNodeNotFound, err.Error()) return nil, errors.ServiceUnavailable("NODE_NOT_FOUND", err.Error())
} }
req = req.Clone(ctx) req = req.Clone(ctx)
addr, err := parseEndpoint(client.scheme, node.Endpoints) addr, err := parseEndpoint(client.scheme, node.Endpoints)
if err != nil { if err != nil {
return nil, errors.ServiceUnavailable(errNodeNotFound, err.Error()) return nil, errors.ServiceUnavailable("NODE_NOT_FOUND", err.Error())
} }
req.URL.Host = addr req.URL.Host = addr
} }
@ -317,7 +311,8 @@ func (client *Client) do(ctx context.Context, req *http.Request, c callInfo) (*h
return resp, nil return resp, nil
} }
func defaultRequestEncoder(ctx context.Context, in interface{}) (string, []byte, error) { // DefaultRequestEncoder is an HTTP request encoder.
func DefaultRequestEncoder(ctx context.Context, in interface{}) (string, []byte, error) {
body, err := encoding.GetCodec("json").Marshal(in) body, err := encoding.GetCodec("json").Marshal(in)
if err != nil { if err != nil {
return "", nil, err return "", nil, err
@ -325,16 +320,18 @@ func defaultRequestEncoder(ctx context.Context, in interface{}) (string, []byte,
return "application/json", body, err return "application/json", body, err
} }
func defaultResponseDecoder(ctx context.Context, res *http.Response, v interface{}) error { // DefaultResponseDecoder is an HTTP response decoder.
func DefaultResponseDecoder(ctx context.Context, res *http.Response, v interface{}) error {
defer res.Body.Close() defer res.Body.Close()
data, err := ioutil.ReadAll(res.Body) data, err := ioutil.ReadAll(res.Body)
if err != nil { if err != nil {
return err return err
} }
return codecForResponse(res).Unmarshal(data, v) return CodecForResponse(res).Unmarshal(data, v)
} }
func defaultErrorDecoder(ctx context.Context, res *http.Response) error { // DefaultErrorDecoder is an HTTP error decoder.
func DefaultErrorDecoder(ctx context.Context, res *http.Response) error {
if res.StatusCode >= 200 && res.StatusCode <= 299 { if res.StatusCode >= 200 && res.StatusCode <= 299 {
return nil return nil
} }
@ -342,20 +339,18 @@ func defaultErrorDecoder(ctx context.Context, res *http.Response) error {
data, err := ioutil.ReadAll(res.Body) data, err := ioutil.ReadAll(res.Body)
if err == nil { if err == nil {
e := new(errors.Error) e := new(errors.Error)
if err = codecForResponse(res).Unmarshal(data, e); err == nil { if err = CodecForResponse(res).Unmarshal(data, e); err == nil {
return e return e
} }
} }
return errors.Errorf(res.StatusCode, errors.UnknownReason, err.Error()) return errors.Errorf(res.StatusCode, errors.UnknownReason, err.Error())
} }
func codecForResponse(r *http.Response) encoding.Codec { // CodecForResponse get encoding.Codec via http.Response
func CodecForResponse(r *http.Response) encoding.Codec {
codec := encoding.GetCodec(httputil.ContentSubtype("Content-Type")) codec := encoding.GetCodec(httputil.ContentSubtype("Content-Type"))
if codec != nil { if codec != nil {
return codec return codec
} }
if codec == nil { return encoding.GetCodec("json")
codec = encoding.GetCodec("json")
}
return codec
} }

@ -43,9 +43,9 @@ type HandleOptions struct {
// Deprecated: use NewHandler instead. // Deprecated: use NewHandler instead.
func DefaultHandleOptions() HandleOptions { func DefaultHandleOptions() HandleOptions {
return HandleOptions{ return HandleOptions{
Decode: defaultRequestDecoder, Decode: DefaultRequestDecoder,
Encode: defaultResponseEncoder, Encode: DefaultResponseEncoder,
Error: defaultErrorEncoder, Error: DefaultErrorEncoder,
Middleware: recovery.Recovery(), Middleware: recovery.Recovery(),
} }
} }
@ -86,7 +86,7 @@ type Handler struct {
opts HandleOptions opts HandleOptions
} }
// NewHandler new a HTTP handler. // NewHandler new an HTTP handler.
func NewHandler(handler interface{}, opts ...HandleOption) http.Handler { func NewHandler(handler interface{}, opts ...HandleOption) http.Handler {
if err := validateHandler(handler); err != nil { if err := validateHandler(handler); err != nil {
panic(err) panic(err)
@ -150,11 +150,11 @@ func validateHandler(handler interface{}) error {
return nil return nil
} }
// defaultRequestDecoder decodes the request body to object. // DefaultRequestDecoder decodes the request body to object.
func defaultRequestDecoder(req *http.Request, v interface{}) error { func DefaultRequestDecoder(r *http.Request, v interface{}) error {
subtype := httputil.ContentSubtype(req.Header.Get("Content-Type")) codec, ok := CodecForRequest(r, "Content-Type")
if codec := encoding.GetCodec(subtype); codec != nil { if ok {
data, err := ioutil.ReadAll(req.Body) data, err := ioutil.ReadAll(r.Body)
if err != nil { if err != nil {
return errors.BadRequest("CODEC", err.Error()) return errors.BadRequest("CODEC", err.Error())
} }
@ -162,16 +162,16 @@ func defaultRequestDecoder(req *http.Request, v interface{}) error {
return errors.BadRequest("CODEC", err.Error()) return errors.BadRequest("CODEC", err.Error())
} }
} else { } else {
if err := binding.BindForm(req, v); err != nil { if err := binding.BindForm(r, v); err != nil {
return errors.BadRequest("CODEC", err.Error()) return errors.BadRequest("CODEC", err.Error())
} }
} }
return nil return nil
} }
// defaultResponseEncoder encodes the object to the HTTP response. // DefaultResponseEncoder encodes the object to the HTTP response.
func defaultResponseEncoder(w http.ResponseWriter, r *http.Request, v interface{}) error { func DefaultResponseEncoder(w http.ResponseWriter, r *http.Request, v interface{}) error {
codec := CodecForRequest(r) codec, _ := CodecForRequest(r, "Accept")
data, err := codec.Marshal(v) data, err := codec.Marshal(v)
if err != nil { if err != nil {
return err return err
@ -186,9 +186,9 @@ func defaultResponseEncoder(w http.ResponseWriter, r *http.Request, v interface{
return nil return nil
} }
// defaultErrorEncoder encodes the error to the HTTP response. // DefaultErrorEncoder encodes the error to the HTTP response.
func defaultErrorEncoder(w http.ResponseWriter, r *http.Request, se error) { func DefaultErrorEncoder(w http.ResponseWriter, r *http.Request, se error) {
codec := CodecForRequest(r) codec, _ := CodecForRequest(r, "Accept")
body, err := codec.Marshal(se) body, err := codec.Marshal(se)
if err != nil { if err != nil {
w.WriteHeader(http.StatusInternalServerError) w.WriteHeader(http.StatusInternalServerError)
@ -206,15 +206,12 @@ func defaultErrorEncoder(w http.ResponseWriter, r *http.Request, se error) {
} }
// CodecForRequest get encoding.Codec via http.Request // CodecForRequest get encoding.Codec via http.Request
func CodecForRequest(r *http.Request) encoding.Codec { func CodecForRequest(r *http.Request, name string) (encoding.Codec, bool) {
var codec encoding.Codec for _, accept := range r.Header[name] {
for _, accept := range r.Header["Accept"] { codec := encoding.GetCodec(httputil.ContentSubtype(accept))
if codec = encoding.GetCodec(httputil.ContentSubtype(accept)); codec != nil { if codec != nil {
break return codec, true
} }
} }
if codec == nil { return encoding.GetCodec("json"), false
codec = encoding.GetCodec("json")
}
return codec
} }

@ -19,7 +19,7 @@ import (
var _ transport.Server = (*Server)(nil) var _ transport.Server = (*Server)(nil)
var _ transport.Endpointer = (*Server)(nil) var _ transport.Endpointer = (*Server)(nil)
// ServerOption is HTTP server option. // ServerOption is an HTTP server option.
type ServerOption func(*Server) type ServerOption func(*Server)
// Network with server network. // Network with server network.
@ -50,7 +50,7 @@ func Logger(logger log.Logger) ServerOption {
} }
} }
// Server is a HTTP server wrapper. // Server is an HTTP server wrapper.
type Server struct { type Server struct {
*http.Server *http.Server
lis net.Listener lis net.Listener
@ -61,7 +61,7 @@ type Server struct {
log *log.Helper log *log.Helper
} }
// NewServer creates a HTTP server by options. // NewServer creates an HTTP server by options.
func NewServer(opts ...ServerOption) *Server { func NewServer(opts ...ServerOption) *Server {
srv := &Server{ srv := &Server{
network: "tcp", network: "tcp",

Loading…
Cancel
Save