/* ==================== __lua_print ==================== */ I32 __lua_print(lua_State* ls) { LUA_STACK; I32 n = lua_gettop(ls); I32 i; LUA_WATCH(ls); lua_getglobal(ls, "tostring"); for (i = 1; i <= n; i++) { const CHAR *s; lua_pushvalue(ls, -1); lua_pushvalue(ls, i); LUA_WATCH(ls); lua_call(ls, 1, 1); LUA_WATCH(ls); s = lua_tostring(ls, -1); LUA_WATCH(ls); if (s == NULL) return luaL_error(ls, LUA_QL("tostring") " must return a string to " LUA_QL("print")); LUA_WATCH(ls); if (i > 1) GLog(LT_SCRIPT, "\t"); GLog(LT_SCRIPT, s); lua_pop(ls, 1); } GLog(LT_SCRIPT, "\n"); return 0; }
I32 __app_compress(lua_State* ls) { const CHAR* src_string; uLong src_len; CHAR* dst_string = zlib_buff; uLong dst_len = MAX_TEXT*sizeof(CHAR); I32 error; LUA_STACK; LUA_WATCH(ls); if(lua_gettop(ls) != 1 || lua_type(ls, 1) != LUA_TSTRING) { GLog(LT_ERROR, "__app_compress : invalid parameters!"); return 0; } src_string = lua_tolstring(ls, 1, &src_len); error = compress(dst_string, &dst_len, src_string, src_len); if(error != Z_OK) { GLog(LT_ERROR, "__app_compress : compress is failed and error code is %d", error); return 0; } lua_pushlstring(ls, dst_string, dst_len); LUA_WATCH(ls); return 1; }
/* ==================== __tcp_connect ==================== */ I32 __tcp_connect(lua_State* ls) { U32 fd = INVALID_SOCKET; I32 opt = 0; I32 ret = -1; const CHAR* ip; struct sockaddr_in sock_addr; LUA_STACK; LUA_WATCH(ls); // check the port if(lua_gettop(ls) != 1 || lua_type(ls, 1) != LUA_TSTRING) { GLog(LT_ERROR, "__tcp_connect : Invalid ip!"); return 0; } ip = lua_tostring(ls, 1); // create the host socket. fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(fd == INVALID_SOCKET) { GLog(LT_ERROR, "__tcp_connect: There was an error creating the host socket: %s\n", get_socket_error_string()); return 0; } // make it non-blocking opt = 1; ret = ioctlsocket(fd, FIONBIO, (U32*)&opt); if(ret < 0) { GLog(LT_ERROR, "__tcp_connect: There was an error making a socket non-blocking : %s\n", get_socket_error_string()); return -1; } // make socket address string_to_sockaddr(ip, &sock_addr); // connect the socket. ret = connect(fd, (struct sockaddr *)&sock_addr, sizeof(struct sockaddr_in)); if(ret < 0) { if(WSAGetLastError() != WSAEWOULDBLOCK) { GLog(LT_ERROR, "__tcp_connect: There was an error connecting a socket : %s\n", get_socket_error_string()); return -1; } } // return the socket lua_pushinteger(ls, fd); LUA_WATCH(ls); return 1; }
/* ==================== __tcp_accept ==================== */ I32 __tcp_accept(lua_State* ls) { U32 listen_sock = INVALID_SOCKET; U32 fd = INVALID_SOCKET; I32 opt = 0; I32 ret = -1; struct sockaddr_in sock_addr; I32 addr_len = sizeof(sock_addr); const CHAR* ip; LUA_STACK; LUA_WATCH(ls); // check the socket if(lua_gettop(ls) != 1 || lua_type(ls, 1) != LUA_TNUMBER) { GLog(LT_ERROR, "__tcp_accept : invalid socket!"); return 0; } listen_sock = (U32)lua_tointeger(ls, 1); CHECK(listen_sock != INVALID_SOCKET); // accept a new connection memset(&sock_addr, 0, sizeof(sock_addr)); fd = accept(listen_sock, (struct sockaddr*)&sock_addr, &addr_len); if(fd == INVALID_SOCKET) { if(WSAGetLastError() != WSAEWOULDBLOCK) { GLog(LT_ERROR, "__tcp_accept: There was an error accept a socket : %s\n", get_socket_error_string()); return 0; } return 0; } // make it non-blocking opt = 1; ret = ioctlsocket(fd, FIONBIO, (U32*)&opt); if(ret < 0) { GLog(LT_ERROR, "__tcp_accept: There was an error making a socket non-blocking : %s\n", get_socket_error_string()); return 0; } // return the socket and the ipaddr lua_pushinteger(ls, fd); LUA_WATCH(ls); ip = sockaddr_to_string(&sock_addr); lua_pushstring(ls, ip); LUA_WATCH(ls); return 2; }
I32 __app_rc4(lua_State* ls) { RC4_KEY key; const CHAR* key_string; U32 key_len; const CHAR* data_string; U32 data_len; CHAR* out_string; LUA_STACK; LUA_WATCH(ls); if(lua_gettop(ls) != 2 || lua_type(ls, 1) != LUA_TSTRING || lua_type(ls, 2) != LUA_TSTRING) { GLog(LT_ERROR, "__app_rc4 : invalid parameters!"); return 0; } key_string = lua_tolstring(ls, 1, &key_len); data_string = lua_tolstring(ls, 2, &data_len); out_string = MALLOC(data_len*sizeof(CHAR)); memset(out_string, 0, data_len*sizeof(CHAR)); RC4_set_key(&key, key_len, key_string); RC4(&key, data_len, data_string, out_string); lua_pushlstring(ls, out_string, data_len); LUA_WATCH(ls); FREE(out_string); return 1; }
I32 __timer_create(lua_State* ls) { F64 interval = 0; I32 max_count = 0; I32 cb_ref = LUA_REFNIL; timer_t *timer = NULL; LUA_STACK; LUA_WATCH(ls); if(lua_gettop(ls) != 3 || lua_type(ls, 1) != LUA_TNUMBER || lua_type(ls, 2) != LUA_TNUMBER || lua_type(ls, 3) != LUA_TFUNCTION) { GLog(LT_ERROR, "__timer_create : invalid parameters!"); return 0; } interval = (F64)lua_tonumber(ls, 1); max_count = (I32)lua_tointeger(ls, 2); cb_ref = lua_ref(ls, TRUE); LUA_WATCH(ls); timer = MALLOC(sizeof(timer_t)); memset(timer, 0, sizeof(timer_t)); timer->id = s_timer_id++; timer->cb_ref = cb_ref; timer->interval = interval; timer->cur_time = GSeconds(); timer->max_count = max_count; timer->cur_count = 0; if(s_timer_list) list_add(s_timer_list, timer); lua_pushinteger(ls, timer->id); LUA_WATCH(ls); return 1; }
/* ==================== string_to_sockaddr ==================== */ VOID string_to_sockaddr(const CHAR* ip, struct sockaddr_in* sadr) { CHAR buffer[MAX_NAME]; CHAR* port; struct hostent* host; strncpy(buffer, ip, sizeof(buffer)); port = strstr(buffer, ":" ); if (port) { *port = 0; port++; } memset(sadr, 0, sizeof( *sadr)); sadr->sin_family = AF_INET; sadr->sin_port = htons((U16)atoi(port)); if(buffer[0] >= '0' && buffer[0] <= '9') { *(I32*)&sadr->sin_addr = inet_addr(buffer); } else { host = gethostbyname(buffer); if(host == NULL) { GLog(LT_ERROR, "StringToSockaddr: the ip(%s) is error.\n", ip); return; } *(I32*)&sadr->sin_addr = *(I32*)host->h_addr_list[0]; } }
I32 __timer_destroy(lua_State* ls) { I32 id = -1; list_node*node = NULL; timer_t body; LUA_STACK; LUA_WATCH(ls); if(lua_gettop(ls) != 1 || lua_type(ls, 1) != LUA_TNUMBER) { GLog(LT_ERROR, "__timer_destroy : invalid parameters!"); return 0; } id = (I32)lua_tointeger(ls, 1); memset(&body, 0, sizeof(body)); body.id = id; node = list_find(s_timer_list, &body, __timer_compare); if(node != NULL) { timer_t* timer = list_del(s_timer_list, node); if(timer != NULL) { lua_unref(ls, timer->cb_ref); LUA_WATCH(ls); FREE(timer); } } return 0; }
I32 __app_log(lua_State* ls) { U32 type; const CHAR* msg; LUA_STACK; LUA_WATCH(ls); // check the seconds if(lua_gettop(ls) != 2 || lua_type(ls, 1) != LUA_TNUMBER || lua_type(ls, 2) != LUA_TSTRING) { GLog(LT_ERROR, "__app_log : invalid parameters!"); return 0; } type = (U32)lua_tointeger(ls, 1); msg = lua_tostring(ls, 2); GLog(type, msg); return 0; }
GHtttpService::~GHtttpService() { for(int i=0; i<this->handle_list.size(); i++) { curl_easy_cleanup(this->handle_list[i]); } this->handle_list.clear(); curl_global_cleanup(); GLog("~GHtttpService!!!"); }
/* ==================== __tcp_send ==================== */ I32 __tcp_send(lua_State* ls) { U32 sock = INVALID_SOCKET; I32 ret = -1; I32 total = 0; const CHAR* buf; I32 len; LUA_STACK; LUA_WATCH(ls); // check the socket if(lua_gettop(ls) != 2 || lua_type(ls, 1) != LUA_TNUMBER || lua_type(ls, 2) != LUA_TSTRING) { GLog(LT_ERROR, "__tcp_send : invalid socket!"); return 0; } sock = (U32)lua_tointeger(ls, 1); CHECK(sock != INVALID_SOCKET); buf = luaL_checklstring(ls, 2, &len); do { ret = send(sock, (const CHAR*)&buf[total], (len-total), 0); if(ret == SOCKET_ERROR) { if(WSAGetLastError() != WSAEWOULDBLOCK) { total = -1; break; } } else if(ret == 0) { total = -1; break; } else { total += ret; if(total >= len) { break; } } } while(ret != SOCKET_ERROR); // return the result lua_pushinteger(ls, total); LUA_WATCH(ls); return 1; }
/* ==================== __lua_error ==================== */ I32 __lua_error(lua_State* ls) { LUA_STACK; LUA_WATCH(ls); luaL_where(ls, 1); LUA_WATCH(ls); if(lua_isstring(ls, -2)) { lua_pushvalue(ls, -2); LUA_WATCH(ls); lua_concat(ls, 2); LUA_WATCH(ls); } GLog(LT_SCRIPT, lua_tostring(ls, -1)); return lua_error(ls); }
/* ==================== __tcp_close ==================== */ I32 __tcp_close(lua_State* ls) { U32 fd = INVALID_SOCKET; LUA_STACK; LUA_WATCH(ls); // check the socket if(lua_gettop(ls) != 1 || lua_type(ls, 1) != LUA_TNUMBER) { GLog(LT_ERROR, "__tcp_close : invalid socket!"); return 0; } fd = (U32)lua_tointeger(ls, 1); CHECK(fd != INVALID_SOCKET); // close the socket closesocket(fd); return 0; }
/* ==================== lua_tcp_event ==================== */ BOOL lua_tcp_event(lua_State* ls, const CHAR* func_name, U32 sock) { I32 argc = 0; I32 ret = 0; LUA_STACK; LUA_WATCH(ls); // check the script call function lua_pushstring(ls, func_name); LUA_WATCH(ls); lua_gettable(ls, LUA_GLOBALSINDEX); LUA_WATCH(ls); if(!lua_isfunction(ls, -1)) { lua_pushstring(ls, VA("lua_tcp_event : can`t find the %s function.\n", func_name)); __lua_error(ls); return FALSE; } // push the socket lua_pushinteger(ls, sock); LUA_WATCH(ls); argc += 1; // call the function if(lua_pcall(ls, argc, 1, 0) != 0) { LUA_WATCH(ls); GLog(LT_ERROR, VA("lua_tcp_event : %s \n stack traceback: %s\n", func_name, lua_tostring(ls, -1))); return FALSE; } LUA_WATCH(ls); // get the return value if(lua_isboolean(ls, -1)) { ret = lua_toboolean(ls, -1); } lua_pop(ls, 1); return ret != 0 ? TRUE : FALSE; }
I32 __timer_poll(lua_State* ls) { list_node *node = NULL; LUA_STACK; LUA_WATCH(ls); if(s_timer_list == NULL) return 0; node = s_timer_list->head; while(node) { list_node *cur_node = node; node = node->next; if(cur_node && cur_node->body) { timer_t* timer = (timer_t*)cur_node->body; F64 cur_time = GSeconds(); if(timer->cur_time + timer->interval < cur_time) { timer->cur_time = cur_time; timer->cur_count++; lua_getref(ls, timer->cb_ref); LUA_WATCH(ls); if(lua_pcall(ls, 0, 0, 0) != 0) { GLog(LT_ERROR, VA("__timer_poll error \n stack traceback: %s\n", lua_tostring(ls, -1))); } } if(timer->max_count != 0 && timer->cur_count >= timer->max_count) { timer = list_del(s_timer_list, cur_node); lua_unref(ls, timer->cb_ref); LUA_WATCH(ls); FREE(timer); } } } return 0; }
void GHtttpService::request(GHttpTask* task) { CURL* handle = this->getHandle(task); mutex.lock(); this->handle_list.push_back(handle); mutex.unlock(); auto success = curl_easy_perform(handle); mutex.lock(); long retcode = 0; curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE , &retcode); if(success == CURLE_OK && retcode == 200) { task->setStatus(true); GLog("http request:%s ok",task->getUrl().c_str()); } else { GLogE("http request:%s failure",task->getUrl().c_str()); } if(task->getType() == GHTTPTYPE::DOWNLOAD) { task->closeFile(); if(task->getAsync())//只有异步时才release task->release(); } this->removeHandle(handle); mutex.unlock(); if(task->callback) { task->callback(task->getUrl(),task->getStatus()); } }
/* ==================== __tcp_open ==================== */ I32 __tcp_open(lua_State* ls) { U16 port = 0; U32 fd = INVALID_SOCKET; I32 opt = 0; I32 ret = -1; struct sockaddr_in sock_addr; LUA_STACK; LUA_WATCH(ls); // check the port if(lua_gettop(ls) != 1 || lua_type(ls, 1) != LUA_TNUMBER) { GLog(LT_ERROR, "__tcp_open : Invalid port!"); return 0; } port = (U16)lua_tointeger(ls, 1); // create the host socket. fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(fd == INVALID_SOCKET) { GLog(LT_ERROR, "__tcp_open: There was an error creating the host socket: %s\n", get_socket_error_string()); return 0; } // make it non-blocking opt = 1; ret = ioctlsocket(fd, FIONBIO, (U32*)&opt); if(ret < 0) { GLog(LT_ERROR, "__tcp_open: There was an error making a socket non-blocking : %s\n", get_socket_error_string()); return 0; } // bind the socket. memset(&sock_addr, 0, sizeof(sock_addr)); sock_addr.sin_family = AF_INET; sock_addr.sin_port = htons(port); sock_addr.sin_addr.s_addr = htonl(INADDR_ANY); ret = bind(fd, (struct sockaddr*)&sock_addr, sizeof(struct sockaddr_in)); if(ret < 0) { GLog(LT_ERROR, "__tcp_open: There was an error binding a socket : %s\n", get_socket_error_string()); return 0; } // start listening on the socket. ret = listen(fd, 5); if(ret < 0) { GLog(LT_ERROR, "__tcp_open: There was an error listening on a socket : %s\n", get_socket_error_string()); return 0; } // return the socket lua_pushinteger(ls, fd); LUA_WATCH(ls); return 1; }
/* ==================== __tcp_select ==================== */ I32 __tcp_select(lua_State* ls) { U32 sock = INVALID_SOCKET; fd_set read_set; fd_set write_set; fd_set except_set; I32 i = 0; U32 max_fd = 0; struct timeval tv; I32 rv; LUA_STACK; LUA_WATCH(ls); // check the param if(lua_gettop(ls) != 1 || lua_type(ls, 1) != LUA_TTABLE) { GLog(LT_ERROR, "__tcp_select : the param is invalid!"); lua_pushboolean(ls, FALSE); return 1; } FD_ZERO(&read_set); FD_ZERO(&write_set); FD_ZERO(&except_set); // set the fds lua_pushnil(ls); LUA_WATCH(ls); while(lua_next(ls, -2)) { LUA_WATCH(ls); sock = (U32)lua_tointeger(ls, -2); if(sock != INVALID_SOCKET) { max_fd = (sock >= max_fd) ? (sock + 1) : max_fd; FD_SET(sock, &read_set); FD_SET(sock, &write_set); FD_SET(sock, &except_set); } lua_pop(ls, 1); LUA_WATCH(ls); } // set the timeout tv.tv_sec = SLEEPSEC; tv.tv_usec = 0; // select all of the sockets rv = select(max_fd, &read_set, &write_set, &except_set, &tv); if(rv < 0) { // some error occured. // GLog(LT_ERROR, "__lua_select: select() returned %d", rv); lua_pushboolean(ls, FALSE); return 1; } else if(rv == 0) { // no events lua_pushboolean(ls, TRUE); return 1; } // loop each socket and handle events on each of them lua_pushnil(ls); LUA_WATCH(ls); while(lua_next(ls, -2)) { LUA_WATCH(ls); sock = (U32)lua_tointeger(ls, -2); if(sock != INVALID_SOCKET) { if(FD_ISSET(sock, &except_set)) { lua_tcp_event(ls, "tcp_event_except", sock); } else { if(FD_ISSET(sock, &read_set)) { lua_tcp_event(ls, "tcp_event_read", sock); } if(FD_ISSET(sock, &write_set)) { lua_tcp_event(ls, "tcp_event_write", sock); } } } lua_pop(ls, 1); LUA_WATCH(ls); } lua_pushboolean(ls, TRUE); return 1; }
/* ==================== __tcp_recv ==================== */ I32 __tcp_recv(lua_State* ls) { U32 sock = INVALID_SOCKET; I32 ret; I32 total = 0; CHAR buf[BUFFER_SIZE]; LUA_STACK; LUA_WATCH(ls); memset(buf, 0, sizeof(buf)); // check the socket if(lua_gettop(ls) != 1 || lua_type(ls, 1) != LUA_TNUMBER) { GLog(LT_ERROR, "__tcp_recv : Invalid socket!"); return 0; } sock = (U32)lua_tointeger(ls, 1); CHECK(sock != INVALID_SOCKET); do { // read from the network. ret = recv(sock, (char*)&buf[total], (BUFFER_SIZE-total), 0); if(ret == SOCKET_ERROR) { if(WSAGetLastError() != WSAEWOULDBLOCK) { total = -1; break; } } else if(ret == 0) { // connection closed. total = -1; break; } else { // update the buffer len. total += ret; if(total >= BUFFER_SIZE) { break; } } } while(ret != SOCKET_ERROR); // return the result lua_pushinteger(ls, total); LUA_WATCH(ls); if (total > 0) { lua_pushstring(ls, buf); LUA_WATCH(ls); } else { lua_pushnil(ls); LUA_WATCH(ls); } return 2; }