~tsileo/gluapp

12ed52fbe112ec18c63d0ce65f7126b4e1c45825 — Thomas Sileo 4 years ago e8e54ae
New url module
2 files changed, 102 insertions(+), 0 deletions(-)

M gluapp.go
M http.go
M gluapp.go => gluapp.go +66 -0
@@ 82,6 82,70 @@ func setupMetatable(L *lua.LState) {
		"raw":     valuesRaw,
		"encode":  valuesEncode,
	}))
	mtURL := L.NewTypeMetatable("lurl")
	L.SetField(mtURL, "__tostring", L.NewFunction(func(ls *lua.LState) int {
		ud := L.CheckUserData(1)
		url, ok := ud.Value.(*lurl)
		if !ok {
			panic("bad userdata")
		}
		url.u.RawQuery = url.qs.Encode()
		L.Push(lua.LString(url.u.String()))
		return 1
	}))
	L.SetField(mtURL, "__index", L.NewFunction(func(ls *lua.LState) int {
		ud := ls.CheckUserData(1)
		url, ok := ud.Value.(*lurl)
		if !ok {
			panic("bad userdata")
		}
		k := ls.ToString(2)
		var v string
		switch k {
		case "path":
			v = url.u.Path
		case "host":
			v = url.u.Host
		case "scheme":
			v = url.u.Scheme
		case "fragment":
			v = url.u.Fragment
		case "query":
			ls.Push(buildValues(ls, url.qs))
			return 1
		default:
			ls.Push(lua.LNil)
			return 1
		}
		ls.Push(lua.LString(v))
		return 1
	}))
	L.SetField(mtURL, "__newindex", L.NewFunction(func(ls *lua.LState) int {
		ud := ls.CheckUserData(1)
		url, ok := ud.Value.(*lurl)
		if !ok {
			panic("bad userdata")
		}
		k := ls.ToString(2)
		v := ls.ToString(3)
		switch k {
		case "path":
			url.u.Path = v
		case "host":
			url.u.Host = v
		case "scheme":
			url.u.Scheme = v
		case "fragment":
			url.u.Fragment = v
		default:
			if k == "query" {
				ls.ArgError(2, "please update query directly")
			} else {
				ls.ArgError(2, fmt.Sprintf("unknown field %v", k))
			}
		}
		return 0
	}))
}

func getFuncMaps(fm template.FuncMap) template.FuncMap {


@@ 175,6 239,7 @@ func setupState(L *lua.LState, conf *Config, w http.ResponseWriter, r *http.Requ
	}
	L.PreloadModule("http", setupHTTP(client, conf.Path))

	L.PreloadModule("url", setupURL())   // must be executed after setupHTTP
	L.PreloadModule("form", setupForm()) // must be executed after setupHTTP
	finalFuncs := getFuncMaps(conf.TemplateFuncMap)



@@ 253,6 318,7 @@ func SetupGlue(L *lua.LState, conf *Config) error {
	}
	L.PreloadModule("http", setupHTTP(client, conf.Path))

	L.PreloadModule("url", setupURL())   // must be executed after setupHTTP
	L.PreloadModule("form", setupForm()) // must be executed after setupHTTP

	finalFuncs := getFuncMaps(conf.TemplateFuncMap)

M http.go => http.go +36 -0
@@ 300,6 300,42 @@ func setupForm() func(*lua.LState) int {
	}
}

type lurl struct {
	u  *url.URL
	qs url.Values
}

func checkURL(L *lua.LState) *lurl {
	ud := L.CheckUserData(1)
	if v, ok := ud.Value.(*lurl); ok {
		return v
	}
	L.ArgError(1, "url expected")
	return nil
}

func setupURL() func(*lua.LState) int {
	return func(L *lua.LState) int {
		// Setup the "http" module
		mod := L.SetFuncs(L.NewTable(), map[string]lua.LGFunction{
			"parse": func(L *lua.LState) int {
				u, err := url.Parse(L.ToString(1))
				if err != nil {
					L.Push(lua.LNil)
					return 1
				}
				ud := L.NewUserData()
				ud.Value = &lurl{u, u.Query()}
				L.SetMetatable(ud, L.GetTypeMetatable("lurl"))
				L.Push(ud)
				return 1
			},
		})
		L.Push(mod)
		return 1
	}
}

func buildValues(L *lua.LState, vals url.Values) lua.LValue {
	ud := L.NewUserData()
	ud.Value = &values{vals}