2 configurations for the listeners are now possible: - enableJWT=false with client ssl auth - enableJWT=true with https Actual verification of the tokens is handled by https://github.com/openshift-online/ocm-sdk-go. An authentication handler is run as the top level handler, before any routing is done. Routes which do not require authentication should be listed as exceptions. Authentication can be restricted using an ACL file which allows filtering based on JWT claims. For more information see the inline comments in ocm-sdk/authentication. As an added quirk the `-v` flag for the osbuild-composer executable was changed to `-verbose` to avoid flag collision with glog which declares the `-v` flag in the package `init()` function. The ocm-sdk depends on glog and pulls it in.
298 lines
7.1 KiB
Go
298 lines
7.1 KiB
Go
package reflect2
|
|
|
|
import (
|
|
"github.com/modern-go/concurrent"
|
|
"reflect"
|
|
"unsafe"
|
|
)
|
|
|
|
type Type interface {
|
|
Kind() reflect.Kind
|
|
// New return pointer to data of this type
|
|
New() interface{}
|
|
// UnsafeNew return the allocated space pointed by unsafe.Pointer
|
|
UnsafeNew() unsafe.Pointer
|
|
// PackEFace cast a unsafe pointer to object represented pointer
|
|
PackEFace(ptr unsafe.Pointer) interface{}
|
|
// Indirect dereference object represented pointer to this type
|
|
Indirect(obj interface{}) interface{}
|
|
// UnsafeIndirect dereference pointer to this type
|
|
UnsafeIndirect(ptr unsafe.Pointer) interface{}
|
|
// Type1 returns reflect.Type
|
|
Type1() reflect.Type
|
|
Implements(thatType Type) bool
|
|
String() string
|
|
RType() uintptr
|
|
// interface{} of this type has pointer like behavior
|
|
LikePtr() bool
|
|
IsNullable() bool
|
|
IsNil(obj interface{}) bool
|
|
UnsafeIsNil(ptr unsafe.Pointer) bool
|
|
Set(obj interface{}, val interface{})
|
|
UnsafeSet(ptr unsafe.Pointer, val unsafe.Pointer)
|
|
AssignableTo(anotherType Type) bool
|
|
}
|
|
|
|
type ListType interface {
|
|
Type
|
|
Elem() Type
|
|
SetIndex(obj interface{}, index int, elem interface{})
|
|
UnsafeSetIndex(obj unsafe.Pointer, index int, elem unsafe.Pointer)
|
|
GetIndex(obj interface{}, index int) interface{}
|
|
UnsafeGetIndex(obj unsafe.Pointer, index int) unsafe.Pointer
|
|
}
|
|
|
|
type ArrayType interface {
|
|
ListType
|
|
Len() int
|
|
}
|
|
|
|
type SliceType interface {
|
|
ListType
|
|
MakeSlice(length int, cap int) interface{}
|
|
UnsafeMakeSlice(length int, cap int) unsafe.Pointer
|
|
Grow(obj interface{}, newLength int)
|
|
UnsafeGrow(ptr unsafe.Pointer, newLength int)
|
|
Append(obj interface{}, elem interface{})
|
|
UnsafeAppend(obj unsafe.Pointer, elem unsafe.Pointer)
|
|
LengthOf(obj interface{}) int
|
|
UnsafeLengthOf(ptr unsafe.Pointer) int
|
|
SetNil(obj interface{})
|
|
UnsafeSetNil(ptr unsafe.Pointer)
|
|
Cap(obj interface{}) int
|
|
UnsafeCap(ptr unsafe.Pointer) int
|
|
}
|
|
|
|
type StructType interface {
|
|
Type
|
|
NumField() int
|
|
Field(i int) StructField
|
|
FieldByName(name string) StructField
|
|
FieldByIndex(index []int) StructField
|
|
FieldByNameFunc(match func(string) bool) StructField
|
|
}
|
|
|
|
type StructField interface {
|
|
Offset() uintptr
|
|
Name() string
|
|
PkgPath() string
|
|
Type() Type
|
|
Tag() reflect.StructTag
|
|
Index() []int
|
|
Anonymous() bool
|
|
Set(obj interface{}, value interface{})
|
|
UnsafeSet(obj unsafe.Pointer, value unsafe.Pointer)
|
|
Get(obj interface{}) interface{}
|
|
UnsafeGet(obj unsafe.Pointer) unsafe.Pointer
|
|
}
|
|
|
|
type MapType interface {
|
|
Type
|
|
Key() Type
|
|
Elem() Type
|
|
MakeMap(cap int) interface{}
|
|
UnsafeMakeMap(cap int) unsafe.Pointer
|
|
SetIndex(obj interface{}, key interface{}, elem interface{})
|
|
UnsafeSetIndex(obj unsafe.Pointer, key unsafe.Pointer, elem unsafe.Pointer)
|
|
TryGetIndex(obj interface{}, key interface{}) (interface{}, bool)
|
|
GetIndex(obj interface{}, key interface{}) interface{}
|
|
UnsafeGetIndex(obj unsafe.Pointer, key unsafe.Pointer) unsafe.Pointer
|
|
Iterate(obj interface{}) MapIterator
|
|
UnsafeIterate(obj unsafe.Pointer) MapIterator
|
|
}
|
|
|
|
type MapIterator interface {
|
|
HasNext() bool
|
|
Next() (key interface{}, elem interface{})
|
|
UnsafeNext() (key unsafe.Pointer, elem unsafe.Pointer)
|
|
}
|
|
|
|
type PtrType interface {
|
|
Type
|
|
Elem() Type
|
|
}
|
|
|
|
type InterfaceType interface {
|
|
NumMethod() int
|
|
}
|
|
|
|
type Config struct {
|
|
UseSafeImplementation bool
|
|
}
|
|
|
|
type API interface {
|
|
TypeOf(obj interface{}) Type
|
|
Type2(type1 reflect.Type) Type
|
|
}
|
|
|
|
var ConfigUnsafe = Config{UseSafeImplementation: false}.Froze()
|
|
var ConfigSafe = Config{UseSafeImplementation: true}.Froze()
|
|
|
|
type frozenConfig struct {
|
|
useSafeImplementation bool
|
|
cache *concurrent.Map
|
|
}
|
|
|
|
func (cfg Config) Froze() *frozenConfig {
|
|
return &frozenConfig{
|
|
useSafeImplementation: cfg.UseSafeImplementation,
|
|
cache: concurrent.NewMap(),
|
|
}
|
|
}
|
|
|
|
func (cfg *frozenConfig) TypeOf(obj interface{}) Type {
|
|
cacheKey := uintptr(unpackEFace(obj).rtype)
|
|
typeObj, found := cfg.cache.Load(cacheKey)
|
|
if found {
|
|
return typeObj.(Type)
|
|
}
|
|
return cfg.Type2(reflect.TypeOf(obj))
|
|
}
|
|
|
|
func (cfg *frozenConfig) Type2(type1 reflect.Type) Type {
|
|
if type1 == nil {
|
|
return nil
|
|
}
|
|
cacheKey := uintptr(unpackEFace(type1).data)
|
|
typeObj, found := cfg.cache.Load(cacheKey)
|
|
if found {
|
|
return typeObj.(Type)
|
|
}
|
|
type2 := cfg.wrapType(type1)
|
|
cfg.cache.Store(cacheKey, type2)
|
|
return type2
|
|
}
|
|
|
|
func (cfg *frozenConfig) wrapType(type1 reflect.Type) Type {
|
|
safeType := safeType{Type: type1, cfg: cfg}
|
|
switch type1.Kind() {
|
|
case reflect.Struct:
|
|
if cfg.useSafeImplementation {
|
|
return &safeStructType{safeType}
|
|
}
|
|
return newUnsafeStructType(cfg, type1)
|
|
case reflect.Array:
|
|
if cfg.useSafeImplementation {
|
|
return &safeSliceType{safeType}
|
|
}
|
|
return newUnsafeArrayType(cfg, type1)
|
|
case reflect.Slice:
|
|
if cfg.useSafeImplementation {
|
|
return &safeSliceType{safeType}
|
|
}
|
|
return newUnsafeSliceType(cfg, type1)
|
|
case reflect.Map:
|
|
if cfg.useSafeImplementation {
|
|
return &safeMapType{safeType}
|
|
}
|
|
return newUnsafeMapType(cfg, type1)
|
|
case reflect.Ptr, reflect.Chan, reflect.Func:
|
|
if cfg.useSafeImplementation {
|
|
return &safeMapType{safeType}
|
|
}
|
|
return newUnsafePtrType(cfg, type1)
|
|
case reflect.Interface:
|
|
if cfg.useSafeImplementation {
|
|
return &safeMapType{safeType}
|
|
}
|
|
if type1.NumMethod() == 0 {
|
|
return newUnsafeEFaceType(cfg, type1)
|
|
}
|
|
return newUnsafeIFaceType(cfg, type1)
|
|
default:
|
|
if cfg.useSafeImplementation {
|
|
return &safeType
|
|
}
|
|
return newUnsafeType(cfg, type1)
|
|
}
|
|
}
|
|
|
|
func TypeOf(obj interface{}) Type {
|
|
return ConfigUnsafe.TypeOf(obj)
|
|
}
|
|
|
|
func TypeOfPtr(obj interface{}) PtrType {
|
|
return TypeOf(obj).(PtrType)
|
|
}
|
|
|
|
func Type2(type1 reflect.Type) Type {
|
|
if type1 == nil {
|
|
return nil
|
|
}
|
|
return ConfigUnsafe.Type2(type1)
|
|
}
|
|
|
|
func PtrTo(typ Type) Type {
|
|
return Type2(reflect.PtrTo(typ.Type1()))
|
|
}
|
|
|
|
func PtrOf(obj interface{}) unsafe.Pointer {
|
|
return unpackEFace(obj).data
|
|
}
|
|
|
|
func RTypeOf(obj interface{}) uintptr {
|
|
return uintptr(unpackEFace(obj).rtype)
|
|
}
|
|
|
|
func IsNil(obj interface{}) bool {
|
|
if obj == nil {
|
|
return true
|
|
}
|
|
return unpackEFace(obj).data == nil
|
|
}
|
|
|
|
func IsNullable(kind reflect.Kind) bool {
|
|
switch kind {
|
|
case reflect.Ptr, reflect.Map, reflect.Chan, reflect.Func, reflect.Slice, reflect.Interface:
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func likePtrKind(kind reflect.Kind) bool {
|
|
switch kind {
|
|
case reflect.Ptr, reflect.Map, reflect.Chan, reflect.Func:
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func likePtrType(typ reflect.Type) bool {
|
|
if likePtrKind(typ.Kind()) {
|
|
return true
|
|
}
|
|
if typ.Kind() == reflect.Struct {
|
|
if typ.NumField() != 1 {
|
|
return false
|
|
}
|
|
return likePtrType(typ.Field(0).Type)
|
|
}
|
|
if typ.Kind() == reflect.Array {
|
|
if typ.Len() != 1 {
|
|
return false
|
|
}
|
|
return likePtrType(typ.Elem())
|
|
}
|
|
return false
|
|
}
|
|
|
|
// NoEscape hides a pointer from escape analysis. noescape is
|
|
// the identity function but escape analysis doesn't think the
|
|
// output depends on the input. noescape is inlined and currently
|
|
// compiles down to zero instructions.
|
|
// USE CAREFULLY!
|
|
//go:nosplit
|
|
func NoEscape(p unsafe.Pointer) unsafe.Pointer {
|
|
x := uintptr(p)
|
|
return unsafe.Pointer(x ^ 0)
|
|
}
|
|
|
|
func UnsafeCastString(str string) []byte {
|
|
stringHeader := (*reflect.StringHeader)(unsafe.Pointer(&str))
|
|
sliceHeader := &reflect.SliceHeader{
|
|
Data: stringHeader.Data,
|
|
Cap: stringHeader.Len,
|
|
Len: stringHeader.Len,
|
|
}
|
|
return *(*[]byte)(unsafe.Pointer(sliceHeader))
|
|
}
|