GuNET_Server_Error_t GuNET_Server_Client_Send(GuNET_Server_Client_t * client, const void * buffer, int size) { check(!client || !buffer, GuNET_SERVER_ERROR_INVALID_ARGS); bufferevent_write(client->bev, buffer, size); bufferevent_flush(client->bev, EV_WRITE, BEV_FINISHED); return GuNET_SERVER_ERROR_NONE; }
void NetServer::DisconnectPlayer(DuelPlayer* dp) { auto bit = users.find(dp->bev); if(bit != users.end()) { bufferevent_flush(dp->bev, EV_WRITE, BEV_FLUSH); bufferevent_disable(dp->bev, EV_READ); bufferevent_free(dp->bev); users.erase(bit); } }
void Server::quit(const char *msg, int quitsecs) { if(state >= Connected && state != Quitting) { if(msg) DEBUGF(bufferevent_write_printf(buf, "QUIT :%s\r\n", msg)) else DEBUGF(bufferevent_write_printf(buf, "QUIT\r\n")) bufferevent_flush(buf, EV_WRITE, BEV_FLUSH); struct timeval readtv; readtv.tv_sec = quitsecs; readtv.tv_usec = 0; bufferevent_set_timeouts(buf, &readtv, NULL); // we don't want to wait for the server to close the connection more than a second state = Quitting; } }
static void drone_send_messages_cb(evutil_socket_t fd, short what, void *arg) { struct job *job = arg; struct session *session; struct evbuffer *evb; struct timeval now; float acc = 0; size_t len; u_int64_t i; if (job->client == NULL) return; for (i = 0; i != job->cur_sessions; i++) { session = job->sessions[i]; fd = bufferevent_getfd(session->bev); if (fd > 0) { acc += job->request->messages_percent; if (acc >= 1) { if (session->remaining_data && session->send_try++ > 3) { gettimeofday(&now, NULL); if (drone_report_error_ready(job, &now)) { snprintf(job->error_msg, sizeof(job->error_msg), "Unable to send more packets, " "the server resources should be " "increased(%zd message skipped)", job->skipped_error_msg); drone_report_error(job, &now); // try to purge every remaining data evb = bufferevent_get_output(session->bev); len = evbuffer_get_length(evb); evbuffer_drain(evb, len); evb = bufferevent_get_input(session->bev); len = evbuffer_get_length(evb); evbuffer_drain(evb, len); bufferevent_flush(session->bev, EV_READ | EV_WRITE, BEV_FLUSH); } } else { evb = bufferevent_get_output(session->bev); evbuffer_add(evb, job->message, job->request->block_size); session->remaining_data += job->request->block_size; session->send_try = 0; } acc = 0; } } } }
static void badchunk_transfer_cb(evhtp_request_t * req, void * arg) { /* Start the chunk */ evhtp_send_reply_chunk_start(req, EVHTP_RES_OK); /* Send a few chunks with a bogus GET in the middle */ send_chunk(req, "DATA", "%d\r\n", strlen("DATA")); send_chunk(req, "GET /index.html HTTP/1.1", "", 0); send_chunk(req, "MOREDATA", "%d\r\n", strlen("DATA")); /* Flush the connection */ bufferevent_flush(req->conn->bev, EV_WRITE, BEV_FLUSH); /* Close the chunk */ evhtp_send_reply_chunk_end(req); }
void evhtp_send_reply_chunk(evhtp_request_t * request, evbuf_t * buf) { evbuf_t * output; output = bufferevent_get_output(request->conn->bev); if (evbuffer_get_length(buf) == 0) { return; } if (request->chunked) { evbuffer_add_printf(output, "%x\r\n", (unsigned)evbuffer_get_length(buf)); } evhtp_send_reply_body(request, buf); if (request->chunked) { evbuffer_add(output, "\r\n", 2); } bufferevent_flush(request->conn->bev, EV_WRITE, BEV_FLUSH); }
void CD_DestroyClient (CDClient* self) { assert(self); CD_EventDispatch(self->server, "Client.destroy", self); if (self->buffers) { bufferevent_flush(self->buffers->raw, EV_READ | EV_WRITE, BEV_FINISHED); bufferevent_disable(self->buffers->raw, EV_READ | EV_WRITE); bufferevent_free(self->buffers->raw); CD_DestroyBuffers(self->buffers); } CD_DestroyDynamic(DYNAMIC(self)); pthread_rwlock_destroy(&self->lock.status); CD_free(self); }
//fixme: sometimes this is being called twice O.o static bool cdsurvivalproxy_ClientDisconnect (CDServer* server, CDClient* client, bool status) { assert(server); assert(client); SLOG(server, LOG_INFO, "got disconnect for %x", client); CDBuffers* proxyBuffers = (CDBuffers*)CD_DynamicGet(client, "Client.proxyBuffers"); if (proxyBuffers) { bufferevent_flush(proxyBuffers->raw, EV_READ | EV_WRITE, BEV_FINISHED); //bufferevent_setwatermark(proxyBuffers->raw, EV_WRITE, 0, 0); bufferevent_disable(proxyBuffers->raw, EV_READ | EV_WRITE); bufferevent_free(proxyBuffers->raw); CD_DestroyBuffers(proxyBuffers); } return true; }
/** * Called by libevent when there is data to read. */ void buffered_on_read(struct bufferevent *bev, void *arg) { size_t readed = 0; char data[256] = {0}; readed = bufferevent_read(bev, data, 256); printf("read data: %s\n", data); /* Write back the read buffer. It is important to note that * bufferevent_write_buffer will drain the incoming data so it * is effectively gone after we call it. */ struct evbuffer *out_buffer = evbuffer_new(); evbuffer_add(out_buffer, data, readed); char buffer[32] = "hello, world"; //bufferevent_write(bev, buffer, 32); struct client *c = (struct client *)arg; //if (c->msg_count++ == 2) bufferevent_flush(bev, EV_WRITE, BEV_FINISHED); c->need_free = 1; }
void test_bufferevent_zlib(void *arg) { struct bufferevent *bev1=NULL, *bev2=NULL; char buffer[8333]; z_stream z_input, z_output; int i, pair[2]={-1,-1}, r; (void)arg; infilter_calls = outfilter_calls = readcb_finished = writecb_finished = errorcb_invoked = 0; if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) { tt_abort_perror("socketpair"); } evutil_make_socket_nonblocking(pair[0]); evutil_make_socket_nonblocking(pair[1]); bev1 = bufferevent_socket_new(NULL, pair[0], 0); bev2 = bufferevent_socket_new(NULL, pair[1], 0); memset(&z_output, 0, sizeof(z_output)); r = deflateInit(&z_output, Z_DEFAULT_COMPRESSION); tt_int_op(r, ==, Z_OK); memset(&z_input, 0, sizeof(z_input)); r = inflateInit(&z_input); tt_int_op(r, ==, Z_OK); /* initialize filters */ bev1 = bufferevent_filter_new(bev1, NULL, zlib_output_filter, BEV_OPT_CLOSE_ON_FREE, zlib_deflate_free, &z_output); bev2 = bufferevent_filter_new(bev2, zlib_input_filter, NULL, BEV_OPT_CLOSE_ON_FREE, zlib_inflate_free, &z_input); bufferevent_setcb(bev1, readcb, writecb, errorcb, NULL); bufferevent_setcb(bev2, readcb, writecb, errorcb, NULL); bufferevent_disable(bev1, EV_READ); bufferevent_enable(bev1, EV_WRITE); bufferevent_enable(bev2, EV_READ); for (i = 0; i < (int)sizeof(buffer); i++) buffer[i] = i; /* break it up into multiple buffer chains */ bufferevent_write(bev1, buffer, 1800); bufferevent_write(bev1, buffer + 1800, sizeof(buffer) - 1800); /* we are done writing - we need to flush everything */ bufferevent_flush(bev1, EV_WRITE, BEV_FINISHED); event_dispatch(); tt_want(infilter_calls); tt_want(outfilter_calls); tt_want(readcb_finished); tt_want(writecb_finished); tt_want(!errorcb_invoked); test_ok = 1; end: if (bev1) bufferevent_free(bev1); if (bev2) bufferevent_free(bev2); if (pair[0] >= 0) evutil_closesocket(pair[0]); if (pair[1] >= 0) evutil_closesocket(pair[1]); }
/** Called on successful connections and errors */ void ssl_event_cb(struct bufferevent *bev, short e, void *data) { struct conn *c = data; uint32_t error_conditions = BEV_EVENT_EOF | BEV_EVENT_ERROR | BEV_EVENT_TIMEOUT; #if SSL_DEBUG_LEVEL > 1 errprintf(stdout, "ssl_slave: event callback triggered with flags 0x%hx\n", e); #endif if (e & BEV_EVENT_CONNECTED) { if (c->local_bev == bev) { local_connected(c); } else { ssl_connected(c); } } else if (e & BEV_EVENT_TIMEOUT) { if (c->state == C_SSL_CONNECTING) { /* Handshake timed out. */ #if SSL_DEBUG_LEVEL > 0 errprintf(stdout, "ssl_slave: SSL handshake timeout.\n"); #endif bufferevent_disable(c->remote_bev, EV_READ | EV_WRITE); bufferevent_free(c->remote_bev); c->remote_bev = NULL; c->state = C_SHUTTINGDOWN; if (c->local_bev) { bufferevent_disable(c->local_bev, EV_READ); bufferevent_flush(c->local_bev, EV_WRITE, BEV_FINISHED); } delete_conn(c); } else { /* Bug in some versions of libevent cause this to trigger when it shouldn't. Ignore. */ return; } } else if (e & error_conditions) { if (c->local_bev == bev) { /* Mush side of the connection went away. Flush SSL buffer and shut down. */ #if SSL_DEBUG_LEVEL > 0 errprintf(stdout, "ssl_slave: Lost local connection. State: %d, reason 0x%hx.\n", c->state, e); #endif bufferevent_disable(c->local_bev, EV_READ | EV_WRITE); bufferevent_free(c->local_bev); c->local_bev = NULL; c->state = C_SHUTTINGDOWN; if (c->remote_bev) { bufferevent_disable(c->remote_bev, EV_READ); bufferevent_flush(c->remote_bev, EV_WRITE, BEV_FINISHED); SSL_shutdown(bufferevent_openssl_get_ssl(c->remote_bev)); } delete_conn(c); } else { /* Remote side of the connection went away. Flush mush buffer and shut down. */ #if SSL_DEBUG_LEVEL > 0 errprintf(stdout, "ssl_slave: Lost SSL connection. State: %d, reason 0x%hx.\n", c->state, e); #endif bufferevent_disable(c->remote_bev, EV_READ | EV_WRITE); bufferevent_free(c->remote_bev); c->remote_bev = NULL; c->state = C_SHUTTINGDOWN; if (c->local_bev) { bufferevent_disable(c->local_bev, EV_READ); bufferevent_flush(c->local_bev, EV_WRITE, BEV_FINISHED); } delete_conn(c); } } }
/* Функция обратного вызова для события: данные готовы для чтения в buf_ev */ static void echo_read_cb(struct bufferevent *buf_ev, void *arg) { struct evbuffer *buf_input = bufferevent_get_input(buf_ev); struct evbuffer *buf_output = bufferevent_get_output(buf_ev); size_t length = evbuffer_get_length(buf_input); char recvBuf[10000]; evbuffer_copyout(buf_input, recvBuf, length); recvBuf[length] = '\0'; std::istringstream split(recvBuf); std::string sRequestFileName; for (std::string token; std::getline(split, token);) { if (token.find("GET ") != std::string::npos) { std::istringstream ss(token); std::getline(ss, sRequestFileName, ' '); // GET std::getline(ss, sRequestFileName, ' '); // fname } } if (sRequestFileName.empty()) { std::cout << "invalid request" << std::endl; //onDisconnect(); bufferevent_free(buf_ev); return; } std::cout << "GET " << sRequestFileName << std::endl; std::string sUsedFileName; if (sRequestFileName == "/") sUsedFileName = "/index.html"; else { std::stringstream ss(sRequestFileName); std::getline(ss, sUsedFileName, '?'); //sUsedFileName = sRequestFileName; } FILE *f = fopen((mainDir + sUsedFileName).c_str(), "r"); if (f == NULL) { // 404 std::cout << "No page " << (mainDir + sUsedFileName) << ", disconnecting." << std::endl; //std::string s404 = "HTTP/1.1 404 Not Found\r\n\r\n"; std::string s404 = "HTTP/1.0 404 Not Found\r\nContent-Length: 0\r\nContent-Type: text/html\r\n\r\n"; /* std::string s404 = "HTTP/1.1 "; s404 += sRequestFileName; const char sz404page[] = "<html><body>404 Page not found :(</html></body>"; s404 += " 404 Not Found\r\nContent-Type: text/html;charset=win-1251\r\nContent-Length: "; s404 += std::to_string(sizeof(sz404page)); s404 += "\r\nCache - Control: no - cache, no - store\r\n\r\n"; s404 += sz404page;*/ //send(m_sock, s404.c_str(), s404.length(), 0); bufferevent_write(buf_ev, s404.c_str(), s404.length()); std::cout << s404 << std::endl; bufferevent_flush(buf_ev, EV_WRITE, BEV_NORMAL); //onDisconnect(); //bufferevent_free(buf_ev); return; } long lSize = 0; if (fseek(f, 0, SEEK_END) == 0) { lSize = ftell(f); fseek(f, 0, SEEK_SET); } char *pBuf = new char[lSize + 1]; if (fread(pBuf, lSize, 1, f) != 1) { // read error delete[] pBuf; std::cout << "Read error, disconnecting." << std::endl; std::string s404 = "HTTP/1.1 "; s404 += sRequestFileName; const char sz404page[] = "<html><body>404 Page not found :(</html></body>"; s404 += " 404 Not Found\r\nContent-Type: text/html;charset=win-1251\r\nContent-Length: "; s404 += std::to_string(sizeof(sz404page)); s404 += "\r\nCache - Control: no - cache, no - store\r\n\r\n"; s404 += sz404page; //send(m_sock, s404.c_str(), s404.length(), 0); bufferevent_write(buf_ev, s404.c_str(), s404.length()); //onDisconnect(); //bufferevent_free(buf_ev); fclose(f); return; }; std::string sMsg = "HTTP/1.1 "; sMsg += sRequestFileName; sMsg += " 200 OK \r\nContent-Type: text/html;charset=win-1251\r\nContent-Length: "; //if( pBuf[1] != 'h' ) // sMsg += std::to_string(lSize + 12 + 14 - 1); //else sMsg += std::to_string(lSize - 1); sMsg += "\r\nCache - Control: no - cache, no - store\r\n\r\n"; pBuf[lSize] = '\0'; // if( pBuf[1] != 'h' ) // sMsg += "<html><body>"; sMsg += pBuf; sMsg.pop_back(); delete[] pBuf; //if( pBuf[1] != 'h' ) // sMsg += "</body></html>"; if (bufferevent_write(buf_ev, sMsg.c_str(), sMsg.length()) != 0) { std::cout << "Send fails, disconnecting." << std::endl; //onDisconnect(); //bufferevent_free(buf_ev); fclose(f); return; } std::cout << "File " << sUsedFileName << " transferred." << std::endl; fclose(f); }
void Connection::flush() { bufferevent_flush( m_handle, EV_WRITE, BEV_FLUSH ); }
int BufferEvent::Flush(short iotype) { return bufferevent_flush(bufev_, iotype, BEV_NORMAL); }
int BufferEvent::Flush() { return bufferevent_flush(bufev_, EV_WRITE, BEV_NORMAL); }
void evhtp_send_reply_end(evhtp_request_t * request) { request->finished = 1; bufferevent_flush(request->conn->bev, EV_WRITE, BEV_FLUSH); }