@@ -236,6 +236,7 @@ func HandleFile(L *lua.LState) int {
236236 case data := <- s .serveData :
237237 go func (sData * serveData , filename string ) {
238238 state := newHandlerState (data )
239+ defer state .Close ()
239240 if err := state .DoFile (filename ); err != nil {
240241 log .Printf ("[ERROR] handle file %s: %s\n " , filename , err .Error ())
241242 data .done <- true
@@ -248,7 +249,7 @@ func HandleFile(L *lua.LState) int {
248249 return 0
249250}
250251
251- // HandleString lua http_server_ud:handler_string (body)
252+ // HandleString lua http_server_ud:handle_string (body)
252253func HandleString (L * lua.LState ) int {
253254 s := checkServer (L , 1 )
254255 body := L .CheckString (2 )
@@ -257,6 +258,7 @@ func HandleString(L *lua.LState) int {
257258 case data := <- s .serveData :
258259 go func (sData * serveData , content string ) {
259260 state := newHandlerState (sData )
261+ defer state .Close ()
260262 if err := state .DoString (content ); err != nil {
261263 log .Printf ("[ERROR] handle: %s\n " , err .Error ())
262264 data .done <- true
@@ -268,6 +270,48 @@ func HandleString(L *lua.LState) int {
268270 return 0
269271}
270272
273+ // HandleFunction lua http_server_ud:handle_function(func(response, request))
274+ func HandleFunction (L * lua.LState ) int {
275+ s := checkServer (L , 1 )
276+ f := L .CheckFunction (2 )
277+ if len (f .Upvalues ) > 0 {
278+ L .ArgError (2 , "cannot pass closures" )
279+ }
280+
281+ // Stash any args to pass to the function beyond response and request
282+ var args []lua.LValue
283+ top := L .GetTop ()
284+ for i := 3 ; i <= top ; i ++ {
285+ args = append (args , L .Get (i ))
286+ }
287+
288+ for {
289+ select {
290+ case data := <- s .serveData :
291+ go func (sData * serveData ) {
292+ state := newHandlerState (sData )
293+ defer state .Close ()
294+ response := state .GetGlobal ("response" )
295+ request := state .GetGlobal ("request" )
296+ f := state .NewFunctionFromProto (f .Proto )
297+ state .Push (f )
298+ state .Push (response )
299+ state .Push (request )
300+ // Push any extra args
301+ for _ , arg := range args {
302+ state .Push (arg )
303+ }
304+ if err := state .PCall (2 + len (args ), 0 , nil ); err != nil {
305+ log .Printf ("[ERROR] handle: %s\n " , err .Error ())
306+ data .done <- true
307+ log .Printf ("[ERROR] closed connection\n " )
308+ }
309+ state .Pop (state .GetTop ())
310+ }(data )
311+ }
312+ }
313+ }
314+
271315// ServeHTTP interface realisation
272316func (s * luaServer ) ServeHTTP (w http.ResponseWriter , req * http.Request ) {
273317 doneChan := make (chan bool )
0 commit comments