github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/grpc/internal/grpcutil/method.go (about) 1 /* 2 * 3 * Copyright 2018 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 package grpcutil 20 21 import ( 22 "errors" 23 "strings" 24 ) 25 26 // ParseMethod splits service and method from the input. It expects format 27 // "/service/method". 28 // 29 func ParseMethod(methodName string) (service, method string, _ error) { 30 if !strings.HasPrefix(methodName, "/") { 31 return "", "", errors.New("invalid method name: should start with /") 32 } 33 methodName = methodName[1:] 34 35 pos := strings.LastIndex(methodName, "/") 36 if pos < 0 { 37 return "", "", errors.New("invalid method name: suffix /method is missing") 38 } 39 return methodName[:pos], methodName[pos+1:], nil 40 } 41 42 const baseContentType = "application/grpc" 43 44 // ContentSubtype returns the content-subtype for the given content-type. The 45 // given content-type must be a valid content-type that starts with 46 // "application/grpc". A content-subtype will follow "application/grpc" after a 47 // "+" or ";". See 48 // https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests for 49 // more details. 50 // 51 // If contentType is not a valid content-type for gRPC, the boolean 52 // will be false, otherwise true. If content-type == "application/grpc", 53 // "application/grpc+", or "application/grpc;", the boolean will be true, 54 // but no content-subtype will be returned. 55 // 56 // contentType is assumed to be lowercase already. 57 func ContentSubtype(contentType string) (string, bool) { 58 if contentType == baseContentType { 59 return "", true 60 } 61 if !strings.HasPrefix(contentType, baseContentType) { 62 return "", false 63 } 64 // guaranteed since != baseContentType and has baseContentType prefix 65 switch contentType[len(baseContentType)] { 66 case '+', ';': 67 // this will return true for "application/grpc+" or "application/grpc;" 68 // which the previous validContentType function tested to be valid, so we 69 // just say that no content-subtype is specified in this case 70 return contentType[len(baseContentType)+1:], true 71 default: 72 return "", false 73 } 74 } 75 76 // ContentType builds full content type with the given sub-type. 77 // 78 // contentSubtype is assumed to be lowercase 79 func ContentType(contentSubtype string) string { 80 if contentSubtype == "" { 81 return baseContentType 82 } 83 return baseContentType + "+" + contentSubtype 84 }