static int
ts_lua_http_intercept_run_coroutine(ts_lua_http_intercept_ctx * ictx)
{
  int ret;
  const char *res;
  size_t res_len;
  lua_State *L;

  L = ictx->lua;

  ret = lua_resume(L, 0);

  switch (ret) {

  case 0:                      // finished
    res = lua_tolstring(L, -1, &res_len);
    ts_lua_http_intercept_setup_write(ictx);
    TSIOBufferWrite(ictx->output.buffer, res, res_len);
    TSVIONBytesSet(ictx->output.vio, res_len);
    break;

  case 1:                      // yield
    break;

  default:                     // error
    fprintf(stderr, "lua_resume failed: %s\n", lua_tostring(L, -1));
    return -1;
  }

  return 0;
}
static void
ts_lua_http_intercept_process(ts_lua_http_ctx * http_ctx, TSVConn conn)
{
  TSCont contp;
  lua_State *l;
  TSMutex mtxp;
  ts_lua_http_intercept_ctx *ictx;

  mtxp = http_ctx->mctx->mutexp;
  TSMutexLock(mtxp);

  ictx = ts_lua_create_http_intercept_ctx(http_ctx);

  contp = TSContCreate(ts_lua_http_intercept_handler, TSMutexCreate());
  TSContDataSet(contp, ictx);

  ictx->contp = contp;
  ictx->net_vc = conn;

  l = ictx->lua;

  // set up read.
  ts_lua_http_intercept_setup_read(ictx);

  // set up write.
  ts_lua_http_intercept_setup_write(ictx);

  // invoke function here
  if (http_ctx->intercept_type == TS_LUA_TYPE_HTTP_INTERCEPT) {
    lua_getglobal(l, TS_LUA_FUNCTION_HTTP_INTERCEPT);
  } else {
    lua_getglobal(l, TS_LUA_FUNCTION_HTTP_SERVER_INTERCEPT);
  }

  ts_lua_http_intercept_run_coroutine(ictx, 0);

  TSMutexUnlock(mtxp);

}