Fix the coroutine response function

This commit is contained in:
Robin Malley 2022-02-20 00:08:07 +00:00
parent 9667aa1c3e
commit ac3fc81741
2 changed files with 52 additions and 52 deletions

View File

@ -45,127 +45,116 @@ lhttp_response(lua_State *L){
return 0; return 0;
} }
char response[] = "0\r\n\r\n";
/*Helpers for response coroutines*/ /*Helpers for response coroutines*/
int int
coroutine_iter_sent(struct netbuf *buf){ coroutine_iter_sent(struct netbuf *buf){
printf("Iter sent called\n");
struct co_obj *obj = (struct co_obj*)buf->extra; struct co_obj *obj = (struct co_obj*)buf->extra;
int ret;
lua_State *L = obj->L; 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"); lua_getglobal(L,"coroutine");
printf("Found coroutine...\n");
lua_getfield(L,-1,"status"); lua_getfield(L,-1,"status");
printf("Found status...\n");
lua_rawgeti(L,LUA_REGISTRYINDEX,obj->ref); lua_rawgeti(L,LUA_REGISTRYINDEX,obj->ref);
printf("About to get status\n");
lua_call(L,1,1); lua_call(L,1,1);
printf("Status got\n");
const char *status = luaL_checklstring(L,-1,NULL); const char *status = luaL_checklstring(L,-1,NULL);
printf("status in sent: %s\n",status);
if(strcmp(status,"dead") == 0){ if(strcmp(status,"dead") == 0){
printf("Cleanup\n"); ret = KORE_RESULT_OK;
return KORE_RESULT_OK;
}else{ }else{
printf("About to call iter_next from iter_sent\n"); ret = coroutine_iter_next(obj);
return 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){ int coroutine_iter_next(struct co_obj *obj){
printf("Coroutine iter next called\n");
lua_State *L = obj->L; lua_State *L = obj->L;
lua_getglobal(L,"coroutine"); lua_getglobal(L,"coroutine");
lua_getfield(L,-1,"status"); lua_getfield(L,-1,"status");
lua_rawgeti(L,LUA_REGISTRYINDEX,obj->ref); lua_rawgeti(L,LUA_REGISTRYINDEX,obj->ref);
lua_call(L,1,1); lua_call(L,1,1);
const char *status = luaL_checklstring(L,-1,NULL); const char *status = luaL_checklstring(L,-1,NULL);
printf("status in next: %s\n",status);
lua_pop(L,lua_gettop(L)); lua_pop(L,lua_gettop(L));
printf("Calling resume\n");
lua_getglobal(L,"coroutine"); lua_getglobal(L,"coroutine");
printf("Getting resume()\n");
lua_getfield(L,-1,"resume"); lua_getfield(L,-1,"resume");
printf("Getting function\n");
lua_rawgeti(L,LUA_REGISTRYINDEX,obj->ref); lua_rawgeti(L,LUA_REGISTRYINDEX,obj->ref);
printf("Checking type\n");
luaL_checktype(L,-1,LUA_TTHREAD); luaL_checktype(L,-1,LUA_TTHREAD);
printf("About to call resume()\n");
int err = lua_pcall(L,1,2,0); int err = lua_pcall(L,1,2,0);
if(err != 0){ if(err != 0){
printf("Call error: %d\n",err);
return (KORE_RESULT_ERROR); return (KORE_RESULT_ERROR);
} }
printf("Done calling resume()\n");
if(!lua_toboolean(L,-2)){ //Runtime error if(!lua_toboolean(L,-2)){ //Runtime error
printf("Runtime error\n");
lua_pushstring(L,":\n");//"error",":" lua_pushstring(L,":\n");//"error",":"
printf("top1:%d\n",lua_gettop(L));
lua_getglobal(L,"debug");//"error",":",{debug} lua_getglobal(L,"debug");//"error",":",{debug}
printf("top2:%d\n",lua_gettop(L));
lua_getfield(L,-1,"traceback");//"error",":",{debug},debug.traceback() lua_getfield(L,-1,"traceback");//"error",":",{debug},debug.traceback()
printf("top3:%d\n",lua_gettop(L));
lua_call(L,0,1);//"error",":",{debug},"traceback" lua_call(L,0,1);//"error",":",{debug},"traceback"
printf("top4:%d\n",lua_gettop(L));
lua_remove(L,-2);//"error",":","traceback" lua_remove(L,-2);//"error",":","traceback"
printf("top5:%d\n",lua_gettop(L));
lua_concat(L,3); lua_concat(L,3);
printf("top6:%d\n",lua_gettop(L));
size_t size; size_t size;
const char *s = luaL_checklstring(L,-1,&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)); lua_pop(L,lua_gettop(L));
return (KORE_RESULT_ERROR); return (KORE_RESULT_ERROR);
} }
//No runtime error //No runtime error
if(lua_type(L,-1) == LUA_TSTRING){ if(lua_type(L,-1) == LUA_TSTRING){
printf("Data yielded\n");
size_t size; size_t size;
const char *data = luaL_checklstring(L,-1,&size); const char *data = luaL_checklstring(L,-1,&size);
struct netbuf *nb; struct netbuf *nb;
printf("Yielding data stream size %zu\n",size); struct kore_buf *kb = kore_buf_alloc(4096);
struct kore_buf *kb = kore_buf_alloc(0);
kore_buf_appendf(kb,"%x\r\n",size); kore_buf_appendf(kb,"%x\r\n",size);
kore_buf_append(kb,data,size); kore_buf_append(kb,data,size);
size_t ssize; kore_buf_appendf(kb,"\r\n");
char *sstr = kore_buf_stringify(kb,&ssize); //size_t ssize;
net_send_stream(obj->c, sstr, ssize, coroutine_iter_sent, &nb); //char *sstr = kore_buf_stringify(kb,&ssize);
net_send_stream(obj->c, kb->data, kb->offset, coroutine_iter_sent, &nb);
nb->extra = obj; nb->extra = obj;
lua_pop(L,lua_gettop(L)); lua_pop(L,lua_gettop(L));
kore_buf_free(kb); kore_buf_free(kb);
return (KORE_RESULT_RETRY); return (KORE_RESULT_RETRY);
//return err == 0 ? (KORE_RESULT_OK) : (KORE_RESULT_RETRY); //return err == 0 ? (KORE_RESULT_OK) : (KORE_RESULT_RETRY);
}else if(lua_type(L,-1) == LUA_TNIL){ }else if(lua_type(L,-1) == LUA_TNIL){
printf("Done with function\n");
struct netbuf *nb; struct netbuf *nb;
printf("About to send final bit\n"); struct kore_buf *kb = kore_buf_alloc(4096);
net_send_stream(obj->c, response, strlen(response) + 1, coroutine_iter_sent, &nb); 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; nb->extra = obj;
printf("Done sending final bit\n");
lua_pop(L,lua_gettop(L)); lua_pop(L,lua_gettop(L));
printf("Poped everything\n"); kore_buf_free(kb);
return (KORE_RESULT_OK); return (KORE_RESULT_OK);
}else{ }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); return (KORE_RESULT_ERROR);
} }
} }
static void static void
coroutine_disconnect(struct connection *c){ 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; struct co_obj *obj = (struct co_obj*)c->hdlr_extra;
lua_State *L = obj->L; lua_State *L = obj->L;
int ref = obj->ref; int ref = obj->ref;
int Lref = obj->Lref;
obj->removed = 1;
luaL_unref(L,LUA_REGISTRYINDEX,ref); luaL_unref(L,LUA_REGISTRYINDEX,ref);
free(obj); luaL_unref(L,LUA_REGISTRYINDEX,Lref);
printf("Done with disconnect\n"); c->hdlr_extra = NULL;
} }
/* /*
The coroutine passed to this function should yield() the data to send to the 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 int
lhttp_response_co(lua_State *L){ lhttp_response_co(lua_State *L){
struct connection *c;
printf("Start response coroutine\n"); printf("Start response coroutine\n");
int coroutine_ref = luaL_ref(L,LUA_REGISTRYINDEX); int coroutine_ref = luaL_ref(L,LUA_REGISTRYINDEX);
struct http_request *req = luaL_checkrequest(L,-1); struct http_request *req = luaL_checkrequest(L,-1);
c = req->owner;
if(c->state == CONN_STATE_DISCONNECTING){
return 0;
}
lua_pop(L,1); lua_pop(L,1);
req->flags |= HTTP_REQUEST_NO_CONTENT_LENGTH;
struct co_obj *obj = (struct co_obj*)malloc(sizeof(struct co_obj)); struct co_obj *obj = (struct co_obj*)malloc(sizeof(struct co_obj));
obj->removed = 0;
obj->L = lua_newthread(L); obj->L = lua_newthread(L);
obj->Lref = luaL_ref(L,LUA_REGISTRYINDEX);
obj->ref = coroutine_ref; obj->ref = coroutine_ref;
obj->c = req->owner; obj->c = c;
obj->c->flags |= CONN_IS_BUSY;
obj->c->disconnect = coroutine_disconnect; obj->c->disconnect = coroutine_disconnect;
obj->c->hdlr_extra = obj; 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); http_response(req,200,NULL,0);
printf("About to call iter next\n");
coroutine_iter_next(obj); coroutine_iter_next(obj);
printf("Done calling iter next\n"); printf("Done calling iter next\n");
return 0; return 0;

View File

@ -2,6 +2,8 @@
struct co_obj { struct co_obj {
lua_State *L; lua_State *L;
int ref; int ref;
int Lref;
int removed;
struct connection *c; struct connection *c;
}; };
int lhttp_response(lua_State *L); int lhttp_response(lua_State *L);