Beispiel #1
0
func (h *Handler) findEnterFunc(t reflect.Type) *reflect.Method {
	method, ok := t.MethodByName(flaglyEnter)
	if ok {
		return &method
	}
	return nil
}
Beispiel #2
0
func compileField(typ reflect.Type, name string, args []parse.Node, final reflect.Type) (fn lookupFn, elem reflect.Type) {
	if isNilType(typ) {
		fn = compileFieldDynamic(name, args)
		return
	}

	if m, exist := typ.MethodByName(name); exist {
		fn = compileMethodCall(typ, m.Func, args, final)
		elem = m.Type.Out(0)
		return
	}

	switch typ.Kind() {
	case reflect.Struct:
		structField, found := typ.FieldByName(name)
		if !found {
			panic(fmt.Errorf("%s has no field %s", typ, name))
		}
		fn = func(s state, v reflect.Value, final interface{}) reflect.Value {
			return v.FieldByIndex(structField.Index)
		}
		elem = structField.Type
		return
	case reflect.Map:
		k := reflect.ValueOf(name)
		fn = func(s state, v reflect.Value, final interface{}) reflect.Value {
			return v.MapIndex(k)
		}
		elem = typ.Key()
		return
	}
	panic(fmt.Errorf("struct or map expected, but got %s", typ))
}
Beispiel #3
0
func CheckMethod(t *testing.T, typ reflect.Type, desc Method) {
	method, found := typ.MethodByName(desc.Name)
	if !found {
		t.Fatalf("Le type %v ne définit pas de méthode '%s'", typ, desc.Name)
	}

	if method.Type.NumIn() != len(desc.InTypes)+1 {
		t.Fatalf("La méthode %v.%s doit prendre %d paramètre(s)", typ, desc.Name, len(desc.InTypes))
	}

	if method.Type.NumOut() != len(desc.OutTypes) {
		t.Fatalf("La méthode %v.%s doit renvoyer %d résultat(s)", typ, desc.Name, len(desc.OutTypes))
	}

	for i, inType := range desc.InTypes {
		if method.Type.In(i+1) != inType {
			t.Fatalf("La méthode %v.%s doit prendre un type %v en paramètre #%d", typ, desc.Name, inType, i+1)
		}
	}

	for i, outType := range desc.OutTypes {
		if method.Type.Out(i) != outType {
			t.Fatalf("La méthode %v.%s doit renvoyer un type %v en résultat #%d", typ, desc.Name, outType, i+1)
		}
	}
}
Beispiel #4
0
func (info *Info) addMethods(jt *Type, t reflect.Type) {
	// Add any methods.
	var vt reflect.Type
	if t.Kind() != reflect.Interface && !isWithoutReceiver(t) {
		t = reflect.PtrTo(t)
		vt = t.Elem()
	}
	for i := 0; i < t.NumMethod(); i++ {
		m := t.Method(i)
		if m.PkgPath != "" {
			continue
		}
		if t.Kind() != reflect.Interface {
			m.Type = withoutReceiverType{m.Type}
		}
		jm := Method{
			Name: m.Name,
			Type: info.Ref(m.Type),
		}
		if vt != nil {
			_, hasValueMethod := vt.MethodByName(m.Name)
			jm.PtrReceiver = !hasValueMethod
		}
		if jt.Methods == nil {
			jt.Methods = make(map[string]*Method)
		}
		jt.Methods[jm.Name] = &jm
	}
}
Beispiel #5
0
func dispose(v uintptr, t r.Type) {
	if m, ok := t.MethodByName("Dispose"); ok {
		// && m.Func.Type().NumIn() == 2 {
		f := m.Func
		tv := r.NewAt(f.Type().In(1).Elem(),
			unsafe.Pointer(v))
		f.Call([]r.Value{r.New(t).Elem(), tv})
	}
}
Beispiel #6
0
func missingMethod(iT, xT reflect.Type) (method string) {
	numMethod := iT.NumMethod()
	for i := 0; i < numMethod; i += 1 {
		method = iT.Method(i).Name
		if _, ok := xT.MethodByName(method); !ok {
			return
		}
	}
	return ""
}
Beispiel #7
0
func getMapMethods(baseType reflect.Type) (get, set reflect.Type, err error) {
	getAll, ok := baseType.MethodByName("GetAll")
	if !ok {
		return nil, nil, errors.Errorf("no method named GetAll")
	}
	setAll, ok := baseType.MethodByName("SetAll")
	if !ok {
		return nil, nil, errors.Errorf("no method named SetAll")
	}
	return getAll.Type, setAll.Type, nil
}
func MethodsMissingFromType(inter, typ reflect.Type) []string {
	missingMethods := make([]string, 0)
	for n := 0; n < inter.NumMethod(); n++ {
		_, present := typ.MethodByName(inter.Method(n).Name)
		if !present {
			fmt.Println(inter.Method(n).Name)
			missingMethods = append(missingMethods, inter.Method(n).Name)
		}
	}
	return missingMethods
}
Beispiel #9
0
func enumSymbols(t reflect.Type) []string {
	if _, ok := t.MethodByName("SymbolSet"); ok {
		//an enum type that RDL generated. Create a dummy instance and call to get the symbol set
		tmp := reflect.New(t)
		vv := tmp.Elem()
		vv.SetInt(1)
		symbols := tmp.MethodByName("SymbolSet").Call([]reflect.Value{})[0].Interface()
		return symbols.([]string)[1:]
	}
	return nil
}
Beispiel #10
0
func findParameterGetMethod(handlerParametersType reflect.Type, field reflect.Type) (reflect.Method, bool) {
	var name []rune
	switch field.Kind() {
	case reflect.Ptr:
		name = []rune(field.Elem().Kind().String())
	default:
		name = []rune(field.Kind().String())
	}
	name[0] = unicode.ToUpper(name[0])
	methodName := "Get" + string(name)
	return handlerParametersType.MethodByName(methodName)
}
Beispiel #11
0
func methodValue(key string, typ reflect.Type) (mapFunc, reflect.Type, error) {
	if m, ok := typ.MethodByName(key); ok {
		if m.Type.NumIn() > 1 {
			return nil, nil, fmt.Errorf("method %s on type %s has %d arguments, must have none", key, typ, m.Type.NumIn()-1)
		}
		if m.Type.NumOut() != 1 {
			return nil, nil, fmt.Errorf("method %s on type %s returns %d values, must return one", key, typ, m.Type.NumOut())
		}
		return methodValueFunc(m), m.Type.Out(0), nil
	}
	return nil, nil, nil
}
Beispiel #12
0
func getTypes(t reflect.Type, s supportingTypes, c *int) *Type {
	n, p := t.String(), t.PkgPath()

	if _, ok := t.MethodByName("MarshalJSON"); ok {
		return custom(n, p)
	}

	switch t.Kind() {
	case reflect.String:
		return simple(String)
	case reflect.Int, reflect.Int8, reflect.Int16,
		reflect.Int32, reflect.Int64,
		reflect.Uint, reflect.Uint8, reflect.Uint16,
		reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		return simple(Int)
	case reflect.Float32, reflect.Float64:
		return simple(Float)
	case reflect.Bool:
		return simple(Bool)
	case reflect.Ptr:
		return s.set(n, p, func() *Type {
			return ptrOf(getTypes(t.Elem(), s, c))
		})
	case reflect.Array, reflect.Slice:
		if t.Elem().Kind() == reflect.Uint8 {
			return simple(Bytes)
		}
		return s.set(n, p, func() *Type {
			return arrayOf(getTypes(t.Elem(), s, c))
		})
	case reflect.Struct:
		if p == "" {
			// gets an anonymous type name and fake the package
			n = anonTypeName(c)
			p = "github.com/shutej/go2flow/anonymous"
		}
		return s.set(n, p, func() *Type {
			return structOf(getFields(t, s, c))
		})
	case reflect.Map:
		if t.Key().Kind() != reflect.String {
			log.Fatalf("unexpected map key type: %v", t.Key())
		}
		return s.set(n, p, func() *Type {
			return mapOf(getTypes(t.Elem(), s, c))
		})
	}
	log.Fatalf("unknown kind for type: %v", t)
	return nil
}
Beispiel #13
0
func createTypeDescribe(typ reflect.Type) *typeDescribe {
	td := &typeDescribe{}
	td.initMethod, td.hasInitMethod = typ.MethodByName("PostConstruct")
	for typ.Kind() == reflect.Ptr {
		typ = typ.Elem()
	}
	for i := 0; i < typ.NumField(); i++ {
		f := typ.Field(i)
		tag := f.Tag.Get("inject")
		if tag != "" {
			td.fields = append(td.fields, f)
		}
	}
	typeDescribes[typ.String()] = td
	return td
}
Beispiel #14
0
func go2jsonType(t reflect.Type, canAddr bool) *Type {
	if _, ok := t.MethodByName("MarshalJSON"); ok {
		return CustomType(t.String())
	}
	if canAddr {
		if _, ok := reflect.PtrTo(t).MethodByName("MarshalJSON"); ok {
			return CustomType(t.String())
		}
	}
	switch t.Kind() {
	case reflect.Bool:
		return SimpleType(Bool)
	case reflect.Int, reflect.Int8, reflect.Int16,
		reflect.Int32, reflect.Int64,
		reflect.Uint, reflect.Uint8, reflect.Uint16,
		reflect.Uint32, reflect.Uint64, reflect.Uintptr,
		reflect.Float32, reflect.Float64:
		return SimpleType(Number)
	case reflect.String:
		return SimpleType(String)
	case reflect.Complex64, reflect.Complex128:
		return CustomType("complex")
	case reflect.Chan:
		return CustomType("chan")
	case reflect.Array, reflect.Slice:
		return ArrayOf(go2jsonType(t.Elem(), canAddr || t.Kind() == reflect.Slice))
	case reflect.Map:
		if t.Key().Kind() != reflect.String {
			// TODO better error recovery
			panic("unexpected map key kind")
		}
		return MapOf(go2jsonType(t.Elem(), false))
	case reflect.Ptr:
		return NullableOf(go2jsonType(t.Elem(), true))
	case reflect.Struct:
		return ObjectOf(jsonFields(t, canAddr))
	case reflect.UnsafePointer:
		return CustomType("unsafe.Pointer")
	case reflect.Interface:
		return CustomType("any")
	case reflect.Func:
		return CustomType("func")
	}
	panic(fmt.Errorf("unknown kind for type %s", t))
}
Beispiel #15
0
func (p *Page) callMethod(tpc reflect.Type, vpc reflect.Value, action string, rvr reflect.Value, rvw reflect.Value) []reflect.Value {
	arv := []reflect.Value{}
	if rm, ok := tpc.MethodByName(action); ok {
		mt := rm.Type
		switch mt.NumIn() {
		case 2:
			if mt.In(1) == rvr.Type() {
				arv = vpc.MethodByName(action).Call([]reflect.Value{rvr})
			} else {
				arv = vpc.MethodByName(action).Call([]reflect.Value{rvw})
			}
		case 3:
			arv = vpc.MethodByName(action).Call([]reflect.Value{rvw, rvr})
		default:
			arv = vpc.MethodByName(action).Call([]reflect.Value{})
		}
	}

	return arv
}
Beispiel #16
0
// Route registers a route by method name.
func (r *Router) Route(path, name string, context reflect.Type, methods []string) error {
	rule, err := r.Rule(path, name, methods)
	if err != nil {
		return err
	}

	parts := strings.Split(name, ".")
	method, ok := context.MethodByName(parts[len(parts)-1])
	if !ok {
		return nil // change
	}

	r.endpoints[rule] = &endpoint{
		context:  context,
		method:   method.Func,
		bindings: make(map[string]interface{}),
	}

	return nil
}
Beispiel #17
0
func MakeMethods(typ reflect.Type) (m *Methods, err error) {
	m = &Methods{-1, -1}
	// Get pointer methods
	if typ.Kind() != reflect.Ptr {
		typ = reflect.PtrTo(typ)
	}
	// Check for Load and Save methods
	if load, ok := typ.MethodByName("Load"); ok {
		if err = checkMethod(typ, load); err != nil {
			return
		}
		m.LoadIndex = load.Index
	}
	if save, ok := typ.MethodByName("Save"); ok {
		if err = checkMethod(typ, save); err != nil {
			return
		}
		m.SaveIndex = save.Index
	}
	return
}
Beispiel #18
0
// GetMissingMethods checks if a given object implements all methods of a
// given interface. It returns the interface coverage [0..1] as well as an array
// of error messages. If the interface is correctly implemented the coverage is
// 1 and the error message array is empty.
func GetMissingMethods(objType reflect.Type, ifaceType reflect.Type) (float32, []interface{}) {
	var missing []interface{}
	if objType.Implements(ifaceType) {
		return 1.0, missing
	}

	methodCount := ifaceType.NumMethod()
	for mIdx := 0; mIdx < methodCount; mIdx++ {
		ifaceMethod := ifaceType.Method(mIdx)
		objMethod, exists := objType.MethodByName(ifaceMethod.Name)
		signatureMismatch := false

		switch {
		case !exists:
			missing = append(missing, fmt.Sprintf("Missing: \"%s\" %v", ifaceMethod.Name, ifaceMethod.Type))
			continue // ### continue, error found ###

		case ifaceMethod.Type.NumOut() != objMethod.Type.NumOut():
			signatureMismatch = true

		case ifaceMethod.Type.NumIn()+1 != objMethod.Type.NumIn():
			signatureMismatch = true

		default:
			for oIdx := 0; !signatureMismatch && oIdx < ifaceMethod.Type.NumOut(); oIdx++ {
				signatureMismatch = ifaceMethod.Type.Out(oIdx) != objMethod.Type.Out(oIdx)
			}
			for iIdx := 0; !signatureMismatch && iIdx < ifaceMethod.Type.NumIn(); iIdx++ {
				signatureMismatch = ifaceMethod.Type.In(iIdx) != objMethod.Type.In(iIdx+1)
			}
		}

		if signatureMismatch {
			missing = append(missing, fmt.Sprintf("Invalid: \"%s\" %v is not %v", ifaceMethod.Name, objMethod.Type, ifaceMethod.Type))
		}
	}

	return float32(methodCount-len(missing)) / float32(methodCount), missing
}
Beispiel #19
0
func AddApis(am Apis) {
	for _, a := range am {
		f := r.ValueOf(a.Fnc)
		if f.Kind() != r.Ptr {
			panic("outside: " + r.TypeOf(a.Fnc).String() + " supplied : Pointer to function expected")
		}
		fn := f.Elem()
		fnt := fn.Type()
		var apiCall func(i []r.Value) []r.Value
		//Allow 2 returns and put err in 2nd if supplied
		var ot, et r.Type
		nOut := fnt.NumOut()
		if nOut >= 1 {
			ot = fnt.Out(0)
		}
		if nOut == 2 {
			et = fnt.Out(1)
		}
		p, unicode := apiAddr(a.Ep)
		if p != nil {
			fai, sli, fao, slo := funcAnalysis(fnt)
			// name := a.Ep
			retSizeArg := -1
			if nOut >= 1 && ot.Kind() == r.Slice {
				if sa, ok := ot.MethodByName("SizeArg"); ok {
					retSizeArg = int(sa.Func.Call([]r.Value{r.Indirect(r.New(ot))})[0].Int() - 1)
				}
			}
			var hasErrorMethod bool
			var ea r.Method
			if ot != nil {
				ea, hasErrorMethod = ot.MethodByName("Error")
			}
			apiCall = func(i []r.Value) []r.Value {
				TOT++
				var rr r.Value
				inStructs(unicode, i, fai, sli)
				ina := inArgs(unicode, i)
				r1, r2, f, err := p.call(ina...)
				// Printf("%s %v %v %b %x %b %x\n", name, i, ot, fai, sli, fao, slo)
				outStructs(unicode, i, fao, slo)
				if ot != nil {
					if runtime.GOARCH == "amd64" || ot.Size() == 4 {
						rr = r.ValueOf(r1)
					} else if fnt.Out(0).Kind() == r.Float64 || fnt.Out(0).Kind() == r.Float32 {
						rr = r.ValueOf(f)
					} else {
						rr = r.ValueOf((uint64(r2) << 32) | uint64(r1))
					}
					vrsa := rsaNo
					if retSizeArg != -1 {
						vrsa = i[retSizeArg]
					}
					v1 := convert(rr, ot, unicode, vrsa)
					if hasErrorMethod {
						// TODO(t): for linux - error strategy
						var ret []r.Value
						if err == nil {
							ret = ea.Func.Call([]r.Value{v1, r.Zero(r.TypeOf(new(error)).Elem())}) // issue 6871
						} else {
							ret = ea.Func.Call([]r.Value{v1, r.ValueOf(err)})
						}
						v1 = ret[0]
						if e := ret[1].Interface(); e != nil {
							err = e.(error)
						} else {
							err = nil
						}
					}
					if et == nil {
						return []r.Value{v1}
					} else {
						return []r.Value{v1, convert(r.ValueOf(err), et, unicode, rsaNo)}
					}
				} else {
					return nil
				}
			}
		} else {
			apiCall = func(i []r.Value) []r.Value {
				panic(`outside: call of non-existent procedure "` + string(a.Ep) + `"`)
			}
		}
		v := r.MakeFunc(fn.Type(), apiCall)
		fn.Set(v)
	}
}
Beispiel #20
0
// From the endpoint, defined in the Service struct, init the variables and the server listeners.
// Besides, load de configuration file to start basic data required for the proposed solution.
func initSvc(svcElem EndPointHandler) (*Service, error) {
	var err error
	var i int
	var resp *Service
	var cfg Shaper
	var ls net.Listener
	var met reflect.Method
	var ok bool
	var typ reflect.Type
	var fld reflect.StructField
	var auth AuthT

	resp = &Service{
		//      AuthRequired: false,
		MatchedOps: map[int]int{},
	}

	cfg, err = svcElem.GetConfig()
	if err != nil {
		Goose.Initialize.Logf(1, "Failed opening config: %s", err)
		return nil, err
	}

	if cfg == nil {
		return nil, nil
	}

	/*
	   //TODO: shaper -> remover
	   err = json.NewDecoder(cfg).Decode(&resp)

	   if (err!=nil) && (err!=io.EOF) {
	      Goose.Initialize.Logf(1,"Failed parsing config file: %s", err)
	      return nil, err
	   }
	*/

	resp.Config = cfg

	ls, err = net.Listen("tcp", cfg.ListenAddress())
	if err != nil {
		Goose.Initialize.Logf(1, "Failed creating listener: %s", err)
		return nil, err
	}

	resp.Listener, err = NewListener(ls)
	if err != nil {
		Goose.Initialize.Logf(1, "Failed creating stoppable listener: %s", err)
		return nil, err
	}

	ls, err = net.Listen("tcp", cfg.CRLListenAddress())
	if err != nil {
		Goose.Initialize.Logf(1, "Failed creating listener: %s", err)
		return nil, err
	}

	resp.CRLListener, err = NewListener(ls)
	if err != nil {
		Goose.Initialize.Logf(1, "Failed creating stoppable listener: %s", err)
		return nil, err
	}

	typ = reflect.ValueOf(svcElem).Type()
	if typ.Kind() == reflect.Ptr {
		typ = typ.Elem()
	}

	met, ok = typ.MethodByName("SavePending")
	if ok {
		resp.SavePending = func(info interface{}) error {
			var err error

			errIFace := met.Func.Call([]reflect.Value{reflect.ValueOf(resp.Config), reflect.ValueOf(info)})[0].Interface()
			switch errIFace.(type) {
			case error:
				err = errIFace.(error)
			}

			if err != nil {
				Goose.Auth.Logf(1, "Internal server error saving unauthorized access attempt info: %s", err)
				Goose.Auth.Logf(5, "Dump of info on internal server error saving unauthorized access attempt info: %#v", info)
			}
			return err
		}
	} else {
		resp.SavePending = func(interface{}) error {
			return nil
		}
	}

	Goose.Auth.Logf(5, "cfg: %#v", cfg)
	Goose.Auth.Logf(5, "cfg.CertKit(): %#v", cfg.CertKit())
	Goose.Auth.Logf(5, "auth: %#v", auth)
	Goose.Auth.Logf(5, "auth: %#v", reflect.TypeOf((*AuthT)(nil)).Elem())
	if cfg.CertKit() != nil && reflect.TypeOf(cfg.CertKit()).Implements(reflect.TypeOf((*AuthT)(nil)).Elem()) {
		resp.Authorizer = cfg.CertKit()
	} else {
		resp.Authorizer = PublicAccessT{}
	}

	for i = 0; i < typ.NumField(); i++ {
		fld = typ.Field(i)
		if fld.Anonymous && fld.Type.Implements(reflect.TypeOf((*AuthT)(nil)).Elem()) {
			resp.Authorizer = reflect.ValueOf(svcElem).Field(i).Interface().(AuthT)
			break
		}
	}

	return resp, err
}
Beispiel #21
0
func New(svcs ...EndPointHandler) (*Service, error) {
	var resp *Service
	var svc EndPointHandler
	var svcElem EndPointHandler
	var svcRecv reflect.Value
	var consumes string
	var svcConsumes string
	var produces string
	var svcProduces string
	var allowGzip string
	var enableCORS string
	var proto []string
	var svcProto []string
	var svcRoot string
	var i, j, k int
	var typ reflect.Type
	var typPtr reflect.Type
	var pt []reflect.Type
	var fld reflect.StructField
	var method reflect.Method
	var parmcount int
	var httpmethod, path string
	var methodName string
	var tk string
	var ok bool
	var re string
	var reAllOps string
	var reComp *regexp.Regexp
	var c rune
	var err error
	var stmp string
	var SwaggerParameter *SwaggerParameterT
	var swaggerParameters []SwaggerParameterT
	var swaggerInfo SwaggerInfoT
	var swaggerLicense SwaggerLicenseT
	var swaggerContact SwaggerContactT
	var globalDataCount int
	var responseOk string
	var responseCreated string
	var responseAccepted string
	var responses map[string]SwaggerResponseT
	var fldType reflect.Type
	var doc string
	var description *string
	var headers []string
	var query []string
	var optIndex map[string]int
	var HdrNew, HdrOld string
	var MatchedOpsIndex int
	var postFields []string
	var postField string
	var postdata string
	//   var accesstype           uint8
	var parmnames []string

	for _, svc = range svcs {
		Goose.New.Logf(6, "Elem: %#v (Kind: %#v)", reflect.ValueOf(svc), reflect.ValueOf(svc).Kind())
		if reflect.ValueOf(svc).Kind() == reflect.Ptr {
			Goose.New.Logf(6, "Elem: %#v", reflect.ValueOf(svc).Elem())
			svcElem = reflect.ValueOf(svc).Elem().Interface().(EndPointHandler)
			Goose.New.Logf(6, "Elem type: %s, ptr type: %s", reflect.TypeOf(svcElem), reflect.TypeOf(svc))
		} else {
			svcElem = svc
			Goose.New.Logf(6, "Elem type: %s", reflect.TypeOf(svcElem))
		}

		// The first endpoint handler MUST have a config defined, otherwise we'll ignore endpoint handlers until we find one which provides a configuration
		if resp == nil {
			resp, err = initSvc(svcElem)
			if err != nil {
				return nil, err
			}
			if resp == nil {
				continue // If we still don't have a config defined and the endpoint handler has no config defined it WILL BE IGNORED!!!
			}
		}

		typ = reflect.ValueOf(svcElem).Type()
		if typ.Kind() == reflect.Ptr {
			typPtr = typ
			typ = typ.Elem()
		} else {
			typPtr = reflect.PtrTo(typ)
		}

		if resp.Swagger == nil {
			for i = 0; (i < typ.NumField()) && (globalDataCount < 4); i++ {
				if svcRoot == "" {
					svcRoot = typ.Field(i).Tag.Get("root")
					if svcRoot != "" {
						svcConsumes = typ.Field(i).Tag.Get("consumes")
						svcProduces = typ.Field(i).Tag.Get("produces")
						allowGzip = typ.Field(i).Tag.Get("allowGzip")
						enableCORS = typ.Field(i).Tag.Get("enableCORS")
						if typ.Field(i).Tag.Get("proto") != "" {
							svcProto = strings.Split(strings.ToLower(strings.Trim(typ.Field(i).Tag.Get("proto"), " ")), ",")
						} else {
							svcProto = []string{"https"}
						}

						Goose.New.Logf(3, "Access tag: %s", typ.Field(i).Tag.Get("access"))

						if typ.Field(i).Tag.Get("access") != "" {
							switch strings.ToLower(strings.Trim(typ.Field(i).Tag.Get("access"), " ")) {
							case "none":
								resp.Access = AccessNone
							case "auth":
								resp.Access = AccessAuth
							case "authinfo":
								resp.Access = AccessAuthInfo
							case "verifyauth":
								resp.Access = AccessVerifyAuth
							case "verifyauthinfo":
								resp.Access = AccessVerifyAuthInfo
							}
							Goose.New.Logf(3, "Custom access type: %d", resp.Access)
						} else {
							resp.Access = AccessAuthInfo
							Goose.New.Logf(3, "Default access type: %d", resp.Access)
						}
						globalDataCount++
					}
				}
				if swaggerInfo.Title == "" {
					stmp = typ.Field(i).Tag.Get("title")
					if stmp != "" {
						swaggerInfo.Title = stmp
						swaggerInfo.Description = typ.Field(i).Tag.Get("description")
						swaggerInfo.TermsOfService = typ.Field(i).Tag.Get("tos")
						swaggerInfo.Version = typ.Field(i).Tag.Get("version")
						globalDataCount++
					}
				}
				if swaggerContact.Name == "" {
					stmp = typ.Field(i).Tag.Get("contact")
					if stmp != "" {
						swaggerContact.Name = stmp
						swaggerContact.Url = typ.Field(i).Tag.Get("url")
						swaggerContact.Email = typ.Field(i).Tag.Get("email")
						globalDataCount++
					}
				}
				if swaggerLicense.Name == "" {
					stmp = typ.Field(i).Tag.Get("license")
					if stmp != "" {
						swaggerLicense.Name = stmp
						swaggerLicense.Url = typ.Field(i).Tag.Get("url")
						globalDataCount++
					}
				}
			}

			swaggerInfo.Contact = swaggerContact
			swaggerInfo.License = swaggerLicense

			svcRoot = strings.Trim(strings.Trim(svcRoot, " "), "/") + "/"
			svcConsumes = strings.Trim(svcConsumes, " ")
			svcProduces = strings.Trim(svcProduces, " ")

			if (svcRoot == "") || (svcConsumes == "") || (svcProduces == "") {
				Goose.New.Logf(1, "Err: %s", ErrorNoRoot)
				return nil, ErrorNoRoot
			}

			hostport := strings.Split(resp.Config.ListenAddress(), ":")
			if hostport[0] == "" {
				hostport[0] = resp.Authorizer.GetDNSNames()[0]
			}

			resp.Swagger = &SwaggerT{
				Version:     "2.0",
				Info:        swaggerInfo,
				Host:        strings.Join(hostport, ":"),
				BasePath:    "/" + svcRoot[:len(svcRoot)-1],
				Schemes:     svcProto,
				Consumes:    []string{svcConsumes},
				Produces:    []string{svcProduces},
				Paths:       map[string]SwaggerPathT{},
				Definitions: map[string]SwaggerSchemaT{},
			}

			resp.Proto = svcProto

			Goose.New.Logf(6, "enableCORS: [%s]", enableCORS)
			if enableCORS != "" {
				resp.EnableCORS, err = strconv.ParseBool(enableCORS)
				Goose.New.Logf(6, "resp.EnableCORS: %#v", resp.EnableCORS)
				if err != nil {
					Goose.New.Logf(1, "Err: %s", ErrorServiceSyntax)
					return nil, ErrorServiceSyntax
				}
			}

			Goose.New.Logf(6, "allowGzip: [%s]", allowGzip)
			if allowGzip != "" {
				resp.AllowGzip, err = strconv.ParseBool(allowGzip)
				Goose.New.Logf(6, "resp.AllowGzip: %#v", resp.AllowGzip)
				if err != nil {
					Goose.New.Logf(1, "Err: %s", ErrorServiceSyntax)
					return nil, ErrorServiceSyntax
				}
			}
		}

		for i = 0; i < typ.NumField(); i++ {
			fld = typ.Field(i)
			httpmethod = fld.Tag.Get("method")
			if httpmethod != "" {
				methodName = strings.ToUpper(fld.Name[:1]) + fld.Name[1:]
				svcRecv = reflect.ValueOf(svcElem)
				if method, ok = typ.MethodByName(methodName); !ok {
					if method, ok = typPtr.MethodByName(methodName); !ok {
						Goose.New.Logf(5, "|methods|=%d", typ.NumMethod())
						Goose.New.Logf(5, "type=%s.%s", typ.PkgPath(), typ.Name())
						for j = 0; j < typ.NumMethod(); j++ {
							mt := typ.Method(j)
							Goose.New.Logf(5, "%d: %s", j, mt.Name)
						}

						Goose.New.Logf(1, "Method not found: %s, Data: %#v", methodName, typ)
						return nil, errors.New(fmt.Sprintf("Method not found: %s", methodName))
					} else {
						Goose.New.Logf(1, "Pointer method found, type of svcElem: %s", reflect.TypeOf(svcElem))
						svcRecv = reflect.ValueOf(svc)
						Goose.New.Logf(5, "Pointer method found: %s", methodName)
					}
				}
				path = fld.Tag.Get("path")

				if _, ok := resp.Swagger.Paths[path]; !ok {
					resp.Swagger.Paths[path] = SwaggerPathT{}
					//         } else if _, ok := resp.Swagger.Paths[path][httpmethod]; !ok {
					//            resp.Swagger.Paths[path][httpmethod] = SwaggerOperationT{}
				}

				swaggerParameters = []SwaggerParameterT{}

				re = "^" + strings.ToUpper(httpmethod) + ":/" + svcRoot

				parmcount = 0
				parmnames = []string{}

				for _, tk = range strings.Split(strings.Trim(path, "/"), "/") {
					if tk != "" {
						if (tk[0] == '{') && (tk[len(tk)-1] == '}') {
							re += "([^/]+)/"
							parmcount++
							SwaggerParameter, err = GetSwaggerType(method.Type.In(parmcount))
							if err != nil {
								return nil, err
							}

							if SwaggerParameter == nil {
								return nil, ErrorInvalidNilParam
							}

							if (SwaggerParameter.Items != nil) || (SwaggerParameter.CollectionFormat != "") || (SwaggerParameter.Schema.Required != nil) {
								Goose.New.Logf(1, "%s: %s", tk[1:len(tk)-1])
								return nil, ErrorInvalidParameterType
							}

							doc = fld.Tag.Get(tk[1 : len(tk)-1])
							if doc != "" {
								description = new(string)
								(*description) = doc
							} else {
								description = SwaggerParameter.Schema.Description
								if description == nil {
									description = new(string)
								}
							}

							xkeytype := ""
							if SwaggerParameter.Schema != nil {
								xkeytype = SwaggerParameter.Schema.XKeyType
							}

							swaggerParameters = append(
								swaggerParameters,
								SwaggerParameterT{
									Name:        tk[1 : len(tk)-1],
									In:          "path",
									Required:    true,
									Type:        SwaggerParameter.Schema.Type,
									XKeyType:    xkeytype,
									Description: *description,
									Format:      SwaggerParameter.Format,
								})
							parmnames = append(parmnames, tk[1:len(tk)-1])
						} else if (tk[0] != '{') && (tk[len(tk)-1] != '}') {
							for _, c = range tk {
								re += fmt.Sprintf("\\x{%x}", c)
							}
							re += "/"
						} else {
							return nil, errors.New("syntax error at " + tk)
						}
					}
				}

				if resp.Svc == nil {
					resp.Svc = []UrlNode{}
				}

				re += "{0,1}$"

				Goose.New.Logf(4, "Service "+strings.ToUpper(httpmethod)+":/"+svcRoot+path+", RE="+re)

				query, parmcount, _, swaggerParameters, err = ParseFieldList("query", parmcount, fld, method, methodName, swaggerParameters)
				if err != nil {
					return nil, err
				}

				headers, parmcount, _, swaggerParameters, err = ParseFieldList("header", parmcount, fld, method, methodName, swaggerParameters)
				if err != nil {
					return nil, err
				}

				parmnames = append(parmnames, query...)
				parmnames = append(parmnames, headers...)

				postdata = fld.Tag.Get("postdata")
				if postdata != "" {
					// Body fields definitions
					postFields = strings.Split(postdata, ",")
					pt = make([]reflect.Type, len(postFields))
					for k, postField = range postFields {
						parmcount++
						pt[k] = method.Type.In(parmcount)
						SwaggerParameter, err = GetSwaggerType(pt[k])
						if err != nil {
							return nil, err
						}

						if SwaggerParameter == nil {
							return nil, ErrorInvalidNilParam
						}

						doc = fld.Tag.Get(postField)
						if doc != "" {
							SwaggerParameter.Schema.Description = new(string)
							(*SwaggerParameter.Schema.Description) = doc
						}

						parmnames = append(parmnames, postField)
						SwaggerParameter.Name = postField
						SwaggerParameter.In = "body"
						SwaggerParameter.Required = true

						swaggerParameters = append(swaggerParameters, *SwaggerParameter)
					}

					/*
					   if resp.Access == AccessAuthInfo || resp.Access == AccessVerifyAuthInfo {
					      parmcount++
					   }

					   if (parmcount+len(postFields)+1) != method.Type.NumIn() {
					      return nil, errors.New("Wrong parameter count (with post) at method " + methodName)
					   }
					*/
				} else {
					pt = nil
				}

				if resp.Access == AccessAuthInfo || resp.Access == AccessVerifyAuthInfo {
					if (parmcount + 1) != method.Type.NumIn() {
						parmcount++
						if (parmcount + 1) != method.Type.NumIn() {
							return nil, errors.New("Wrong parameter (with info) count at method " + methodName)
						}
					}
				} else {
					if (parmcount + 1) != method.Type.NumIn() {
						return nil, errors.New("Wrong parameter count at method " + methodName)
					}
				}

				Goose.New.Logf(5, "Registering: %s", re)
				consumes = fld.Tag.Get("consumes")
				Goose.New.Logf(1, "op:%s consumes: %s tag:%#v", methodName, consumes, fld.Tag)
				if consumes == "" {
					consumes = svcConsumes
				}

				produces = fld.Tag.Get("produces")
				if produces == "" {
					produces = svcProduces
				}

				if fld.Tag.Get("proto") != "" {
					proto = strings.Split(strings.ToLower(strings.Trim(typ.Field(i).Tag.Get("proto"), " ")), ",")
				} else {
					proto = svcProto
				}

				responses = map[string]SwaggerResponseT{}

				responseOk = fld.Tag.Get("ok")
				responseCreated = fld.Tag.Get("created")
				responseAccepted = fld.Tag.Get("accepted")
				if responseOk != "" || responseCreated != "" || responseAccepted != "" {
					if responseOk != "" {
						fldType = fld.Type
						if fldType.Kind() == reflect.Ptr {
							fldType = fldType.Elem()
						}

						SwaggerParameter, err = GetSwaggerType(fldType)
						if err != nil {
							return nil, err
						}

						if SwaggerParameter == nil {
							responses[fmt.Sprintf("%d", http.StatusNoContent)] = SwaggerResponseT{
								Description: responseOk,
							}
						} else {

							doc = fld.Tag.Get(fld.Name)

							if doc != "" {
								SwaggerParameter.Schema.Description = new(string)
								(*SwaggerParameter.Schema.Description) = doc
							}

							if SwaggerParameter.Schema == nil {
								SwaggerParameter.Schema = &SwaggerSchemaT{}
							}

							if (SwaggerParameter.Schema.Type == "") && (SwaggerParameter.Type != "") {
								SwaggerParameter.Schema.Type = SwaggerParameter.Type
							}

							responses[fmt.Sprintf("%d", http.StatusOK)] = SwaggerResponseT{
								Description: responseOk,
								Schema:      SwaggerParameter.Schema,
							}
							//(*responses[fmt.Sprintf("%d",http.StatusOK)].Schema) = *SwaggerParameter.Schema
							//ioutil.WriteFile("debug.txt", []byte(fmt.Sprintf("%#v",responses)), os.FileMode(0770))
							Goose.New.Logf(6, "====== %#v", *(responses[fmt.Sprintf("%d", http.StatusOK)].Schema))
						}
					}
					if responseCreated != "" {
						fldType = fld.Type
						if fldType.Kind() == reflect.Ptr {
							fldType = fldType.Elem()
						}

						SwaggerParameter, err = GetSwaggerType(fldType)
						if err != nil {
							return nil, err
						}

						if SwaggerParameter == nil {
							responses[fmt.Sprintf("%d", http.StatusCreated)] = SwaggerResponseT{
								Description: responseCreated,
							}
						} else {

							doc = fld.Tag.Get(fld.Name)

							if doc != "" {
								SwaggerParameter.Schema.Description = new(string)
								(*SwaggerParameter.Schema.Description) = doc
							}

							if SwaggerParameter.Schema == nil {
								SwaggerParameter.Schema = &SwaggerSchemaT{}
							}

							if (SwaggerParameter.Schema.Type == "") && (SwaggerParameter.Type != "") {
								SwaggerParameter.Schema.Type = SwaggerParameter.Type
							}

							responses[fmt.Sprintf("%d", http.StatusCreated)] = SwaggerResponseT{
								Description: responseCreated,
								Schema:      SwaggerParameter.Schema,
							}
							//(*responses[fmt.Sprintf("%d",http.StatusOK)].Schema) = *SwaggerParameter.Schema
							//ioutil.WriteFile("debug.txt", []byte(fmt.Sprintf("%#v",responses)), os.FileMode(0770))
							Goose.New.Logf(6, "====== %#v", *(responses[fmt.Sprintf("%d", http.StatusCreated)].Schema))
						}
					}
					if responseAccepted != "" {
						fldType = fld.Type
						if fldType.Kind() == reflect.Ptr {
							fldType = fldType.Elem()
						}

						SwaggerParameter, err = GetSwaggerType(fldType)
						if err != nil {
							return nil, err
						}

						if SwaggerParameter == nil {
							responses[fmt.Sprintf("%d", http.StatusAccepted)] = SwaggerResponseT{
								Description: responseAccepted,
							}
						} else {

							doc = fld.Tag.Get(fld.Name)

							if doc != "" {
								SwaggerParameter.Schema.Description = new(string)
								(*SwaggerParameter.Schema.Description) = doc
							}

							if SwaggerParameter.Schema == nil {
								SwaggerParameter.Schema = &SwaggerSchemaT{}
							}

							if (SwaggerParameter.Schema.Type == "") && (SwaggerParameter.Type != "") {
								SwaggerParameter.Schema.Type = SwaggerParameter.Type
							}

							responses[fmt.Sprintf("%d", http.StatusAccepted)] = SwaggerResponseT{
								Description: responseAccepted,
								Schema:      SwaggerParameter.Schema,
							}
							//(*responses[fmt.Sprintf("%d",http.StatusOK)].Schema) = *SwaggerParameter.Schema
							//ioutil.WriteFile("debug.txt", []byte(fmt.Sprintf("%#v",responses)), os.FileMode(0770))
							Goose.New.Logf(6, "====== %#v", *(responses[fmt.Sprintf("%d", http.StatusAccepted)].Schema))
						}
					}
				} else if responseFunc, ok := typ.MethodByName(fld.Name + "Responses"); ok {
					responseList := responseFunc.Func.Call([]reflect.Value{})[0].Interface().(map[string]ResponseT)
					for responseStatus, responseSchema := range responseList {
						SwaggerParameter, err = GetSwaggerType(reflect.TypeOf(responseSchema.TypeReturned))
						if err != nil {
							return nil, err
						}
						if SwaggerParameter == nil {
							responses[responseStatus] = SwaggerResponseT{
								Description: responseSchema.Description,
							}
						} else {
							responses[responseStatus] = SwaggerResponseT{
								Description: responseSchema.Description,
								Schema:      SwaggerParameter.Schema,
							}
						}
					}
				}

				resp.Swagger.Paths[path][strings.ToLower(httpmethod)] = SwaggerOperationT{
					Schemes:     proto,
					OperationId: methodName,
					Parameters:  swaggerParameters,
					Responses:   responses,
					Consumes:    []string{consumes},
					Produces:    []string{produces},
				}

				Goose.New.Logf(5, "Registering marshalers: %s, %s", consumes, produces)

				resp.MatchedOps[MatchedOpsIndex] = len(resp.Svc)
				reComp = regexp.MustCompile(re)
				MatchedOpsIndex += reComp.NumSubexp() + 1

				/*
				   switch strings.ToLower(fld.Tag.Get("access")) {
				      case "none":     accesstype = AccessNone
				      case "auth":     accesstype = AccessAuth
				      case "authinfo": accesstype = AccessAuthInfo
				      default:         accesstype = AccessAuth
				   }
				*/

				resp.Svc = append(resp.Svc, UrlNode{
					Proto:     proto,
					Path:      path,
					consumes:  consumes,
					produces:  produces,
					Headers:   headers,
					Query:     query,
					Body:      postFields,
					ParmNames: parmnames,
					Handle:    buildHandle(svcRecv, method, pt, resp.Access),
					//               Access:    resp.Access,
				})

				reAllOps += "|(" + re + ")"
				Goose.New.Logf(6, "Partial Matcher for %s is %s", path, reAllOps)

				if resp.EnableCORS {
					index := len(resp.Svc)
					if optIndex == nil {
						optIndex = map[string]int{path: index}
					} else if index, ok = optIndex[path]; ok {
						for _, HdrNew = range headers {
							for _, HdrOld = range resp.Svc[index].Headers {
								if HdrOld == HdrNew {
									break
								}
							}
							if HdrOld != HdrNew {
								resp.Svc[index].Headers = append(resp.Svc[index].Headers, HdrNew)
							}
						}
						continue
					} else {
						optIndex[path] = len(resp.Svc)
					}

					re = "^OPTIONS" + re[len(httpmethod)+1:]
					resp.MatchedOps[MatchedOpsIndex] = len(resp.Svc)
					reComp = regexp.MustCompile(re)
					MatchedOpsIndex += reComp.NumSubexp() + 1

					resp.Svc = append(resp.Svc, UrlNode{
						Path:    path,
						Headers: headers,
					})
					reAllOps += "|(" + re + ")"
					Goose.New.Logf(6, "Partial Matcher with options for %s is %s", path, reAllOps)
				}
			}
		}
	}

	Goose.New.Logf(6, "Operations matcher: %s\n", reAllOps[1:])
	Goose.New.Logf(6, "Operations %#v\n", resp.Svc)
	resp.Matcher = regexp.MustCompile(reAllOps[1:]) // Cutting the leading '|'
	return resp, nil
}