summaryrefslogtreecommitdiff
path: root/main.go
diff options
context:
space:
mode:
authorunwox <me@unwox.com>2024-06-06 16:08:13 +0600
committerunwox <me@unwox.com>2024-06-06 16:08:26 +0600
commit97a480249e7c8f605efd7a4252449791eabc90a8 (patch)
treecdf6cdad3d05cb22681af039cf6a3a6faf10adcb /main.go
parent6ef4939963e85fa044753598cd8456d48a155d4a (diff)
refactor main.go into several files
Diffstat (limited to 'main.go')
-rw-r--r--main.go259
1 files changed, 0 insertions, 259 deletions
diff --git a/main.go b/main.go
index 12c0248..ccacca3 100644
--- a/main.go
+++ b/main.go
@@ -1,269 +1,10 @@
package main
import (
- "errors"
"fmt"
- "io"
"log"
"net/http"
)
-/*
-#cgo LDFLAGS: -llua
-#include <stdlib.h>
-#include <lua.h>
-#include <lualib.h>
-#include <lauxlib.h>
-*/
-import "C"
-
-import "unsafe"
-
-type LuaRef C.longlong
-type Lua struct {
- l *C.lua_State
-}
-
-func (l *Lua) Start () {
- l.l = C.luaL_newstate()
- C.luaL_openlibs(l.l)
-}
-
-func (l *Lua) Close () {
- C.lua_close(l.l)
- C.free(unsafe.Pointer(l.l))
-}
-
-func (l *Lua) Require (file string) (LuaRef, error) {
- if !l.LoadFile(file) {
- return 0, errors.New("could not open the file")
- }
- if !l.PCall(0, C.LUA_MULTRET) {
- return 0, errors.New("could not execute the file")
- }
- if !l.IsTable(-1) {
- return 0, errors.New("module did not return a table")
- }
- return l.PopToRef(), nil
-}
-
-
-func (l *Lua) PCall (nargs int, nresults int) bool {
- res := C.lua_pcallk(l.l, C.int(nargs), C.int(nresults), 0, 0, nil)
- return res == C.LUA_OK
-}
-
-func (l *Lua) LoadFile (file string) bool {
- cfile := C.CString(file)
- defer C.free(unsafe.Pointer(cfile))
- res := C.luaL_loadfilex(l.l, cfile, nil)
- return res == C.LUA_OK
-}
-
-func (l *Lua) StackLen () int {
- return int(C.lua_gettop(l.l))
-}
-
-func (l *Lua) ToString (index int) string {
- return C.GoString(C.lua_tolstring(l.l, C.int(index), nil))
-}
-
-func (l *Lua) ToInt (index int) int {
- return int(C.lua_tonumberx(l.l, C.int(index), nil))
-}
-
-func (l *Lua) PopToRef () LuaRef {
- return LuaRef(C.luaL_ref(l.l, C.LUA_REGISTRYINDEX))
-}
-
-func (l *Lua) Pop (n int) {
- C.lua_settop(l.l, C.int(-n - 1))
-}
-
-func (l *Lua) PushNil () {
- C.lua_pushnil(l.l)
-}
-
-func (l *Lua) PushString (str string) {
- cstr := C.CString(str)
- defer C.free(unsafe.Pointer(cstr))
- C.lua_pushstring(l.l, cstr)
-}
-
-func (l *Lua) PushTable (table map[string]string) {
- C.lua_createtable(l.l, 0, C.int(len(table)))
- for k, v := range table {
- l.PushString(v)
- C.lua_setfield(l.l, -2, C.CString(k))
- }
-}
-
-func (l *Lua) PushFromRef (ref LuaRef) {
- C.lua_rawgeti(l.l, C.LUA_REGISTRYINDEX, C.longlong(ref));
-}
-
-func (l *Lua) IsString (index int) bool {
- return C.lua_isstring(l.l, C.int(index)) == 1
-}
-
-func (l *Lua) IsNumber (index int) bool {
- return C.lua_isnumber(l.l, C.int(index)) == 1
-}
-
-func (l *Lua) IsFunction (index int) bool {
- return C.lua_type(l.l, C.int(index)) == C.LUA_TFUNCTION
-}
-
-func (l *Lua) IsTable (index int) bool {
- return C.lua_type(l.l, C.int(index)) == C.LUA_TTABLE
-}
-
-func (l *Lua) Next () bool {
- return C.lua_next(l.l, -2) != 0
-}
-
-func (l *Lua) PushTableItem (key string) {
- ckey := C.CString(key)
- defer C.free(unsafe.Pointer(ckey))
- C.lua_pushstring(l.l, ckey);
- C.lua_gettable(l.l, -2);
-}
-
-type WorkerRequest struct {
- Request *http.Request
- Route string
- result chan *WorkerResponse
-}
-
-type WorkerResponse struct {
- Code int
- Headers map[string]string
- Body string
-}
-
-type Worker struct {
- read chan *WorkerRequest
- lua *Lua
- api LuaRef
- routes map[string]LuaRef
- started bool
-}
-
-func NewWorker(read chan *WorkerRequest) *Worker {
- return &Worker {
- read: read,
- routes: make(map[string]LuaRef),
- lua: &Lua{},
- }
-}
-
-func (w *Worker) Start (filename string) error {
- if w.started {
- return errors.New("already started")
- }
-
- w.lua.Start()
- api, err := w.lua.Require(filename)
- if err != nil {
- return err
- }
- w.api = api
- w.initRoutes()
-
- return nil
-}
-
-func (w *Worker) Listen () {
- for {
- r := <- w.read
- handlerRef := w.routes[r.Route]
- w.lua.PushFromRef(handlerRef)
- w.lua.PushString(r.Request.Method)
- w.lua.PushString(r.Request.URL.Path)
-
- fh := make(map[string]string)
- for k := range r.Request.Header {
- fh[k] = r.Request.Header.Get(k)
- }
- w.lua.PushTable(fh)
-
- body, err := io.ReadAll(r.Request.Body)
- if err != nil {
- w.lua.Pop(4);
- // TODO: 500
- return
- }
- w.lua.PushString(string(body))
-
- w.lua.PCall(4, 3)
- code := w.lua.ToInt(-3)
- rbody := w.lua.ToString(-1)
-
- // parse headers
- headers := make(map[string]string)
- w.lua.Pop(1)
- w.lua.PushNil()
- for w.lua.Next() {
- if !w.lua.IsString(-2) || !w.lua.IsString(-2) {
- w.lua.Pop(1)
- continue
- }
- v := w.lua.ToString(-1)
- w.lua.Pop(1)
- // we must not pop the item key from the stack because
- // otherwise C.lua_next won't work properly
- k := w.lua.ToString(-1)
- headers[k] = v
- }
- w.lua.Pop(2)
-
- r.result <- &WorkerResponse {
- Code: int(code),
- Headers: headers,
- Body: rbody,
- }
- }
-}
-
-func (w *Worker) Request (route string, r *http.Request,) chan *WorkerResponse {
- res := make(chan *WorkerResponse)
- w.read <- &WorkerRequest{
- Request: r,
- Route: route,
- result: res,
- }
- return res
-}
-
-func (w *Worker) ListRoutes() []string {
- res := []string{}
- for route, _ := range w.routes {
- res = append(res, route)
- }
- return res
-}
-
-func (w *Worker) Stop () {
- w.lua.Close()
-}
-
-func (w *Worker) initRoutes() {
- w.lua.PushFromRef(w.api)
- w.lua.PushTableItem("routes")
- // FIXME: istable?
- w.lua.PushNil()
- for w.lua.Next() {
- if !w.lua.IsString(-2) || !w.lua.IsFunction(-1) {
- w.lua.Pop(1)
- continue
- }
- handlerRef := w.lua.PopToRef()
- // we must not pop the item key from the stack because
- // otherwise C.lua_next won't work properly
- route := w.lua.ToString(-1)
- w.routes[route] = handlerRef
- }
- // FIXME: pop?
-}
func main() {
rch := make(chan *WorkerRequest, 4096)