代码拉取完成,页面将自动刷新
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package triple_protocol
import (
"context"
"errors"
"fmt"
"net/http"
)
import (
"github.com/dubbogo/grpc-go"
"github.com/dubbogo/grpc-go/metadata"
"github.com/dubbogo/grpc-go/status"
"github.com/golang/protobuf/proto"
)
import (
dubbo_protocol "gitee.com/git4chen/dubbo-go/protocol"
)
type MethodHandler func(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error)
type tripleCompatInterceptor struct {
spec Spec
peer Peer
header http.Header
procedure string
interceptor Interceptor
}
// be compatible with old triple-gen code
func (t *tripleCompatInterceptor) compatUnaryServerInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
request := NewRequest(req)
request.spec = t.spec
request.peer = t.peer
request.header = t.header
unaryFunc := func(ctx context.Context, request AnyRequest) (AnyResponse, error) {
if err := ctx.Err(); err != nil {
return nil, err
}
typed, ok := request.(*Request)
if !ok {
return nil, errorf(CodeInternal, "unexpected handler request type %T", request)
}
dubbo3RespRaw, err := handler(ctx, typed.Any())
if dubbo3RespRaw == nil && err == nil {
// This is going to panic during serialization. Debugging is much easier
// if we panic here instead, so we can include the procedure name.
panic(fmt.Sprintf("%s returned nil resp and nil error", t.procedure)) //nolint: forbidigo
}
dubbo3Resp, ok := dubbo3RespRaw.(*dubbo_protocol.RPCResult)
if !ok {
panic(fmt.Sprintf("%+v is not of type *RPCResult", dubbo3RespRaw))
}
dubbo3Err, ok := compatError(err)
if ok {
err = dubbo3Err
}
// todo(DMwangnima): expose API for users to write response headers and trailers
resp := NewResponse(dubbo3Resp.Rest)
trailer := make(http.Header)
for key, valRaw := range dubbo3Resp.Attachments() {
switch valRaw.(type) {
case string:
trailer[key] = []string{valRaw.(string)}
case []string:
trailer[key] = valRaw.([]string)
default:
panic(fmt.Sprintf("unsupported attachment value type %T", valRaw))
}
}
resp.trailer = trailer
return resp, err
}
if t.interceptor != nil {
unaryFunc = t.interceptor.WrapUnaryHandler(unaryFunc)
}
return unaryFunc(ctx, request)
}
func NewCompatUnaryHandler(
procedure string,
method string,
srv interface{},
unary MethodHandler,
options ...HandlerOption,
) *Handler {
config := newHandlerConfig(procedure, options)
implementation := generateCompatUnaryHandlerFunc(procedure, method, srv, unary, config.Interceptor)
protocolHandlers := config.newProtocolHandlers(StreamTypeUnary)
hdl := &Handler{
spec: config.newSpec(StreamTypeUnary),
implementations: make(map[string]StreamingHandlerFunc, defaultImplementationsSize),
protocolHandlers: protocolHandlers,
allowMethod: sortedAllowMethodValue(protocolHandlers),
acceptPost: sortedAcceptPostValue(protocolHandlers),
}
hdl.processImplementation(getIdentifier(config.Group, config.Version), implementation)
return hdl
}
func generateCompatUnaryHandlerFunc(
procedure string,
method string,
srv interface{},
unary MethodHandler,
interceptor Interceptor,
) StreamingHandlerFunc {
return func(ctx context.Context, conn StreamingHandlerConn) error {
compatInterceptor := &tripleCompatInterceptor{
spec: conn.Spec(),
peer: conn.Peer(),
header: conn.RequestHeader(),
procedure: procedure,
interceptor: interceptor,
}
decodeFunc := func(req interface{}) error {
if err := conn.Receive(req); err != nil {
return err
}
return nil
}
ctx = metadata.NewIncomingContext(ctx, metadata.MD(conn.ExportableHeader()))
// staticcheck error: SA1029. dubbo3 code needs to make use of "XXX_TRIPLE_GO_METHOD_NAME"
//nolint:staticcheck
ctx = context.WithValue(ctx, "XXX_TRIPLE_GO_METHOD_NAME", method)
// staticcheck error: SA1029. Stub code generated by protoc-gen-go-triple makes use of "XXX_TRIPLE_GO_INTERFACE_NAME" directly
//nolint:staticcheck
ctx = context.WithValue(ctx, "XXX_TRIPLE_GO_INTERFACE_NAME", procedure)
// todo(DMwangnima): deal with XXX_TRIPLE_GO_GENERIC_PAYLOAD
respRaw, err := unary(srv, ctx, decodeFunc, compatInterceptor.compatUnaryServerInterceptor)
if err != nil {
return err
}
resp := respRaw.(*Response)
// merge headers
mergeHeaders(conn.ResponseHeader(), resp.Header())
mergeHeaders(conn.ResponseTrailer(), resp.Trailer())
return conn.Send(resp.Any())
}
}
func compatError(err error) (*Error, bool) {
if err == nil {
return nil, false
}
s, ok := status.FromError(err)
if !ok {
return nil, false
}
triErr := NewError(Code(s.Code()), errors.New(s.Message()))
for _, detail := range s.Details() {
// dubbo3 detail use MessageV1, we need to convert it to MessageV2
errDetail, e := NewErrorDetail(proto.MessageV2(detail.(proto.Message)))
if e != nil {
return nil, false
}
triErr.AddDetail(errDetail)
}
return triErr, ok
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。