Fix the coroutine response function
This commit is contained in:
parent
9667aa1c3e
commit
ac3fc81741
102
src/libkore.c
102
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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue