From ac3fc8174144540b4afb78a753f14e5618dea02c Mon Sep 17 00:00:00 2001 From: Robin Malley Date: Sun, 20 Feb 2022 00:08:07 +0000 Subject: [PATCH] Fix the coroutine response function --- src/libkore.c | 102 +++++++++++++++++++++++++------------------------- src/libkore.h | 2 + 2 files changed, 52 insertions(+), 52 deletions(-) diff --git a/src/libkore.c b/src/libkore.c index 0965d3e..5331020 100644 --- a/src/libkore.c +++ b/src/libkore.c @@ -45,127 +45,116 @@ lhttp_response(lua_State *L){ return 0; } +char response[] = "0\r\n\r\n"; /*Helpers for response coroutines*/ int coroutine_iter_sent(struct netbuf *buf){ - printf("Iter sent called\n"); struct co_obj *obj = (struct co_obj*)buf->extra; + int ret; lua_State *L = obj->L; - printf("\tbuf:%p\n",(void*)buf); - printf("\tobj:%p\n",(void*)obj); - printf("\tL:%p\n",(void*)L); - printf("Top is: %d\n",lua_gettop(L)); - printf("Getting status...\n"); lua_getglobal(L,"coroutine"); - printf("Found coroutine...\n"); lua_getfield(L,-1,"status"); - printf("Found status...\n"); lua_rawgeti(L,LUA_REGISTRYINDEX,obj->ref); - printf("About to get status\n"); lua_call(L,1,1); - printf("Status got\n"); const char *status = luaL_checklstring(L,-1,NULL); - printf("status in sent: %s\n",status); if(strcmp(status,"dead") == 0){ - printf("Cleanup\n"); - return KORE_RESULT_OK; + ret = KORE_RESULT_OK; }else{ - printf("About to call iter_next from iter_sent\n"); - return coroutine_iter_next(obj); + ret = coroutine_iter_next(obj); } + + if(ret == KORE_RESULT_RETRY){ + ret = KORE_RESULT_OK; + }else{ + if(obj->removed == 0){ + http_start_recv(obj->c); + } + obj->c->hdlr_extra = NULL; + obj->c->disconnect = NULL; + obj->c->flags &= ~CONN_IS_BUSY; + net_send_queue(obj->c,response,strlen(response)); + net_send_flush(obj->c); + free(obj); + } + return (ret); } -char response[] = "0\r\n\r\n"; int coroutine_iter_next(struct co_obj *obj){ - printf("Coroutine iter next called\n"); lua_State *L = obj->L; lua_getglobal(L,"coroutine"); lua_getfield(L,-1,"status"); lua_rawgeti(L,LUA_REGISTRYINDEX,obj->ref); lua_call(L,1,1); const char *status = luaL_checklstring(L,-1,NULL); - printf("status in next: %s\n",status); lua_pop(L,lua_gettop(L)); - printf("Calling resume\n"); lua_getglobal(L,"coroutine"); - printf("Getting resume()\n"); lua_getfield(L,-1,"resume"); - printf("Getting function\n"); lua_rawgeti(L,LUA_REGISTRYINDEX,obj->ref); - printf("Checking type\n"); luaL_checktype(L,-1,LUA_TTHREAD); - printf("About to call resume()\n"); int err = lua_pcall(L,1,2,0); if(err != 0){ - printf("Call error: %d\n",err); return (KORE_RESULT_ERROR); } - printf("Done calling resume()\n"); if(!lua_toboolean(L,-2)){ //Runtime error - printf("Runtime error\n"); lua_pushstring(L,":\n");//"error",":" - printf("top1:%d\n",lua_gettop(L)); lua_getglobal(L,"debug");//"error",":",{debug} - printf("top2:%d\n",lua_gettop(L)); lua_getfield(L,-1,"traceback");//"error",":",{debug},debug.traceback() - printf("top3:%d\n",lua_gettop(L)); lua_call(L,0,1);//"error",":",{debug},"traceback" - printf("top4:%d\n",lua_gettop(L)); lua_remove(L,-2);//"error",":","traceback" - printf("top5:%d\n",lua_gettop(L)); lua_concat(L,3); - printf("top6:%d\n",lua_gettop(L)); size_t size; const char *s = luaL_checklstring(L,-1,&size); - printf("Error: %s\n",s); + kore_log(LOG_ERR,"Error: %s\n",s); lua_pop(L,lua_gettop(L)); return (KORE_RESULT_ERROR); } //No runtime error if(lua_type(L,-1) == LUA_TSTRING){ - printf("Data yielded\n"); size_t size; const char *data = luaL_checklstring(L,-1,&size); struct netbuf *nb; - printf("Yielding data stream size %zu\n",size); - struct kore_buf *kb = kore_buf_alloc(0); + struct kore_buf *kb = kore_buf_alloc(4096); kore_buf_appendf(kb,"%x\r\n",size); kore_buf_append(kb,data,size); - size_t ssize; - char *sstr = kore_buf_stringify(kb,&ssize); - net_send_stream(obj->c, sstr, ssize, coroutine_iter_sent, &nb); + kore_buf_appendf(kb,"\r\n"); + //size_t ssize; + //char *sstr = kore_buf_stringify(kb,&ssize); + net_send_stream(obj->c, kb->data, kb->offset, coroutine_iter_sent, &nb); nb->extra = obj; lua_pop(L,lua_gettop(L)); kore_buf_free(kb); return (KORE_RESULT_RETRY); //return err == 0 ? (KORE_RESULT_OK) : (KORE_RESULT_RETRY); }else if(lua_type(L,-1) == LUA_TNIL){ - printf("Done with function\n"); struct netbuf *nb; - printf("About to send final bit\n"); - net_send_stream(obj->c, response, strlen(response) + 1, coroutine_iter_sent, &nb); + struct kore_buf *kb = kore_buf_alloc(4096); + kore_buf_appendf(kb,"0\r\n\r\n"); + net_send_queue(obj->c, kb->data, kb->offset); + net_send_stream(obj->c, response, strlen(response) + 0, coroutine_iter_sent, &nb); nb->extra = obj; - printf("Done sending final bit\n"); + lua_pop(L,lua_gettop(L)); - printf("Poped everything\n"); + kore_buf_free(kb); return (KORE_RESULT_OK); }else{ - printf("Coroutine used for response returned something that was not a string:%s\n",lua_typename(L,lua_type(L,-1))); + kore_log(LOG_CRIT,"Coroutine used for response returned something that was not a string:%s\n",lua_typename(L,lua_type(L,-1))); return (KORE_RESULT_ERROR); } } static void coroutine_disconnect(struct connection *c){ - printf("Disconnect routine called\n"); + kore_log(LOG_ERR,"Disconnect routine called\n"); struct co_obj *obj = (struct co_obj*)c->hdlr_extra; lua_State *L = obj->L; int ref = obj->ref; + int Lref = obj->Lref; + obj->removed = 1; luaL_unref(L,LUA_REGISTRYINDEX,ref); - free(obj); - printf("Done with disconnect\n"); + luaL_unref(L,LUA_REGISTRYINDEX,Lref); + c->hdlr_extra = NULL; } /* The coroutine passed to this function should yield() the data to send to the @@ -176,20 +165,29 @@ http_response_co(request::userdata, co::coroutine) */ int lhttp_response_co(lua_State *L){ + struct connection *c; printf("Start response coroutine\n"); int coroutine_ref = luaL_ref(L,LUA_REGISTRYINDEX); struct http_request *req = luaL_checkrequest(L,-1); + c = req->owner; + if(c->state == CONN_STATE_DISCONNECTING){ + return 0; + } lua_pop(L,1); - req->flags |= HTTP_REQUEST_NO_CONTENT_LENGTH; struct co_obj *obj = (struct co_obj*)malloc(sizeof(struct co_obj)); + obj->removed = 0; obj->L = lua_newthread(L); + obj->Lref = luaL_ref(L,LUA_REGISTRYINDEX); obj->ref = coroutine_ref; - obj->c = req->owner; - obj->c->flags |= CONN_IS_BUSY; + obj->c = c; obj->c->disconnect = coroutine_disconnect; + obj->c->hdlr_extra = obj; - printf("About to call iter next\n"); + obj->c->flags |= CONN_IS_BUSY; + req->flags |= HTTP_REQUEST_NO_CONTENT_LENGTH; + http_response_header(req,"transfer-encoding","chunked"); http_response(req,200,NULL,0); + printf("About to call iter next\n"); coroutine_iter_next(obj); printf("Done calling iter next\n"); return 0; diff --git a/src/libkore.h b/src/libkore.h index 55279f3..40a8026 100644 --- a/src/libkore.h +++ b/src/libkore.h @@ -2,6 +2,8 @@ struct co_obj { lua_State *L; int ref; + int Lref; + int removed; struct connection *c; }; int lhttp_response(lua_State *L);