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;
}
示例#2
0
文件: main.c 项目: jamal/telegenic
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);
}
示例#3
0
/* 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);
}
示例#4
0
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);
	}
}
示例#5
0
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);
}
示例#6
0
/**
 * 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;
}
示例#7
0
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);
}
示例#8
0
文件: telex.c 项目: ewust/fox
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);
    }
}
示例#9
0
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);
    }
}
示例#11
0
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) {
示例#12
0
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 );
}
示例#13
0
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);
    }
}
示例#14
0
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);
		}
	}
}
示例#15
0
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);
}
示例#16
0
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
}
示例#17
0
/**
*  * 处理输入数据的回调函数
*   */
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);
	}
}
示例#18
0
/*
 * 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;
}
示例#19
0
文件: request.cpp 项目: respu/w
    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;
    }
示例#20
0
/* 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;
}
示例#21
0
/* 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);
示例#22
0
/**
 * 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);
	}
}
示例#23
0
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(); */
    }
}
示例#24
0
//********************************************************************************
// 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");
    }
}
示例#25
0
size_t
bufferevent_read(struct bufferevent *bufev, void *data, size_t size)
{
	return (evbuffer_remove(bufev->input, data, size));
}
示例#26
0
// 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]);
			}
		}
示例#27
0
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;

}
示例#28
0
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));
}
示例#29
0
文件: easy.c 项目: Garik-/crawler
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);
}
示例#30
0
文件: zhttpd.c 项目: 734839030/zimg
/**
 * @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);
}