|
|
|
package http
|
|
|
|
|
|
|
|
import (
|
|
|
|
"net/http"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"google.golang.org/grpc/codes"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
baseContentType = "application"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
// HeaderAccept is accept header.
|
|
|
|
HeaderAccept = http.CanonicalHeaderKey("Accept")
|
|
|
|
// HeaderContentType is content-type header.
|
|
|
|
HeaderContentType = http.CanonicalHeaderKey("Content-Type")
|
|
|
|
// HeaderAcceptLanguage is accept-language header.
|
|
|
|
HeaderAcceptLanguage = http.CanonicalHeaderKey("Accept-Language")
|
|
|
|
)
|
|
|
|
|
|
|
|
// ContentType returns the content-type with base prefix.
|
|
|
|
func ContentType(subtype string) string {
|
|
|
|
return strings.Join([]string{baseContentType, subtype}, "/")
|
|
|
|
}
|
|
|
|
|
|
|
|
// ContentSubtype returns the content-subtype for the given content-type. The
|
|
|
|
// given content-type must be a valid content-type that starts with
|
|
|
|
// but no content-subtype will be returned.
|
|
|
|
// according rfc7231.
|
|
|
|
// contentType is assumed to be lowercase already.
|
|
|
|
func ContentSubtype(contentType string) string {
|
|
|
|
left := strings.Index(contentType, "/")
|
|
|
|
if left == -1 {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
right := strings.Index(contentType, ";")
|
|
|
|
if right == -1 {
|
|
|
|
right = len(contentType)
|
|
|
|
}
|
|
|
|
if right < left {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
return contentType[left+1 : right]
|
|
|
|
}
|
|
|
|
|
|
|
|
// GRPCCodeFromStatus converts a HTTP error code into the corresponding gRPC response status.
|
|
|
|
// See: https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto
|
|
|
|
func GRPCCodeFromStatus(code int) codes.Code {
|
|
|
|
switch code {
|
|
|
|
case http.StatusOK:
|
|
|
|
return codes.OK
|
|
|
|
case http.StatusBadRequest:
|
|
|
|
return codes.InvalidArgument
|
|
|
|
case http.StatusUnauthorized:
|
|
|
|
return codes.Unauthenticated
|
|
|
|
case http.StatusForbidden:
|
|
|
|
return codes.PermissionDenied
|
|
|
|
case http.StatusNotFound:
|
|
|
|
return codes.NotFound
|
|
|
|
case http.StatusConflict:
|
|
|
|
return codes.Aborted
|
|
|
|
case http.StatusTooManyRequests:
|
|
|
|
return codes.ResourceExhausted
|
|
|
|
case http.StatusInternalServerError:
|
|
|
|
return codes.Internal
|
|
|
|
case http.StatusNotImplemented:
|
|
|
|
return codes.Unimplemented
|
|
|
|
case http.StatusServiceUnavailable:
|
|
|
|
return codes.Unavailable
|
|
|
|
case http.StatusGatewayTimeout:
|
|
|
|
return codes.DeadlineExceeded
|
|
|
|
}
|
|
|
|
return codes.Unknown
|
|
|
|
}
|
|
|
|
|
|
|
|
// StatusFromGRPCCode converts a gRPC error code into the corresponding HTTP response status.
|
|
|
|
// See: https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto
|
|
|
|
func StatusFromGRPCCode(code codes.Code) int {
|
|
|
|
switch code {
|
|
|
|
case codes.OK:
|
|
|
|
return http.StatusOK
|
|
|
|
case codes.Canceled:
|
|
|
|
return http.StatusRequestTimeout
|
|
|
|
case codes.Unknown:
|
|
|
|
return http.StatusInternalServerError
|
|
|
|
case codes.InvalidArgument:
|
|
|
|
return http.StatusBadRequest
|
|
|
|
case codes.DeadlineExceeded:
|
|
|
|
return http.StatusGatewayTimeout
|
|
|
|
case codes.NotFound:
|
|
|
|
return http.StatusNotFound
|
|
|
|
case codes.AlreadyExists:
|
|
|
|
return http.StatusConflict
|
|
|
|
case codes.PermissionDenied:
|
|
|
|
return http.StatusForbidden
|
|
|
|
case codes.Unauthenticated:
|
|
|
|
return http.StatusUnauthorized
|
|
|
|
case codes.ResourceExhausted:
|
|
|
|
return http.StatusTooManyRequests
|
|
|
|
case codes.FailedPrecondition:
|
|
|
|
return http.StatusBadRequest
|
|
|
|
case codes.Aborted:
|
|
|
|
return http.StatusConflict
|
|
|
|
case codes.OutOfRange:
|
|
|
|
return http.StatusBadRequest
|
|
|
|
case codes.Unimplemented:
|
|
|
|
return http.StatusNotImplemented
|
|
|
|
case codes.Internal:
|
|
|
|
return http.StatusInternalServerError
|
|
|
|
case codes.Unavailable:
|
|
|
|
return http.StatusServiceUnavailable
|
|
|
|
case codes.DataLoss:
|
|
|
|
return http.StatusInternalServerError
|
|
|
|
}
|
|
|
|
return http.StatusInternalServerError
|
|
|
|
}
|