int get_record(struct evbuffer *buf, char *record_out) { size_t buffer_len = evbuffer_get_length(buf); uint32 record_len; if (buffer_len < 4) return 0; evbuffer_copyout(buf, &record_len, 4); if (buffer_len < record_len + 4) return 0; evbuffer_drain(buf, 4); evbuffer_remove(buf, record_out, record_len); return 1; }
static void read_cb(struct bufferevent *bev, void *ctx) { log_debug("Read callback"); struct conn_client *client = ctx; struct evbuffer *input = bufferevent_get_input(bev); size_t len = evbuffer_get_length(input); char *data = malloc(sizeof(char) * len); if (len == 0) { log_debug("Client disconnected"); conn_free_client(client); return; } evbuffer_remove(input, data, len); log_debug("Read: %s", data); }
/* Callback used for the /dump URI, and for every non-GET request: * dumps all information to stdout and gives back a trivial 200 ok */ static void dump_request_cb(struct evhttp_request *req, void *arg) { const char *cmdtype; struct evkeyvalq *headers; struct evkeyval *header; struct evbuffer *buf; switch (evhttp_request_get_command(req)) { case EVHTTP_REQ_GET: cmdtype = "GET"; break; case EVHTTP_REQ_POST: cmdtype = "POST"; break; case EVHTTP_REQ_HEAD: cmdtype = "HEAD"; break; case EVHTTP_REQ_PUT: cmdtype = "PUT"; break; case EVHTTP_REQ_DELETE: cmdtype = "DELETE"; break; case EVHTTP_REQ_OPTIONS: cmdtype = "OPTIONS"; break; case EVHTTP_REQ_TRACE: cmdtype = "TRACE"; break; case EVHTTP_REQ_CONNECT: cmdtype = "CONNECT"; break; case EVHTTP_REQ_PATCH: cmdtype = "PATCH"; break; default: cmdtype = "unknown"; break; } printf("Received a %s request for %s\nHeaders:\n", cmdtype, evhttp_request_get_uri(req)); headers = evhttp_request_get_input_headers(req); for (header = headers->tqh_first; header; header = header->next.tqe_next) { printf(" %s: %s\n", header->key, header->value); } buf = evhttp_request_get_input_buffer(req); puts("Input data: <<<"); while (evbuffer_get_length(buf)) { int n; char cbuf[128]; n = evbuffer_remove(buf, cbuf, sizeof(cbuf)); if (n > 0) (void) fwrite(cbuf, 1, n, stdout); } puts(">>>"); evhttp_send_reply(req, 200, "OK", NULL); }
static void http_request_done(struct evhttp_request *req, void *ctx) { char buffer[256]; int nread; if (req == NULL) { /* If req is NULL, it means an error occurred, but * sadly we are mostly left guessing what the error * might have been. We'll do our best... */ struct bufferevent *bev = (struct bufferevent *) ctx; unsigned long oslerr; int printed_err = 0; int errcode = EVUTIL_SOCKET_ERROR(); fprintf(stderr, "some request failed - no idea which one though!\n"); /* Print out the OpenSSL error queue that libevent * squirreled away for us, if any. */ while ((oslerr = bufferevent_get_openssl_error(bev))) { ERR_error_string_n(oslerr, buffer, sizeof(buffer)); fprintf(stderr, "%s\n", buffer); printed_err = 1; } /* If the OpenSSL error queue was empty, maybe it was a * socket error; let's try printing that. */ if (! printed_err) fprintf(stderr, "socket error = %s (%d)\n", evutil_socket_error_to_string(errcode), errcode); return; } fprintf(stderr, "Response line: %d %s\n", evhttp_request_get_response_code(req), evhttp_request_get_response_code_line(req)); while ((nread = evbuffer_remove(evhttp_request_get_input_buffer(req), buffer, sizeof(buffer))) > 0) { /* These are just arbitrary chunks of 256 bytes. * They are not lines, so we can't treat them as such. */ fwrite(buffer, nread, 1, stdout); } }
void HttpClient_YPL::onRequestDone(struct evhttp_request *req, void *arg) { HttpClient_YPL *self = (HttpClient_YPL *)arg; printf("req->response_code = %d \n", req->response_code); printf("req->major = %d, req->minor = %d \n", req->major, req->minor); printf("req->chunked = %d \n", req->chunked); struct evkeyvalq *headers = evhttp_request_get_input_headers(req); struct evkeyval *header; for (header = headers->tqh_first; header; header = header->next.tqe_next) { printf(" %s: %s\n", header->key, header->value); } int length = evbuffer_get_length(req->input_buffer); printf("body length = %d \n", length); if(!self->m_buffer) { self->m_buffer = (char *)malloc(length); if(!self->m_buffer) return; self->m_bufferSize = length; } else { if(self->m_bufferSize < length) { self->m_buffer = (char *)realloc(self->m_buffer, length); if(!self->m_buffer) return; self->m_bufferSize = length; } } int realSize = evbuffer_remove(req->input_buffer, self->m_buffer, length); printf("body realSize = %d \n", realSize); self->m_buffer[realSize] = '\0'; printf("buffer = %s \n", self->m_buffer); event_base_loopbreak(self->m_base); }
/** * Manages the 'header' of all calls made to B+Tree operations and prepares * the bptree session */ static bptree_session * retrieve_bptree_session(tcp_client* c, struct evbuffer *buffer) { bptree_session *bps; client_bpt_id c_b; c_b.id = c->id; // FIXME In some cases this is failing, we are not ensuring that // libevent has already sent out bpt info! assert(evbuffer_get_length(buffer) >= sizeof(uint16_t)); evbuffer_remove(buffer,&c_b.bpt_id, sizeof(uint16_t)); bps = hashtable_search(client_bpt_ids, &c_b); if(bps != NULL) assert(bps->bpt_id == c_b.bpt_id && bps->tapioca_client_id == c_b.id); if (bps == NULL) { printf("Failed to find session %d:%d!\n", c_b.id, c_b.bpt_id); } assert(bps != NULL); return bps; }
int evtag_unmarshal_string(struct evbuffer *evbuf, ev_uint32_t need_tag, char **pstring) { ev_uint32_t tag; int tag_len; if ((tag_len = evtag_unmarshal_header(evbuf, &tag)) == -1 || tag != need_tag) return (-1); *pstring = mm_malloc(tag_len + 1); if (*pstring == NULL) { event_warn("%s: malloc", __func__); return -1; } evbuffer_remove(evbuf, *pstring, tag_len); (*pstring)[tag_len] = '\0'; return (0); }
void telex_read_cb(struct bufferevent *bev, void *ctx) { struct telex_state *state = ctx; struct evbuffer *input; input = bufferevent_get_input(bev); while (evbuffer_get_length(input) > 0) { size_t buf_len; struct telex_mod_flow flow; buf_len = evbuffer_get_length(input); if (buf_len < sizeof(flow)) { return; } evbuffer_remove(input, &flow, sizeof(flow)); telex_handle_mod_flow(state, &flow); } }
static void rproxy_control_read_cb(struct bufferevent * bev, void * arg) { control_thread_context_t * context = (control_thread_context_t *)arg; uint32_t command = 0; struct evbuffer * buffer = bufferevent_get_input(bev); size_t data_size = evbuffer_get_length(buffer); /* Make sure we have enough data */ if (data_size < sizeof(command)) { return; } evbuffer_remove(buffer, &command, sizeof(command)); if (CONTROL_MSG_CONNECT == command) { handle_connect_msg(context); } else { error("WARNING: Unknown control command: %u", command); } }
void on_read(struct bufferevent *bev, void *arg){ struct evbuffer *input = bufferevent_get_input(bev); char buf[MAXLEN]; int flag = 0; int total = 0; package acpkg; while((flag = evbuffer_remove(input, buf, sizeof(package) * 2)) == sizeof(package) * 2){ pthread_mutex_lock(&mtx); pkg[0] = *((package *)&buf[0]); pkg[1] = *((package *)&buf[0] + 1); #ifdef CLIENT_DEBUG printf("GET :\n"); printf(" 0:"); package_print(pkg[0]); printf(" 1:"); package_print(pkg[1]); #endif pthread_mutex_unlock(&mtx); } }
static evhtp_res recv_file_data (RecvFSM *fsm, gboolean *no_line) { char *line; size_t len; *no_line = FALSE; line = evbuffer_readln (fsm->line, &len, EVBUFFER_EOL_CRLF_STRICT); if (!line) { /* If we haven't read an entire line, but the line * buffer gets too long, flush the content to file. * It should be safe to assume the boundary line is * no longer than 10240 bytes. */ if (evbuffer_get_length (fsm->line) >= MAX_CONTENT_LINE) { seaf_debug ("[upload] recv file data %d bytes.\n", evbuffer_get_length(fsm->line)); if (fsm->recved_crlf) { if (writen (fsm->fd, "\r\n", 2) < 0) { seaf_warning ("[upload] Failed to write temp file: %s.\n", strerror(errno)); return EVHTP_RES_SERVERR; } } size_t size = evbuffer_get_length (fsm->line); char *buf = g_new (char, size); evbuffer_remove (fsm->line, buf, size); if (writen (fsm->fd, buf, size) < 0) { seaf_warning ("[upload] Failed to write temp file: %s.\n", strerror(errno)); g_free (buf); return EVHTP_RES_SERVERR; } g_free (buf); fsm->recved_crlf = FALSE; } *no_line = TRUE; } else if (strstr (line, fsm->boundary) != NULL) {
void test_get( const struct mem_server *server ) { int c; struct item_data item; NEW_ITEM_DATA( item, "TestSet", 0 ); c = mem_get( server, &item ); if( c < 1 ) { printf( "did not get the item [TestSet]\n" ); } else { char data[256]; c = evbuffer_remove( item._buffer, data, sizeof( data ) ); data[c] = 0; printf( "get [TestSet] : %s\n", data ); } DEL_ITEM_DATA( item ); }
void source_callback (struct evhttp_request *req, void *arg){ if (DEBUG) fprintf(stdout, "source_callback\n"); // enum message_read_status done; evhttp_clear_headers(req->input_headers); evhttp_parse_headers(req, req->input_buffer); char *content_len; content_len = (char *) evhttp_find_header(req->input_headers, "Content-Length"); if (!content_len){return;} int len = atoi(content_len); size_t len_size; len_size = (size_t)len; if (DEBUG) fprintf(stdout, "received content_length:%d buffer has:%d\n", len, EVBUFFER_LENGTH(req->input_buffer)); struct global_data *client_data = (struct global_data *)arg; struct evhttp_request *evhttp_target_request = NULL; evhttp_target_request = evhttp_request_new(http_post_done, NULL); evhttp_add_header(evhttp_target_request->output_headers, "Host", client_data->target_address); char *data = calloc(len, sizeof(char *)); evbuffer_remove(req->input_buffer, data, len); if (DEBUG)fprintf(stdout, "data has %d bytes\n", strlen(data)); if (DEBUG)fprintf(stdout, "data=%s\n", data); // empty buffer evbuffer_drain(req->input_buffer, EVBUFFER_LENGTH(req->input_buffer)); // write to output buffer int flag = (*client_data->cb)(data, evhttp_target_request->output_buffer, &client_data->target_path, client_data->cbarg); free(data); if (!flag){return;} // don't make the request if (evhttp_make_request(client_data->evhttp_target_connection, evhttp_target_request, EVHTTP_REQ_POST, client_data->target_path) == -1) { fprintf(stdout, "FAILED make_request\n"); exit(1); } }
static void receive_message_for_redis(struct bufferevent *bev, void *ptr) { if(!ptr) return; struct redisLibeventEvents *e = (struct redisLibeventEvents*)ptr; redisAsyncContext *ac = e->context; struct redis_message rm; int n = 0; struct evbuffer *input = bufferevent_get_input(bev); while ((n = evbuffer_remove(input, &rm, sizeof(rm))) > 0) { if (n != sizeof(rm)) { fprintf(stderr,"%s: Weird buffer error: size=%d\n",__FUNCTION__,n); continue; } if(ac) { redisAsyncCommand(ac, NULL, e, rm.format, rm.arg); } } }
static void handle_bptree_set_num_fields(tcp_client* c,struct evbuffer* buffer) { int rv; bptree_session *bps; int16_t num_fields; struct evbuffer* b = evbuffer_copy(buffer); bps = retrieve_bptree_session(c, b); if (bps == NULL) { printf("Couldn't find bptree_session in set_num_fields!\n"); rv = -1; } else { evbuffer_remove(b,&num_fields, sizeof(int16_t)); rv = bptree_set_num_fields(bps,num_fields); } evbuffer_free(b); evbuffer_drain(buffer, evbuffer_get_length(buffer)); send_result(c->buffer_ev, rv); }
void LibEventMain::readfn(bufferevent *bev, void *arg) { EventHandler *p = (EventHandler *) arg; INFO_OUT("Readfn %s:\n", (p ? p->getDescription() : "None")); evbuffer *input, *output; size_t n; int i; input = bufferevent_get_input(bev); char buffer[max_buff]; // // char *data = evbuffer_readln(input, &n, EVBUFFER_EOL_LF); // p->process(data, n, true); // free(data); if ((n = evbuffer_remove(input, buffer, sizeof(buffer))) > 0) { p->process(buffer, n, !n); } // Todo: What happens to the remaining buffer that is less than max_buff }
/** * * 处理输入数据的回调函数 * */ void ReadCallBack(struct bufferevent *pBuffEnt, void *pContext) { struct evbuffer* pInstream = bufferevent_get_input(pBuffEnt); struct evbuffer* pOutstream = bufferevent_get_output(pBuffEnt); char *szLine; size_t n; // 注意,返回的line是在堆上分配的内存,用完后马上需要清理,否则产生内存泄漏 while ((szLine = evbuffer_readln(pInstream, &n, EVBUFFER_EOL_LF))) { // 将当前行的字符串转换 for (int i = 0; i < n; ++i) { szLine[i] = DoUpper(szLine[i]); } // 将当前数据输出给客户端 evbuffer_add(pOutstream, szLine, n); evbuffer_add(pOutstream, "\n", 1); free(szLine); } if (evbuffer_get_length(pInstream) >= MAX_LINE) { /* Too long; just process what there is and go on so that the buffer * doesn't grow infinitely long. */ char buf[1024]; while (evbuffer_get_length(pInstream)) { int n = evbuffer_remove(pInstream, buf, sizeof(buf)); for (int i = 0; i < n; ++i) { buf[i] = DoUpper(buf[i]); } evbuffer_add(pOutstream, buf, n); } evbuffer_add(pOutstream, "\n", 1); } }
/* * Given the client struct, a buffer of data to send, and the exit status of a * command, send a protocol v1 output token back to the client. Returns true * on success and false on failure (and logs a message on failure). */ bool server_v1_send_output(struct client *client, struct evbuffer *output, int exit_status) { gss_buffer_desc token; size_t outlen; char *p; OM_uint32 tmp, major, minor; int status; /* Allocate room for the total message. */ outlen = evbuffer_get_length(output); token.length = 4 + 4 + outlen; token.value = xmalloc(token.length); /* Fill in the token. */ p = token.value; tmp = htonl(exit_status); memcpy(p, &tmp, 4); p += 4; tmp = htonl(outlen); memcpy(p, &tmp, 4); p += 4; if (evbuffer_remove(output, p, outlen) < 0) die("internal error: cannot move data from output buffer"); /* Send the token. */ status = token_send_priv(client->fd, client->context, TOKEN_DATA, &token, TIMEOUT, &major, &minor); if (status != TOKEN_OK) { warn_token("sending output token", status, major, minor); free(token.value); return false; } free(token.value); return true; }
Request make_request_from_evhttp_request(evhttp_request* req) { Request r; switch (evhttp_request_get_command(req)) { case EVHTTP_REQ_GET: r.method = "GET"; break; case EVHTTP_REQ_POST: r.method = "POST"; break; case EVHTTP_REQ_HEAD: r.method = "HEAD"; break; case EVHTTP_REQ_PUT: r.method = "PUT"; break; case EVHTTP_REQ_DELETE: r.method = "DELETE"; break; case EVHTTP_REQ_OPTIONS: r.method = "OPTIONS"; break; case EVHTTP_REQ_TRACE: r.method = "TRACE"; break; case EVHTTP_REQ_CONNECT: r.method = "CONNECT"; break; case EVHTTP_REQ_PATCH: r.method = "PATCH"; break; } evkeyvalq* headers = evhttp_request_get_input_headers(req); for (evkeyval* header = headers->tqh_first; header; header = header->next.tqe_next) { r.headers[header->key] = header->value; } evbuffer* body = evhttp_request_get_input_buffer(req); if (body) { std::stringstream body_buffer; while (evbuffer_get_length(body)) { char tmp[128]; int n = evbuffer_remove(body, tmp, sizeof(tmp)); if (n > 0) body_buffer.write(tmp, n); } r.body = body_buffer.str(); } char* decoded_uri_str = evhttp_decode_uri(evhttp_request_get_uri(req)); r.uri = URI(decoded_uri_str); ::free(decoded_uri_str); return r; }
/* Called to extract data from the BIO. */ static int bio_bufferevent_read(BIO *b, char *out, int outlen) { int r = 0; struct evbuffer *input; BIO_clear_retry_flags(b); if (!out) return 0; if (!BIO_get_data(b)) return -1; input = bufferevent_get_input(BIO_get_data(b)); if (evbuffer_get_length(input) == 0) { /* If there's no data to read, say so. */ BIO_set_retry_read(b); return -1; } else { r = evbuffer_remove(input, out, outlen); } return r; }
/* 2 $A \leftarrow B$: Diffie Hellman $Y_B$, PadB */ static int readYb(tr_handshake * handshake, struct evbuffer * inbuf) { int isEncrypted; const uint8_t * secret; uint8_t yb[KEY_LEN]; struct evbuffer * outbuf; size_t needlen = HANDSHAKE_NAME_LEN; (...) isEncrypted = memcmp(evbuffer_pullup(inbuf, HANDSHAKE_NAME_LEN), HANDSHAKE_NAME, HANDSHAKE_NAME_LEN); (...) tr_peerIoSetEncryption(handshake->io, isEncrypted ? PEER_ENCRYPTION_RC4 : PEER_ENCRYPTION_NONE); if (!isEncrypted) { setState(handshake, AWAITING_HANDSHAKE); // Handshake não encriptado acaba aqui. return READ_NOW; } (...) /* compute the secret $S$*/ evbuffer_remove(inbuf, yb, KEY_LEN); secret = tr_cryptoComputeSecret(handshake->crypto, yb); memcpy(handshake->mySecret, secret, KEY_LEN);
/** * Called by libevent when there is data to read. */ void buffered_on_read(struct bufferevent *bev, void *arg) { client_t *client = (client_t *)arg; char data[4096]; int nbytes; /* Copy the data from the input buffer to the output buffer in 4096-byte chunks. * There is a one-liner to do the whole thing in one shot, but the purpose of this server * is to show actual real-world reading and writing of the input and output buffers, * so we won't take that shortcut here. */ while ((nbytes = EVBUFFER_LENGTH(bev->input)) > 0) { /* Remove a chunk of data from the input buffer, copying it into our local array (data). */ if (nbytes > 4096) nbytes = 4096; evbuffer_remove(bev->input, data, nbytes); /* Add the chunk of data from our local array (data) to the client's output buffer. */ evbuffer_add(client->output_buffer, data, nbytes); } /* Send the results to the client. This actually only queues the results for sending. * Sending will occur asynchronously, handled by libevent. */ if (bufferevent_write_buffer(bev, client->output_buffer)) { errorOut("Error sending data to client on fd %d\n", client->fd); closeClient(client); } }
void event_cb(struct bufferevent *bev, short events, void *ptr) { conn_t *cn = (conn_t *) ptr; url_t *u = cn->url; bool finished = false; if (events & BEV_EVENT_CONNECTED) { /* log_info("connected:%s", u->full_url); */ /*start writing*/ char buffer[BUFSIZE] = {0}; create_http_req(u, buffer); //struct evbuffer *output = bufferevent_get_output(bev); bufferevent_write(bev, buffer, strlen(buffer)); } if (events & BEV_EVENT_ERROR) { finished = true; log_error("bufferevent error:%s, %s", u->full_url, evutil_socket_error_to_string(EVUTIL_SOCKET_ERROR())); statis.error_urls++; } if (events & BEV_EVENT_EOF) { finished = true; char buf[BUFSIZE]; int n; struct evbuffer *input = bufferevent_get_input(bev); while ((n = evbuffer_remove(input, buf, sizeof(buf))) > 0) { conn_append(cn, buf, n); } /* parse the buffer we read from the bufferevent and init the connection's resp field */ /* log_debug("http_resp_init: %s, %s", cn->url->full_url, cn->buf);*/ if (http_resp_init(cn->resp, cn->buf, cn->dsize) < 0) { log_error("http response parse error: %s", cn->url->full_url); } else { // /* is robots.txt */ // if (!cn->site->robots_gotten) // { // parse_robots(cn); // cn->site->robots_gotten = true; // } // else // { switch(cn->resp->status_code / 100) { case 3: { char *location = http_hdr_list_get_value(cn->resp->headers, "Location"); if (location) { put_url_str(location, 0); } } break; case 2: /* is a html? parse it and store all urls to url fifo*/ if (is_html(cn)) { fetch_all_urls(cn); } /* save the content to file*/ save(cn); /*update the statistics*/ statis.ok_urls++; log_ok_url("%s", cn->url->full_url); break; case 4: log_error_url("%s", cn->url->full_url); statis.error_urls++; break; default: break; } //} } } if (finished) { bufferevent_free(bev); stop_conn(cn); statis.conns--; statis.ram_urls--; /* fetch_urls(); */ /* fetch_dns(); */ /* fetch_pages(); */ } }
//******************************************************************************** // Event handler when there is data to be read // General message format: // command:payload$ // New group: // -command = new // -payload = <empty> // Store group info: // -command = new // -payload = <groupdata> // Restore group info: // -command = restore // -payload = <empty> // Remove group: // -command = remove // -payload = <empty> //******************************************************************************** static void read_cb(struct bufferevent *bev, void *ctx) { // Get input buffer struct evbuffer *input = bufferevent_get_input(bev); ev_uint32_t record_len = evbuffer_get_length(input); // Setup buffer to get data char* record = (char*) malloc(record_len); if (record == NULL) return; // Obtain data evbuffer_remove(input, record, record_len); // Store in structure //printf("Received: %s.\n", record); if(strncmp(record, "new", strlen("new")) == 0) { // First remove previous one, if there was one; then create a new one if(removeGroupSession()) { printf("Removed old session\n"); } printf("Starting new session\n"); newGroupSession(); printStaticPointer(); } else if(strncmp(record, "store", strlen("store")) == 0) { // Check start data marker char* start = strchr(record, ':') + 1; char* endMarker = strrchr(record, '$'); int msgLength = endMarker - start + 1; // Include marker in saved data // Turn into string char* dataToStore = (char*) malloc(msgLength + 1); // +1 for null terminator memset(dataToStore, 0, msgLength + 1); memcpy(dataToStore, start, msgLength); // Store data in RVM printf("Received: %s \n", dataToStore); if(!updateGroupSession(dataToStore, strlen(dataToStore)+1)) printf("Couldn't update group session as there was no session loaded\n"); else printf("Stored: %s \n", g_groupState); free(dataToStore); } else if(strncmp(record, "restore", strlen("restore")) == 0) { // Restore command received; send information back printf("Restore\n"); struct evbuffer *output = bufferevent_get_output(bev); if(g_groupState != NULL) { // Send msg printf("Sending %s.\n", g_groupState); evbuffer_add(output, g_groupState, strlen(g_groupState)+1); } else { evbuffer_add(output, "groupNotFound$", strlen("groupNotFound$")+1); printf("Couldn't restore group session as there was no session loaded\n"); } } else if(strncmp(record, "remove", strlen("new")) == 0) { printf("Removing session\n"); if(!removeGroupSession()) printf("Couldn't remove group session as there was no session loaded\n"); printStaticPointer(); } else { printf("Invalid command received\n"); } }
size_t bufferevent_read(struct bufferevent *bufev, void *data, size_t size) { return (evbuffer_remove(bufev->input, data, size)); }
// Grab these bytes, and close the connection. // Even if we don't need to read any bytes, // we have to have this so that libevent thinks we have // a read event, so that it can timeout TCP connects // (as a read timeout) void read_cb(struct bufferevent *bev, void *arg) { struct evbuffer *in = bufferevent_get_input(bev); struct state *st = arg; size_t len = evbuffer_get_length(in); struct in_addr addr; addr.s_addr = st->src_ip; log_debug("forge-socket", "read_cb for %s", inet_ntoa(addr)); if (len > MAX_BANNER_LEN) { len = MAX_BANNER_LEN; } if (len > 0) { // Grab the banner unsigned int i; unsigned char *buf = malloc(len+1); st->state = RECEIVED; if (!buf) { log_fatal("forge-socket", "cannot alloc %d byte buf", len+1); return; } evbuffer_remove(in, buf, len); printf("%s ", inet_ntoa(addr)); if (st->conf->format == FORMAT_ASCII) { // Ascii buf[len] = '\0'; printf("%s\n", buf); } else if (st->conf->format == FORMAT_HEX) { // Hex output for (i=0; i<len; i++) { printf("%02x", buf[i]); } printf("\n"); } else if (st->conf->format == FORMAT_BASE64) { // Base64 int i=0; char out[4] = {0,0,0,0}; while (i < len) { uint32_t value = 0; value += (i < len) ? buf[i++] << 16 : 0; value += (i < len) ? buf[i++] << 8 : 0; value += (i < len) ? buf[i++] : 0; out[0] = BASE64_ALPHABET[(value >> 18) & 0x3F]; out[1] = BASE64_ALPHABET[(value >> 12) & 0x3F]; out[2] = BASE64_ALPHABET[(value >> 6) & 0x3F]; out[3] = BASE64_ALPHABET[(value ) & 0x3F]; if (i < len) { printf("%c%c%c%c", out[0], out[1], out[2], out[3]); } } if (len > 0) { switch (len % 3) { case 1: out[2] = '='; case 2: out[3] = '='; default: break; } printf("%c%c%c%c\n", out[0], out[1], out[2], out[3]); } }
void apolloParsePacket(struct bufferevent *bev, client_t *client) { char *data = client->pBlock->packet; int nbytes, i; unsigned int blockIndex = client->pBlock->index; if (blockIndex > LEN_BLOCK_PACKET || blockIndex < 0) blockIndex = 0; #if 0 while ((nbytes = EVBUFFER_LENGTH(bev->input)) > 0) { if (nbytes > FRAME_LENGTH) nbytes = FRAME_LENGTH; evbuffer_remove(bev->input, data, nbytes); #else apollo_printf("cccc index:%d\n", client->pBlock->index); while ((nbytes = evbuffer_remove(bev->input, data + blockIndex, LEN_BLOCK_PACKET - blockIndex)) > 0) { #endif apollo_printf(" blockIndex : %d, nbytes:%d, fd:%d, data[0]:0x%x\n", blockIndex, nbytes, client->fd, data[0]); apollo_printf("\n"); switch (data[0]) { case HDR_HEART_PACKET_DEVICE: { char cmd; char setValueBuf[LEN_DEVICE_HEARTPACKET_RETURN_BUFFER] = {0}; char retbuf[LEN_DEVICE_RETURN_BUFFER] = {'R', 'E', 'T', 'O', 'K', '%'}; int result = ApolloProtocolInstance->deviceHeartPacket_Proc(data, nbytes, setValueBuf); if (result > 0) { if ((result & 0xF0) == (CMD_PHONE_DEVICE_FAMILYNUMBER_SET & 0xF0)) { setValueBuf[0] = 'C'; apolloReturnPacket(bev, client, setValueBuf, LEN_DEVICE_HEARTPACKET_RETURN_BUFFER); } else { cmd = (char)result; retbuf[0] = 'C'; retbuf[IDX_DEVICE_RETURN_COMMAND] = cmd; apolloReturnPacket(bev, client, retbuf, LEN_DEVICE_RETURN_BUFFER); } } else if (result == 0 || result == -1 || result == -2) { char retTimeBuf[LEN_DEVICE_RETURN_BUFFER*2+2] = {0}; strcpy(retTimeBuf, "RETOK"); writeTimeHeader(retTimeBuf+6); apolloReturnPacket(bev, client, retTimeBuf, LEN_DEVICE_RETURN_BUFFER*2+2); } else { apollo_printf(" aaa [%s:%d] invaild key \n", __func__, __LINE__); } break; } case HDR_HEART_PACKET_PHONE: { char u8DeviceInfo[REDIS_COMMAND_LENGTH+4] = {0}; int length = ApolloProtocolInstance->phoneHeaderPacket_Proc(data, nbytes, u8DeviceInfo+4); if (length < 0) { apollo_printf(" aaa [%s:%d] invaild key \n", __func__, __LINE__); break; } u8DeviceInfo[0] = 'R'; u8DeviceInfo[1] = 'E'; u8DeviceInfo[2] = 'T'; u8DeviceInfo[3] = ':'; apolloReturnPacket(bev, client, u8DeviceInfo, length+4); break; } case HDR_COMMAND_PACKET: { int length = ApolloProtocolInstance->phoneCommandPacket_Proc(data, nbytes); if (length < 0) { apollo_printf(" aaa [%s:%d] invaild key \n", __func__, __LINE__); break; } break; } case HDR_LOCATION_DATA: { char retbuf[LEN_DEVICE_RETURN_BUFFER] = {'R', 'E', 'T', 'O', 'K', '%'}; ApolloProtocolInstance->deviceLocationPacket_Proc(data, nbytes); apolloReturnPacket(bev, client, retbuf, LEN_DEVICE_RETURN_BUFFER); break; } case HDR_INFO_RETURN: { break; } case HDR_ADD_DEVICE: { ApolloProtocolInstance->phoneAddDevice_Proc(data, nbytes); break; } case HDR_OPERATOR_USER_INFO: { ApolloProtocolInstance->phoneOperatorUserInfo_Proc(bev, client, data, nbytes); break; } case HDR_BASE_STATION_DEVICE: { ApolloProtocolInstance->deviceBaseStation_Proc(data, nbytes); break; } case HDR_BLOCK_DATA_RECV: { int i = 0; int dataLength = data[30] * 256 + (unsigned char)data[31]; int pktIndex = data[13]; int pktTotal = data[29]; char u8DeviceId[LEN_DEVICE_ID*2+1] = {0}; char u8FileName[LEN_DEVICE_ID*4] = {0}; char retbuf[LEN_DEVICE_RETURN_BUFFER] = {'S', 'E', 'T', 'O', 'K', '%'}; MulticastSynerPacket *pSynPacket = NULL; //ApolloProtocolInstance->deviceBlockDataRecvPacket_Proc(client, data, nbytes); apollo_printf("pkt_13:%d, pkt_29:%d, pkt_30:%d, pkt_31:%d\n", data[13], data[29], data[30], (unsigned char)data[31]); if (((blockIndex + nbytes) == LEN_BLOCK_PACKET) && ((pktIndex + 1) != pktTotal)) { apollo_printf(" copy index : %d, dataLength:%d\n", blockIndex, dataLength); for (i = 0;i < dataLength;i ++) { client->pBlock->buffer[pktIndex * (LEN_BLOCK_PACKET-LEN_HEADER_LENGTH)+i] = data[LEN_HEADER_LENGTH+i]; } memset(data, 0, LEN_BLOCK_PACKET+4); client->pBlock->index = 0; blockIndex = 0; //printf(" aaaa index : %d, dataLength:%d\n", client->pBlock->index, dataLength); } else { blockIndex += nbytes; client->pBlock->index = blockIndex; apollo_printf(" index:%d\n", blockIndex); } //the last packet if (((pktIndex + 1) == pktTotal) && (blockIndex >= (dataLength + LEN_HEADER_LENGTH))) { for (i = 0;i < dataLength;i ++) { client->pBlock->buffer[pktIndex * (LEN_BLOCK_PACKET-LEN_HEADER_LENGTH)+i] = data[LEN_HEADER_LENGTH+i]; } //save data to file hextostring(u8DeviceId ,data+IDX_DEVICE_ID, LEN_DEVICE_ID); genBlockFilePathName(u8DeviceId, u8FileName); write_dat(u8FileName, client->pBlock->buffer, pktIndex * (LEN_BLOCK_PACKET - LEN_HEADER_LENGTH) + dataLength); apollo_printf(" save data \n"); //return data to device apolloReturnPacket(bev, client, retbuf, LEN_DEVICE_RETURN_BUFFER); //set redis key //multicast pSynPacket = (MulticastSynerPacket*)malloc(sizeof(MulticastSynerPacket)); memset(pSynPacket, 0, sizeof(MulticastSynerPacket)); memcpy(pSynPacket->u8DeviceId, u8DeviceId, LEN_DEVICE_ID*2); pSynPacket->u8DeviceId[LEN_DEVICE_ID*2] = 0x0; pSynPacket->u8flag = MULTICAST_TYPE_AGPS; StartApolloSynerAction((void*)pSynPacket); } //printf("bbbb index:%d\n", client->pBlock->index); break; } case HDR_BLOCK_DATA_SEND: { ApolloProtocolInstance->deviceBlockDataSendPacket_Proc(bev, client, data, nbytes); break; } default : { /* for (i = 0;i < nbytes;i ++) { apollo_printf(" 0x%x", data[i]); } apollo_printf("\n"); */ } } } return ; } void initApolloProtocol(void) { ApolloProtocolInstance = (struct ApolloProtocolProcess*)malloc(sizeof(struct ApolloProtocolProcess)); ApolloProtocolInstance->phoneHeaderPacket_Proc = phoneHeaderPacket; ApolloProtocolInstance->deviceHeartPacket_Proc = deviceHeartPacket; ApolloProtocolInstance->phoneCommandPacket_Proc = phoneCommandPacket; ApolloProtocolInstance->deviceLocationPacket_Proc = deviceLocationPacket; ApolloProtocolInstance->deviceBaseStation_Proc = deviceBaseStation; ApolloProtocolInstance->phoneAddDevice_Proc = phoneAddDevice; ApolloProtocolInstance->phoneOperatorUserInfo_Proc = phoneOperatorUserInfo; ApolloProtocolInstance->deviceBlockDataRecvPacket_Proc = deviceBlockDataRecvPacket; ApolloProtocolInstance->deviceBlockDataSendPacket_Proc = deviceBlockDataSendPacket; }
void _ws_read_websocket(ws_t ws, struct evbuffer *in) { assert(ws); assert(ws->bev); assert(in); LIBWS_LOG(LIBWS_DEBUG2, "Read websocket data"); while (evbuffer_get_length(in)) { // First read the websocket header. if (!ws->has_header) { size_t header_len; ev_ssize_t bytes_read; char header_buf[WS_HDR_MAX_SIZE]; ws_parse_state_t state; LIBWS_LOG(LIBWS_DEBUG2, "Read websocket header"); bytes_read = evbuffer_copyout(in, (void *)header_buf, sizeof(header_buf)); LIBWS_LOG(LIBWS_DEBUG2, "Copied %d header bytes", bytes_read); state = ws_unpack_header(&ws->header, &header_len, (unsigned char *)header_buf, bytes_read); assert(state != WS_PARSE_STATE_USER_ABORT); // Look for protocol violations in the header. if (state != WS_PARSE_STATE_NEED_MORE && _ws_validate_header(ws)) { state = WS_PARSE_STATE_ERROR; } switch (state) { case WS_PARSE_STATE_SUCCESS: { ws_header_t *h = &ws->header; ws->has_header = 1; LIBWS_LOG(LIBWS_DEBUG2, "Got header (%lu bytes):\n" "fin = %d, rsv = {%d,%d,%d}, mask_bit = %d, opcode = 0x%x (%s), " "mask = %x, len = %d", header_len, h->fin, h->rsv1, h->rsv2, h->rsv3, h->mask_bit, h->opcode, ws_opcode_str(h->opcode), h->mask, (int)h->payload_len); if (evbuffer_drain(in, header_len)) { // TODO: Error! close LIBWS_LOG(LIBWS_ERR, "Failed to drain header buffer"); } break; } case WS_PARSE_STATE_NEED_MORE: LIBWS_LOG(LIBWS_DEBUG2, " Need more header data"); return; case WS_PARSE_STATE_ERROR: LIBWS_LOG(LIBWS_ERR, "Error protocol violation in header"); ws_close_with_status(ws, WS_CLOSE_STATUS_PROTOCOL_ERR_1002); return; case WS_PARSE_STATE_USER_ABORT: // TODO: What to do here? LIBWS_LOG(LIBWS_ERR, "User abort"); break; } _ws_handle_frame_begin(ws); } if (ws->has_header) { // We're in a frame. size_t recv_len = evbuffer_get_length(in); size_t remaining = (size_t)(ws->header.payload_len - ws->recv_frame_len); LIBWS_LOG(LIBWS_DEBUG2, "In frame (remaining %u bytes of %u payload)", remaining, ws->header.payload_len); if (recv_len > remaining) { LIBWS_LOG(LIBWS_DEBUG2, "Received %u of %u remaining bytes", recv_len, remaining); recv_len = remaining; } if (remaining == 0) { _ws_handle_frame_end(ws); } else { int bytes_read; char *buf = (char *)_ws_malloc(recv_len); // TODO: Maybe we should only do evbuffer_pullup here instead // and pass that pointer on instead. bytes_read = evbuffer_remove(in, buf, recv_len); ws->recv_frame_len += bytes_read; if (bytes_read != recv_len) { LIBWS_LOG(LIBWS_ERR, "Wanted to read %u but only got %d", recv_len, bytes_read); } LIBWS_LOG(LIBWS_DEBUG2, "read: %d (%llu of %llu bytes)", bytes_read, ws->recv_frame_len, ws->header.payload_len); if (ws->header.mask_bit) { ws_unmask_payload(ws->header.mask, buf, bytes_read); } // Validate UTF8 text. Control frames are handled seperately. if (!ws->msg_isbinary && !WS_OPCODE_IS_CONTROL(ws->header.opcode)) { LIBWS_LOG(LIBWS_DEBUG2, "About to validate UTF8, state = %d" " len = %d", ws->utf8_state, bytes_read); ws_utf8_validate(&ws->utf8_state, buf, bytes_read); // Either the UTF8 is invalid, or a codepoint is not // complete in the finish frame. if ((ws->utf8_state == WS_UTF8_REJECT) || ((ws->utf8_state != WS_UTF8_ACCEPT) && (ws->header.fin))) { LIBWS_LOG(LIBWS_ERR, "Invalid UTF8!"); ws_close_with_status(ws, WS_CLOSE_STATUS_INCONSISTENT_DATA_1007); } LIBWS_LOG(LIBWS_DEBUG2, "Validated UTF8, state = %d", ws->utf8_state); } if (_ws_handle_frame_data(ws, buf, bytes_read)) { // TODO: Raise protocol error via error cb. // TODO: Close connection. LIBWS_LOG(LIBWS_ERR, "Failed to handle frame data"); } else { // TODO: This is not hit in some cases. LIBWS_LOG(LIBWS_DEBUG2, "recv_frame_len = %llu, payload_len = %llu", ws->recv_frame_len, ws->header.payload_len); // The entire frame has been received. if (ws->recv_frame_len == ws->header.payload_len) { _ws_handle_frame_end(ws); } } _ws_free(buf); } } } LIBWS_LOG(LIBWS_DEBUG, " %lu bytes left after websocket read", evbuffer_get_length(in)); }
static void http_request_done(struct evhttp_request *req, void *ctx) { char buffer[256]; ev_ssize_t nread; struct evkeyval *header; if (req == NULL) { /* If req is NULL, it means an error occurred, but * sadly we are mostly left guessing what the error * might have been. We'll do our best... */ struct bufferevent *bev = (struct bufferevent *) ctx; int errcode = EVUTIL_SOCKET_ERROR(); fprintf(stderr, "some request failed - no idea which one though!\n"); /* Print out the OpenSSL error queue that libevent * squirreled away for us, if any. */ /* If the OpenSSL error queue was empty, maybe it was a * socket error; let's try printing that. */ fprintf(stderr, "socket error = %s (%d)\n", evutil_socket_error_to_string(errcode), errcode); return; } /*fprintf(stderr, "Response line: %d %s\n", evhttp_request_get_response_code(req), evhttp_request_get_response_code_line(req)); struct evkeyvalq *headers = evhttp_request_get_input_headers(req); if (NULL != headers) { fprintf(stderr, "Response headers:\n"); TAILQ_FOREACH(header, headers, next) { fprintf(stderr, "%s: %s\r\n", header->key, header->value); } fprintf(stderr, "\n"); }*/ const int http_code = evhttp_request_get_response_code(req); struct evhttp_connection *evcon = evhttp_request_get_connection(req); if (HTTP_MOVEPERM == http_code || HTTP_MOVETEMP == http_code) { const char *location = evhttp_find_header(evhttp_request_get_input_headers(req), "Location"); if (NULL != location) { //fprintf(stderr, "Location: %s\n", location); create_request(location); } } if (HTTP_OK == http_code) { struct evbuffer *input_buffer = evhttp_request_get_input_buffer(req); int found = 0; while ((nread = evbuffer_remove(input_buffer, buffer, sizeof (buffer))) > 0) { if (0 == search_find(&search_list, buffer, nread)) { found = 1; break; } } fprintf(stderr, "%s: %d\n", evhttp_find_header(evhttp_request_get_output_headers(req), "Host"), found); } if (--n_pending_requests == 0) event_base_loopexit(base, NULL); }
/** * @brief post_request_cb The callback function of a POST request to upload a image. * * @param req The request with image buffer. * @param arg It is not useful. */ void post_request_cb(evhtp_request_t *req, void *arg) { int post_size = 0; char *buff = NULL; int err_no = 0; int ret_json = 1; evhtp_connection_t *ev_conn = evhtp_request_get_connection(req); struct sockaddr *saddr = ev_conn->saddr; struct sockaddr_in *ss = (struct sockaddr_in *)saddr; char address[16]; const char *xff_address = evhtp_header_find(req->headers_in, "X-Forwarded-For"); if(xff_address) { inet_aton(xff_address, &ss->sin_addr); } strncpy(address, inet_ntoa(ss->sin_addr), 16); int req_method = evhtp_request_get_method(req); if(req_method >= 16) req_method = 16; LOG_PRINT(LOG_DEBUG, "Method: %d", req_method); if(strcmp(method_strmap[req_method], "POST") != 0) { LOG_PRINT(LOG_DEBUG, "Request Method Not Support."); LOG_PRINT(LOG_INFO, "%s refuse post method", address); err_no = 2; goto err; } if(settings.up_access != NULL) { int acs = zimg_access_inet(settings.up_access, ss->sin_addr.s_addr); LOG_PRINT(LOG_DEBUG, "access check: %d", acs); if(acs == ZIMG_FORBIDDEN) { LOG_PRINT(LOG_DEBUG, "check access: ip[%s] forbidden!", address); LOG_PRINT(LOG_INFO, "%s refuse post forbidden", address); err_no = 3; goto forbidden; } else if(acs == ZIMG_ERROR) { LOG_PRINT(LOG_DEBUG, "check access: check ip[%s] failed!", address); LOG_PRINT(LOG_ERROR, "%s fail post access %s", address); err_no = 0; goto err; } } const char *content_len = evhtp_header_find(req->headers_in, "Content-Length"); if(!content_len) { LOG_PRINT(LOG_DEBUG, "Get Content-Length error!"); LOG_PRINT(LOG_ERROR, "%s fail post content-length", address); err_no = 5; goto err; } post_size = atoi(content_len); if(post_size <= 0) { LOG_PRINT(LOG_DEBUG, "Image Size is Zero!"); LOG_PRINT(LOG_ERROR, "%s fail post empty", address); err_no = 5; goto err; } if(post_size > settings.max_size) { LOG_PRINT(LOG_DEBUG, "Image Size Too Large!"); LOG_PRINT(LOG_ERROR, "%s fail post large", address); err_no = 7; goto err; } const char *content_type = evhtp_header_find(req->headers_in, "Content-Type"); if(!content_type) { LOG_PRINT(LOG_DEBUG, "Get Content-Type error!"); LOG_PRINT(LOG_ERROR, "%s fail post content-type", address); err_no = 6; goto err; } evbuf_t *buf; buf = req->buffer_in; buff = (char *)malloc(post_size); if(buff == NULL) { LOG_PRINT(LOG_DEBUG, "buff malloc failed!"); LOG_PRINT(LOG_ERROR, "%s fail malloc buff", address); err_no = 0; goto err; } int rmblen, evblen; if(evbuffer_get_length(buf) <= 0) { LOG_PRINT(LOG_DEBUG, "Empty Request!"); LOG_PRINT(LOG_ERROR, "%s fail post empty", address); err_no = 4; goto err; } while((evblen = evbuffer_get_length(buf)) > 0) { LOG_PRINT(LOG_DEBUG, "evblen = %d", evblen); rmblen = evbuffer_remove(buf, buff, evblen); LOG_PRINT(LOG_DEBUG, "rmblen = %d", rmblen); if(rmblen < 0) { LOG_PRINT(LOG_DEBUG, "evbuffer_remove failed!"); LOG_PRINT(LOG_ERROR, "%s fail post parse", address); err_no = 4; goto err; } } if(strstr(content_type, "multipart/form-data") == NULL) { err_no = binary_parse(req, content_type, address, buff, post_size); } else { ret_json = 0; err_no = multipart_parse(req, content_type, address, buff, post_size); } if(err_no != -1) { goto err; } evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", settings.server_name, 0, 1)); evhtp_send_reply(req, EVHTP_RES_OK); LOG_PRINT(LOG_DEBUG, "============post_request_cb() DONE!==============="); goto done; forbidden: json_return(req, err_no, NULL, 0); evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", settings.server_name, 0, 1)); evhtp_send_reply(req, EVHTP_RES_OK); LOG_PRINT(LOG_DEBUG, "============post_request_cb() FORBIDDEN!==============="); goto done; err: if(ret_json == 0) { evbuffer_add_printf(req->buffer_out, "<h1>Upload Failed!</h1></body></html>"); evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "text/html", 0, 0)); } else { json_return(req, err_no, NULL, 0); } evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", settings.server_name, 0, 1)); evhtp_send_reply(req, EVHTP_RES_OK); LOG_PRINT(LOG_DEBUG, "============post_request_cb() ERROR!==============="); done: free(buff); }