コード例 #1
0
ファイル: event_tagging.c プロジェクト: 4hopp/libevent
static int
decode_tag_internal(ev_uint32_t *ptag, struct evbuffer *evbuf, int dodrain)
{
	ev_uint32_t number = 0;
	size_t len = evbuffer_get_length(evbuf);
	ev_uint8_t *data;
	size_t count = 0;
	int  shift = 0, done = 0;

	/*
	 * the encoding of a number is at most one byte more than its
	 * storage size.  however, it may also be much smaller.
	 */
	data = evbuffer_pullup(
		evbuf, len < sizeof(number) + 1 ? len : sizeof(number) + 1);
	if (!data)
		return (-1);

	while (count++ < len) {
		ev_uint8_t lower = *data++;
		if (shift >= 28) {
			/* Make sure it fits into 32 bits */
			if (shift > 28)
				return (-1);
			if ((lower & 0x7f) > 15)
				return (-1);
		}
		number |= (lower & (unsigned)0x7f) << shift;
		shift += 7;

		if (!(lower & 0x80)) {
			done = 1;
			break;
		}
	}

	if (!done)
		return (-1);

	if (dodrain)
		evbuffer_drain(evbuf, count);

	if (ptag != NULL)
		*ptag = number;

	return count > INT_MAX ? INT_MAX : (int)(count);
}
コード例 #2
0
ファイル: article.c プロジェクト: ptt/pttbbs
static int
evbuffer_slice(struct evbuffer *buf, int offset, int size)
{
    int len = evbuffer_get_length(buf);
    if (offset + size > len)
	return -1;

    struct evbuffer *back = evbuffer_new();
    evbuffer_add_buffer(back, buf);

    if (evbuffer_add_reference(buf, evbuffer_pullup(back, len) + offset,
			       size, cleanup_evbuffer, back) == 0)
	return 0;

    evbuffer_free(back);
    return -1;
}
コード例 #3
0
ファイル: web.c プロジェクト: GunioRobot/transmission
static void
task_finish_func( void * vtask )
{
    struct tr_web_task * task = vtask;
    dbgmsg( "finished web task %p; got %ld", task, task->code );

    if( task->done_func != NULL )
        task->done_func( task->session,
                         task->did_connect,
                         task->did_timeout,
                         task->code,
                         evbuffer_pullup( task->response, -1 ),
                         evbuffer_get_length( task->response ),
                         task->done_func_user_data );

    task_free( task );
}
コード例 #4
0
ファイル: dir_tree.c プロジェクト: SaqlainAbbas/s3ffs
static void dir_tree_file_read_on_last_chunk_cb (S3HttpClient *http, struct evbuffer *input_buf, gpointer ctx)
{
    gchar *buf = NULL;
    size_t buf_len;
    DirTreeFileOpData *op_data = (DirTreeFileOpData *) ctx;
    DirTreeFileRange *range;

    buf_len = evbuffer_get_length (input_buf);
    buf = (gchar *) evbuffer_pullup (input_buf, buf_len);
    
    /*
    range = g_queue_pop_head (op_data->q_ranges_requested);
    if (range) {
        op_data->c_size = range->size;
        op_data->c_off = range->off;
        op_data->c_req = range->c_req;
    }
    */

    op_data->total_read += buf_len;
    LOG_debug (DIR_TREE_LOG, "[%p %p] lTOTAL read: %zu (req: %zu), orig size: %zu, TOTAL: %"OFF_FMT", Qsize: %zu", 
        op_data->c_req, http,
        buf_len, op_data->c_size, op_data->en->size, op_data->total_read, g_queue_get_length (op_data->q_ranges_requested));
    
    if (op_data->file_read_cb)
        op_data->file_read_cb (op_data->c_req, TRUE, buf, buf_len);

    evbuffer_drain (input_buf, buf_len);
    
    // if there are more pending chunk requests 
    if (g_queue_get_length (op_data->q_ranges_requested) > 0) {
        range = g_queue_pop_head (op_data->q_ranges_requested);
        LOG_debug (DIR_TREE_LOG, "[%p] more data: %zd", range->c_req, range->size);
        op_data->c_size = range->size;
        op_data->c_off = range->off;
        op_data->c_req = range->c_req;
        g_free (range);

        op_data->op_in_progress = TRUE;
        // perform the next chunk request
        dir_tree_file_read_prepare_request (op_data, http, op_data->c_off, op_data->c_size);
    } else {
        LOG_debug (DIR_TREE_LOG, "Done downloading !!");
        op_data->op_in_progress = FALSE;
    }
}
コード例 #5
0
ファイル: libevent-server.c プロジェクト: bizzbyster/nghttp2
/* Read the data in the bufferevent and feed them into nghttp2 library
   function. Invocation of nghttp2_session_mem_recv() may make
   additional pending frames, so call session_send() at the end of the
   function. */
static int session_recv(http2_session_data *session_data)
{
  int rv;
  struct evbuffer *input = bufferevent_get_input(session_data->bev);
  size_t datalen = evbuffer_get_length(input);
  unsigned char *data = evbuffer_pullup(input, -1);
  rv = nghttp2_session_mem_recv(session_data->session, data, datalen);
  if(rv < 0) {
    warnx("Fatal error: %s", nghttp2_strerror(rv));
    return -1;
  }
  evbuffer_drain(input, rv);
  if(session_send(session_data) != 0) {
    return -1;
  }
  return 0;
}
コード例 #6
0
static void
extract_parts_from_multipart (const struct evkeyvalq  * headers,
                              struct evbuffer         * body,
                              tr_ptrArray             * setme_parts)
{
  const char * content_type = evhttp_find_header (headers, "Content-Type");
  const char * in = (const char*) evbuffer_pullup (body, -1);
  size_t inlen = evbuffer_get_length (body);

  const char * boundary_key = "boundary=";
  const char * boundary_key_begin = content_type ? strstr (content_type, boundary_key) : NULL;
  const char * boundary_val = boundary_key_begin ? boundary_key_begin + strlen (boundary_key) : "arglebargle";
  char * boundary = tr_strdup_printf ("--%s", boundary_val);
  const size_t boundary_len = strlen (boundary);

  const char * delim = tr_memmem (in, inlen, boundary, boundary_len);
  while (delim)
    {
      size_t part_len;
      const char * part = delim + boundary_len;

      inlen -= (part - in);
      in = part;

      delim = tr_memmem (in, inlen, boundary, boundary_len);
      part_len = delim ? (size_t)(delim - part) : inlen;

      if (part_len)
        {
          const char * rnrn = tr_memmem (part, part_len, "\r\n\r\n", 4);
          if (rnrn)
            {
              struct tr_mimepart * p = tr_new (struct tr_mimepart, 1);
              p->headers_len = (size_t) (rnrn - part);
              p->headers = tr_strndup (part, p->headers_len);
              p->body_len = (size_t) ((part + part_len) - (rnrn + 4));
              p->body = tr_strndup (rnrn+4, p->body_len);
              tr_ptrArrayAppend (setme_parts, p);
            }
        }
    }

  tr_free (boundary);
}
コード例 #7
0
ファイル: pipe.c プロジェクト: gvsurenderreddy/tunsocks
static void pipe_bev_readable(struct bufferevent *bev, void *ctx)
{
	struct pipe_data *data = ctx;
	int avail;
	struct evbuffer *buf;
	struct evbuffer_iovec vec_out;
	err_t ret;
	int wait_for_more = 0;
	u8_t apiflags;

	avail = tcp_sndbuf(data->pcb);
	if (!avail) {
		bufferevent_disable(bev, EV_READ);
		return;
	}

	buf = bufferevent_get_input(data->bev);
	if (avail < evbuffer_get_length(buf))
		wait_for_more = 1;
	else if (avail > evbuffer_get_length(buf))
		avail = evbuffer_get_length(buf);

	if (!avail)
		return;

	evbuffer_pullup(buf, avail);
	evbuffer_peek(buf, avail, NULL, &vec_out, 1);

	apiflags = TCP_WRITE_FLAG_COPY;
	if (wait_for_more)
		apiflags |= TCP_WRITE_FLAG_MORE;
	ret = tcp_write(data->pcb, vec_out.iov_base, avail, apiflags);
	if (ret < 0) {
		bufferevent_disable(bev, EV_READ);
		if (ret != ERR_MEM) {
			pipe_tcp_free(data);
			pipe_bev_flush(data);
		}
	} else {
		evbuffer_drain(buf, avail);
		if (wait_for_more)
			bufferevent_disable(bev, EV_READ);
	}
}
コード例 #8
0
ファイル: httpserver.cpp プロジェクト: Crinklebine/bitcoin
std::string HTTPRequest::ReadBody()
{
    struct evbuffer* buf = evhttp_request_get_input_buffer(req);
    if (!buf)
        return "";
    size_t size = evbuffer_get_length(buf);
    /** Trivial implementation: if this is ever a performance bottleneck,
     * internal copying can be avoided in multi-segment buffers by using
     * evbuffer_peek and an awkward loop. Though in that case, it'd be even
     * better to not copy into an intermediate string but use a stream
     * abstraction to consume the evbuffer on the fly in the parsing algorithm.
     */
    const char* data = (const char*)evbuffer_pullup(buf, size);
    if (!data) // returns NULL in case of empty buffer
        return "";
    std::string rv(data, size);
    evbuffer_drain(buf, size);
    return rv;
}
コード例 #9
0
ファイル: regress_bufferevent.c プロジェクト: kjg/libevent
static enum bufferevent_filter_result
bufferevent_input_filter(struct evbuffer *src, struct evbuffer *dst,
    ev_ssize_t lim, enum bufferevent_flush_mode state, void *ctx)
{
	const unsigned char *buffer;
	int i;

	buffer = evbuffer_pullup(src, evbuffer_get_length(src));
	for (i = 0; i < evbuffer_get_length(src); i += 2) {
		assert(buffer[i] == 'x');
		evbuffer_add(dst, buffer + i + 1, 1);

		if (i + 2 > evbuffer_get_length(src))
			break;
	}

	evbuffer_drain(src, i);
	return (BEV_OK);
}
コード例 #10
0
static void
socks_relay_cb(struct bufferevent *bev, void *ptr)
{
	obfsproxyssh_client_session_t *session = ptr;
	obfsproxyssh_t *state = session->client->state;
	struct evbuffer *buf;
	unsigned char *p;
	size_t len;
	ssize_t rval;

	assert(session->socks_ev == bev);

	/*
	 * Note: This is not very efficient, but since libssh2 doesn't have
	 * scatter/gather I/O and libssh2 is most efficient when sending 1 SSH
	 * packet worth of data (32 KiB) at a time, I can't think of a better
	 * way to do this.
	 */

	buf = bufferevent_get_input(bev);
	len = evbuffer_get_length(buf);
	len = (len > OBFSPROXYSSH_CLIENT_WRITE_SZ) ?
		OBFSPROXYSSH_CLIENT_WRITE_SZ : len;
	p = evbuffer_pullup(buf, len);
	if (NULL == p) {
		log_f(state, "RELAY: Error: %s Failed to pullup (OOM?)",
				bdata(session->socks_addr));
		ssh_relay_event_cb(session->ssh_ev, BEV_EVENT_ERROR, session);
		return;
	}

	rval = libssh2_channel_write(session->ssh_channel, (char *) p, len);
	if (LIBSSH2_ERROR_EAGAIN == rval || 0 == rval)
		return;
	else if (rval < 0) {
		log_f(state, "RELAY: Error: %s Channel write failed (%d)",
				bdata(session->ssh_addr), rval);
		ssh_relay_event_cb(session->ssh_ev, BEV_EVENT_ERROR, session);
		return;
	} else
		evbuffer_drain(buf, rval);
}
コード例 #11
0
ファイル: libevent-server.c プロジェクト: LPardue/nghttp2
/* Read the data in the bufferevent and feed them into nghttp2 library
   function. Invocation of nghttp2_session_mem_recv() may make
   additional pending frames, so call session_send() at the end of the
   function. */
static int session_recv(http2_session_data *session_data) {
  ssize_t readlen;
  struct evbuffer *input = bufferevent_get_input(session_data->bev);
  size_t datalen = evbuffer_get_length(input);
  unsigned char *data = evbuffer_pullup(input, -1);

  readlen = nghttp2_session_mem_recv(session_data->session, data, datalen);
  if (readlen < 0) {
    warnx("Fatal error: %s", nghttp2_strerror((int)readlen));
    return -1;
  }
  if (evbuffer_drain(input, (size_t)readlen) != 0) {
    warnx("Fatal error: evbuffer_drain failed");
    return -1;
  }
  if (session_send(session_data) != 0) {
    return -1;
  }
  return 0;
}
コード例 #12
0
ファイル: miniupnpc-libevent.c プロジェクト: khanmgn/miniupnp
static void upnpc_soap_response(struct evhttp_request * req, void * pvoid)
{
	size_t len;
	unsigned char * data;
	struct evbuffer * input_buffer;
	upnpc_device_t * d = (upnpc_device_t *)pvoid;
	int code;

	if(req == NULL) {
		debug_printf("%s(%p, %p) NULL argument !\n", __func__, req, pvoid);
		return;
	}
	code = evhttp_request_get_response_code(req);
	input_buffer = evhttp_request_get_input_buffer(req);
	len = evbuffer_get_length(input_buffer);
	data = evbuffer_pullup(input_buffer, len);
	debug_printf("%s %d (%d bytes)\n", __func__, code, (int)len);
	debug_printf("%.*s\n", (int)len, (char *)data);
	if(data == NULL)
		return;

	ClearNameValueList(&d->soap_response_data);
	ParseNameValue((char *)data, (int)len, 
	               &d->soap_response_data);
	d->state &= ~UPNPC_DEVICE_SOAP_REQ;
	if(d->state & UPNPC_DEVICE_READY) {
		d->parent->soap_cb(code, d->parent, d, d->parent->cb_data);
	} else if(d->state & UPNPC_DEVICE_GETSTATUS) {
		const char * connection_status;
		d->state &= ~UPNPC_DEVICE_GETSTATUS;
		connection_status = GetValueFromNameValueList(&d->soap_response_data, "NewConnectionStatus");
		d->state |= UPNPC_DEVICE_READY;
		if((code == 200) && connection_status && (0 == strcmp("Connected", connection_status))) {
			d->parent->ready_cb(code, d->parent, d, d->parent->cb_data);
			d->state |= UPNPC_DEVICE_CONNECTED;
			event_del(d->parent->ev_ssdp_recv);
		} else {
			d->parent->ready_cb(UPNPC_ERR_NOT_CONNECTED, d->parent, d, d->parent->cb_data);
		}
	}
}
コード例 #13
0
/* Post Request Function */
void http_requset_post_cb(struct evhttp_request *req, void *arg)
{
    struct http_request_post *http_req_post = (struct http_request_post *)arg;
    switch(req->response_code)
    {
        case HTTP_OK:
        {
            struct evbuffer* buf = evhttp_request_get_input_buffer(req);
            size_t len = evbuffer_get_length(buf);
            printf("print the head info:\n");
            print_request_head_info(req->output_headers);
            
            printf("len:%zu  body size:%zu\n", len, req->body_size);
            char *tmp = malloc(len+1);
            memcpy(tmp, evbuffer_pullup(buf, -1), len);
            tmp[len] = '\0';
            printf("print the body:\n");
            printf("HTML BODY:%s\n", tmp);
            free(tmp);
            
            event_base_loopexit(http_req_post->base, 0);
            break;
        }
        case HTTP_MOVEPERM:
            printf("%s", "the uri moved permanently\n");
            break;
        case HTTP_MOVETEMP:
        {
            const char *new_location = evhttp_find_header(req->input_headers, "Location");
            struct evhttp_uri *new_uri = evhttp_uri_parse(new_location);
            evhttp_uri_free(http_req_post->uri);
            http_req_post->uri = new_uri;
            start_url_request((struct http_request_get *)http_req_post, REQUEST_POST_FLAG);
            return;
        }
            
        default:
            event_base_loopexit(http_req_post->base, 0);
            return;
    }
}
コード例 #14
0
ファイル: nbd.c プロジェクト: KristineMcNerney/gammaray
bool __check_zero_handshake(struct evbuffer* in,
                            struct nbd_client* client)
{
    uint32_t* peek;
    peek = (uint32_t*) evbuffer_pullup(in, 4);

    if (peek)
    {
        if (*peek != 0)
        {
            client->state = NBD_DISCONNECTED;
            return false;
        }

        evbuffer_drain(in, 4);
        client->state = NBD_ZERO_RECEIVED;
        return false;
    }

    return true;
}
コード例 #15
0
ファイル: announcer-http.c プロジェクト: liangzhimy/BitLove
void
tr_tracker_http_announce( tr_session                 * session,
                          const tr_announce_request  * request,
                          tr_announce_response_func    response_func,
                          void                       * response_func_user_data )
{
    struct announce_data * d;
    struct evbuffer * buf = announce_url_new( session, request );
    const char * url = (const char *) evbuffer_pullup( buf, -1 );

    d = tr_new0( struct announce_data, 1 );
    d->response_func = response_func;
    d->response_func_user_data = response_func_user_data;
    memcpy( d->response.info_hash, request->info_hash, SHA_DIGEST_LENGTH );
    tr_strlcpy( d->log_name, request->log_name, sizeof( d->log_name ) );

    dbgmsg( request->log_name, "Sending announce to libcurl: \"%s\"", url );
    tr_webRun( session, url, NULL, NULL, on_announce_done, d );

    evbuffer_free( buf );
}
コード例 #16
0
static void s3http_connection_on_responce_cb (struct evhttp_request *req, void *ctx)
{
    RequestData *data = (RequestData *) ctx;
    struct evbuffer *inbuf;
    const char *buf = NULL;
    size_t buf_len;

    LOG_debug (CON_LOG, "Got HTTP response from server !");

    if (!req) {
        LOG_err (CON_LOG, "Request failed !");
        if (data->error_cb)
            data->error_cb (data->con, data->ctx);
        goto done;
    }

    // XXX: handle redirect
    // 200 and 204 (No Content) are ok
    if (evhttp_request_get_response_code (req) != 200 && evhttp_request_get_response_code (req) != 204
        && evhttp_request_get_response_code (req) != 307) {
        LOG_err (CON_LOG, "Server returned HTTP error: %d !", evhttp_request_get_response_code (req));
        LOG_debug (CON_LOG, "Error str: %s", req->response_code_line);
        if (data->error_cb)
            data->error_cb (data->con, data->ctx);
        goto done;
    }

    inbuf = evhttp_request_get_input_buffer (req);
    buf_len = evbuffer_get_length (inbuf);
    buf = (const char *) evbuffer_pullup (inbuf, buf_len);
    
    if (data->responce_cb)
        data->responce_cb (data->con, data->ctx, buf, buf_len, evhttp_request_get_input_headers (req));
    else
        LOG_debug (CON_LOG, ">>> NO callback function !");

done:
    g_free (data);
}
コード例 #17
0
ファイル: bencode-test.c プロジェクト: biiiep/transmission
static int
testJSONSnippet( const char * benc_str,
                 const char * expected )
{
    tr_benc top;
    char * serialized;
    struct evbuffer * buf;

    tr_bencLoad( benc_str, strlen( benc_str ), &top, NULL );
    buf = tr_bencToBuf( &top, TR_FMT_JSON );
    serialized = (char*) evbuffer_pullup( buf, -1 );
    stripWhitespace( serialized );
#if 0
    fprintf( stderr, "benc: %s\n", benc_str );
    fprintf( stderr, "json: %s\n", serialized );
    fprintf( stderr, "want: %s\n", expected );
#endif
    check_streq (expected, serialized);
    tr_bencFree( &top );
    evbuffer_free( buf );
    return 0;
}
コード例 #18
0
static bool
getfile (char ** setme, const char * root, tr_variant * path, struct evbuffer * buf)
{
  bool success = false;

  if (tr_variantIsList (path))
    {
      int i;
      const int n = tr_variantListSize (path);

      evbuffer_drain (buf, evbuffer_get_length (buf));
      evbuffer_add (buf, root, strlen (root));
      for (i=0; i<n; i++)
        {
          size_t len;
          const char * str;

          if (tr_variantGetStr (tr_variantListChild (path, i), &str, &len))
            {
              evbuffer_add (buf, TR_PATH_DELIMITER_STR, 1);
              evbuffer_add (buf, str, len);
            }
        }

      *setme = tr_utf8clean ((char*)evbuffer_pullup (buf, -1), evbuffer_get_length (buf));
      /* fprintf (stderr, "[%s]\n", *setme); */
      success = true;
    }

  if ((*setme != NULL) && path_is_suspicious (*setme))
    {
      tr_free (*setme);
      *setme = NULL;
      success = false;
    }

  return success;
}
コード例 #19
0
ファイル: libevent-client.c プロジェクト: YuWenHaiBo/nghttp2
/* readcb for bufferevent. Here we get the data from the input buffer
   of bufferevent and feed them to nghttp2 library. This may invoke
   nghttp2 callbacks. It may also queues the frame in nghttp2 session
   context. To send them, we call session_send() in the end. */
static void readcb(struct bufferevent *bev, void *ptr) {
  http2_session_data *session_data = (http2_session_data *)ptr;
  ssize_t readlen;
  struct evbuffer *input = bufferevent_get_input(bev);
  size_t datalen = evbuffer_get_length(input);
  unsigned char *data = evbuffer_pullup(input, -1);

  readlen = nghttp2_session_mem_recv(session_data->session, data, datalen);
  if (readlen < 0) {
    warnx("Fatal error: %s", nghttp2_strerror((int)readlen));
    delete_http2_session_data(session_data);
    return;
  }
  if (evbuffer_drain(input, (size_t)readlen) != 0) {
    warnx("Fatal error: evbuffer_drain failed");
    delete_http2_session_data(session_data);
    return;
  }
  if (session_send(session_data) != 0) {
    delete_http2_session_data(session_data);
    return;
  }
}
コード例 #20
0
static void userInput2Buff(struct evhttp_request *req, void *args)
{
	UserInput *ui = (UserInput *)args;
	struct event_base *base = ui->base;
	char *buff = ui->buff;
	struct evbuffer *body = evhttp_request_get_input_buffer(req);
	size_t len = evbuffer_get_length(body);
	unsigned char *requestLine;
	struct evbuffer *buf = evbuffer_new();

	switch(req->type) {
		case EVHTTP_REQ_POST:
			requestLine = evbuffer_pullup(body, -1);
			requestLine[len] = '\0';
			memcpy(buff, requestLine, len);
			evhttp_send_reply(req, HTTP_OK, "OK", buf);
			break;
		default:
			evhttp_send_error(req, HTTP_BADREQUEST, "Available POST only");
			break;
	}
	evbuffer_free(buf);
	event_base_loopbreak(base);
}
コード例 #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
ファイル: compress.c プロジェクト: nfvproject/TFM
int encode_in_ev(Gzb64* gzb64, struct evbuffer* input)
{
	int contiguous;
	unsigned char* input_block;

	while(evbuffer_get_length(input) > 0) 
	{
		contiguous = evbuffer_get_contiguous_space(input);	
		input_block = evbuffer_pullup(input, contiguous);

		if( contiguous < evbuffer_get_length(input) ) 
		{
			encode_in(gzb64, &input_block[0], contiguous, false);
			evbuffer_drain(input, contiguous);			
		} else 
		{
			/* last (only) block */
			encode_in(gzb64, &input_block[0], contiguous, true);
			evbuffer_drain(input, contiguous);
		}
	}
	
	return 0;
}
コード例 #23
0
ファイル: bitcoin-cli.cpp プロジェクト: RichardW35/bitcoin
static void http_request_done(struct evhttp_request *req, void *ctx)
{
    HTTPReply *reply = static_cast<HTTPReply*>(ctx);

    if (req == nullptr) {
        /* If req is nullptr, it means an error occurred while connecting: the
         * error code will have been passed to http_error_cb.
         */
        reply->status = 0;
        return;
    }

    reply->status = evhttp_request_get_response_code(req);

    struct evbuffer *buf = evhttp_request_get_input_buffer(req);
    if (buf)
    {
        size_t size = evbuffer_get_length(buf);
        const char *data = (const char*)evbuffer_pullup(buf, size);
        if (data)
            reply->body = std::string(data, size);
        evbuffer_drain(buf, size);
    }
}
コード例 #24
0
ファイル: chaincoin-cli.cpp プロジェクト: chaincoin/chaincoin
static void http_request_done(struct evhttp_request *req, void *ctx)
{
    HTTPReply *reply = static_cast<HTTPReply*>(ctx);

    if (req == nullptr) {
        /* If req is nullptr, it means an error occurred while connecting, but
         * I'm not sure how to find out which one. We also don't really care.
         */
        reply->status = 0;
        return;
    }

    reply->status = evhttp_request_get_response_code(req);

    struct evbuffer *buf = evhttp_request_get_input_buffer(req);
    if (buf)
    {
        size_t size = evbuffer_get_length(buf);
        const char *data = (const char*)evbuffer_pullup(buf, size);
        if (data)
            reply->body = std::string(data, size);
        evbuffer_drain(buf, size);
    }
}
コード例 #25
0
ファイル: conn.c プロジェクト: 0xffea/shim
static void
conn_readcb(struct bufferevent *bev, void *arg)
{
	struct conninfo *info = arg;
	struct evbuffer *inbuf = bufferevent_get_input(bev);
	unsigned char *data;
	unsigned char code;

	/* socks4 and socks4a both have an 8 byte response */
	if (evbuffer_get_length(inbuf) < 8) {
		log_debug("conn: waiting for full socks response");
		return;
	}

	data = evbuffer_pullup(inbuf, 8);
	code = data[1];
	evbuffer_drain(inbuf, 8);

	if (code != 0x5a) {
		finish_connection(info, 0, socks4_error_to_string(code));
	} else {
		finish_connection(info, 1, NULL);
	}
}
コード例 #26
0
ファイル: announcer-http.c プロジェクト: liangzhimy/BitLove
static void
on_announce_done( tr_session   * session,
                  bool           did_connect,
                  bool           did_timeout,
                  long           response_code,
                  const void   * msg,
                  size_t         msglen,
                  void         * vdata )
{
    tr_announce_response * response;
    struct announce_data * data = vdata;

    response = &data->response;
    response->did_connect = did_connect;
    response->did_timeout = did_timeout;
    dbgmsg( data->log_name, "Got announce response" );

    if( response_code != HTTP_OK )
    {
        const char * fmt = _( "Tracker gave HTTP response code %1$ld (%2$s)" );
        const char * response_str = tr_webGetResponseStr( response_code );
        response->errmsg = tr_strdup_printf( fmt, response_code, response_str );
    }
    else
    {
        tr_benc benc;
        const int benc_loaded = !tr_bencLoad( msg, msglen, &benc, NULL );

        if( getenv( "TR_CURL_VERBOSE" ) != NULL )
        {
            struct evbuffer * buf = tr_bencToBuf( &benc, TR_FMT_JSON );
            fprintf( stderr, "Announce response:\n< %s\n", evbuffer_pullup( buf, -1 ) );
            tr_free( buf );
        }

        if( benc_loaded && tr_bencIsDict( &benc ) )
        {
            int64_t i;
            size_t rawlen;
            tr_benc * tmp;
            const char * str;
            const uint8_t * raw;

            if( tr_bencDictFindStr( &benc, "failure reason", &str ) )
                response->errmsg = tr_strdup( str );

            if( tr_bencDictFindStr( &benc, "warning message", &str ) )
                response->warning = tr_strdup( str );

            if( tr_bencDictFindInt( &benc, "interval", &i ) )
                response->interval = i;

            if( tr_bencDictFindInt( &benc, "min interval", &i ) )
                response->min_interval = i;

            if( tr_bencDictFindStr( &benc, "tracker id", &str ) )
                response->tracker_id_str = tr_strdup( str );

            if( tr_bencDictFindInt( &benc, "complete", &i ) )
                response->seeders = i;

            if( tr_bencDictFindInt( &benc, "incomplete", &i ) )
                response->leechers = i;

            if( tr_bencDictFindInt( &benc, "downloaded", &i ) )
                response->downloads = i;

            if( tr_bencDictFindRaw( &benc, "peers6", &raw, &rawlen ) ) {
                dbgmsg( data->log_name, "got a peers6 length of %zu", rawlen );
                response->pex6 = tr_peerMgrCompact6ToPex( raw, rawlen,
                                              NULL, 0, &response->pex6_count );
            }

            if( tr_bencDictFindRaw( &benc, "peers", &raw, &rawlen ) ) {
                dbgmsg( data->log_name, "got a compact peers length of %zu", rawlen );
                response->pex = tr_peerMgrCompactToPex( raw, rawlen,
                                               NULL, 0, &response->pex_count );
            } else if( tr_bencDictFindList( &benc, "peers", &tmp ) ) {
                response->pex = listToPex( tmp, &response->pex_count );
                dbgmsg( data->log_name, "got a peers list with %zu entries",
                        response->pex_count );
            }
        }

        if( benc_loaded )
            tr_bencFree( &benc );
    }

    tr_runInEventThread( session, on_announce_done_eventthread, data );
}
コード例 #27
0
ファイル: httpd.c プロジェクト: topherx/forked-daapd
/* Thread: httpd */
void
httpd_send_reply(struct evhttp_request *req, int code, const char *reason, struct evbuffer *evbuf)
{
  unsigned char outbuf[128 * 1024];
  z_stream strm;
  struct evbuffer *gzbuf;
  struct evkeyvalq *headers;
  const char *param;
  int flush;
  int zret;
  int ret;

  if (!req)
    return;

  if (!evbuf || (evbuffer_get_length(evbuf) == 0))
    {
      DPRINTF(E_DBG, L_HTTPD, "Not gzipping body-less reply\n");

      goto no_gzip;
    }

  headers = evhttp_request_get_input_headers(req);

  param = evhttp_find_header(headers, "Accept-Encoding");
  if (!param)
    {
      DPRINTF(E_DBG, L_HTTPD, "Not gzipping; no Accept-Encoding header\n");

      goto no_gzip;
    }
  else if (!strstr(param, "gzip") && !strstr(param, "*"))
    {
      DPRINTF(E_DBG, L_HTTPD, "Not gzipping; gzip not in Accept-Encoding (%s)\n", param);

      goto no_gzip;
    }

  gzbuf = evbuffer_new();
  if (!gzbuf)
    {
      DPRINTF(E_LOG, L_HTTPD, "Could not allocate evbuffer for gzipped reply\n");

      goto no_gzip;
    }

  strm.zalloc = Z_NULL;
  strm.zfree = Z_NULL;
  strm.opaque = Z_NULL;

  /* Set up a gzip stream (the "+ 16" in 15 + 16), instead of a zlib stream (default) */
  zret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 + 16, 8, Z_DEFAULT_STRATEGY);
  if (zret != Z_OK)
    {
      DPRINTF(E_DBG, L_HTTPD, "zlib setup failed: %s\n", zError(zret));

      goto out_fail_init;
    }

  strm.next_in = evbuffer_pullup(evbuf, -1);
  strm.avail_in = evbuffer_get_length(evbuf);

  flush = Z_NO_FLUSH;

  /* 2 iterations: Z_NO_FLUSH until input is consumed, then Z_FINISH */
  for (;;)
    {
      do
	{
	  strm.next_out = outbuf;
	  strm.avail_out = sizeof(outbuf);

	  zret = deflate(&strm, flush);
	  if (zret == Z_STREAM_ERROR)
	    {
	      DPRINTF(E_LOG, L_HTTPD, "Could not deflate data: %s\n", strm.msg);

	      goto out_fail_gz;
	    }

	  ret = evbuffer_add(gzbuf, outbuf, sizeof(outbuf) - strm.avail_out);
	  if (ret < 0)
	    {
	      DPRINTF(E_LOG, L_HTTPD, "Out of memory adding gzipped data to evbuffer\n");

	      goto out_fail_gz;
	    }
	}
      while (strm.avail_out == 0);

      if (flush == Z_FINISH)
	break;

      flush = Z_FINISH;
    }

  if (zret != Z_STREAM_END)
    {
      DPRINTF(E_LOG, L_HTTPD, "Compressed data not finalized!\n");

      goto out_fail_gz;
    }

  deflateEnd(&strm);

  headers = evhttp_request_get_output_headers(req);

  evhttp_add_header(headers, "Content-Encoding", "gzip");
  evhttp_send_reply(req, code, reason, gzbuf);

  evbuffer_free(gzbuf);

  /* Drain original buffer, as would be after evhttp_send_reply() */
  evbuffer_drain(evbuf, evbuffer_get_length(evbuf));

  return;

 out_fail_gz:
  deflateEnd(&strm);
 out_fail_init:
  evbuffer_free(gzbuf);
 no_gzip:
  evhttp_send_reply(req, code, reason, evbuf);
}
コード例 #28
0
static void
add_response (struct evhttp_request * req,
              struct tr_rpc_server  * server,
              struct evbuffer       * out,
              struct evbuffer       * content)
{
  const char * key = "Accept-Encoding";
  const char * encoding = evhttp_find_header (req->input_headers, key);
  const int do_compress = encoding && strstr (encoding, "gzip");

  if (!do_compress)
    {
      evbuffer_add_buffer (out, content);
    }
  else
    {
      int state;
      struct evbuffer_iovec iovec[1];
      void * content_ptr = evbuffer_pullup (content, -1);
      const size_t content_len = evbuffer_get_length (content);

      if (!server->isStreamInitialized)
        {
          int compressionLevel;

          server->isStreamInitialized = true;
          server->stream.zalloc = (alloc_func) Z_NULL;
          server->stream.zfree = (free_func) Z_NULL;
          server->stream.opaque = (voidpf) Z_NULL;

          /* zlib's manual says: "Add 16 to windowBits to write a simple gzip header
           * and trailer around the compressed data instead of a zlib wrapper." */
#ifdef TR_LIGHTWEIGHT
          compressionLevel = Z_DEFAULT_COMPRESSION;
#else
          compressionLevel = Z_BEST_COMPRESSION;
#endif
          deflateInit2 (&server->stream, compressionLevel, Z_DEFLATED, 15+16, 8, Z_DEFAULT_STRATEGY);
        }

      server->stream.next_in = content_ptr;
      server->stream.avail_in = content_len;

      /* allocate space for the raw data and call deflate () just once --
       * we won't use the deflated data if it's longer than the raw data,
       * so it's okay to let deflate () run out of output buffer space */
      evbuffer_reserve_space (out, content_len, iovec, 1);
      server->stream.next_out = iovec[0].iov_base;
      server->stream.avail_out = iovec[0].iov_len;
      state = deflate (&server->stream, Z_FINISH);

      if (state == Z_STREAM_END)
        {
          iovec[0].iov_len -= server->stream.avail_out;

#if 0
          fprintf (stderr, "compressed response is %.2f of original (raw==%zu bytes; compressed==%zu)\n",
                   (double)evbuffer_get_length (out)/content_len,
                   content_len, evbuffer_get_length (out));
#endif
          evhttp_add_header (req->output_headers,
                             "Content-Encoding", "gzip");
        }
      else
        {
          memcpy (iovec[0].iov_base, content_ptr, content_len);
          iovec[0].iov_len = content_len;
        }

      evbuffer_commit_space (out, iovec, 1);
      deflateReset (&server->stream);
    }
}
コード例 #29
0
ファイル: regress_buffer.c プロジェクト: rphillips/libevent
static void
test_evbuffer(void *ptr)
{
	static char buffer[512], *tmp;
	struct evbuffer *evb = evbuffer_new();
	struct evbuffer *evb_two = evbuffer_new();
	size_t sz_tmp;
	int i;

	evbuffer_validate(evb);
	evbuffer_add_printf(evb, "%s/%d", "hello", 1);
	evbuffer_validate(evb);

	tt_assert(evbuffer_get_length(evb) == 7);
	tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "hello/1", 1));

	evbuffer_add_buffer(evb, evb_two);
	evbuffer_validate(evb);

	evbuffer_drain(evb, strlen("hello/"));
	evbuffer_validate(evb);
	tt_assert(evbuffer_get_length(evb) == 1);
	tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "1", 1));

	evbuffer_add_printf(evb_two, "%s", "/hello");
	evbuffer_validate(evb);
	evbuffer_add_buffer(evb, evb_two);
	evbuffer_validate(evb);

	tt_assert(evbuffer_get_length(evb_two) == 0);
	tt_assert(evbuffer_get_length(evb) == 7);
	tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "1/hello", 7) != 0);

	memset(buffer, 0, sizeof(buffer));
	evbuffer_add(evb, buffer, sizeof(buffer));
	evbuffer_validate(evb);
	tt_assert(evbuffer_get_length(evb) == 7 + 512);

	tmp = (char *)evbuffer_pullup(evb, 7 + 512);
	tt_assert(tmp);
	tt_assert(!strncmp(tmp, "1/hello", 7));
	tt_assert(!memcmp(tmp + 7, buffer, sizeof(buffer)));
	evbuffer_validate(evb);

	evbuffer_prepend(evb, "something", 9);
	evbuffer_validate(evb);
	evbuffer_prepend(evb, "else", 4);
	evbuffer_validate(evb);

	tmp = (char *)evbuffer_pullup(evb, 4 + 9 + 7);
	tt_assert(!strncmp(tmp, "elsesomething1/hello", 4 + 9 + 7));
	evbuffer_validate(evb);

	evbuffer_drain(evb, -1);
	evbuffer_validate(evb);
	evbuffer_drain(evb_two, -1);
	evbuffer_validate(evb);

	for (i = 0; i < 3; ++i) {
		evbuffer_add(evb_two, buffer, sizeof(buffer));
		evbuffer_validate(evb_two);
		evbuffer_add_buffer(evb, evb_two);
		evbuffer_validate(evb);
		evbuffer_validate(evb_two);
	}

	tt_assert(evbuffer_get_length(evb_two) == 0);
	tt_assert(evbuffer_get_length(evb) == i * sizeof(buffer));

	/* test remove buffer */
	sz_tmp = (size_t)(sizeof(buffer)*2.5);
	evbuffer_remove_buffer(evb, evb_two, sz_tmp);
	tt_assert(evbuffer_get_length(evb_two) == sz_tmp);
	tt_assert(evbuffer_get_length(evb) == sizeof(buffer) / 2);
	evbuffer_validate(evb);

	if (memcmp(evbuffer_pullup(
			   evb, -1), buffer, sizeof(buffer) / 2) != 0 ||
	    memcmp(evbuffer_pullup(
			   evb_two, -1), buffer, sizeof(buffer) != 0))
		tt_abort_msg("Pullup did not preserve content");

	evbuffer_validate(evb);


	/* testing one-vector reserve and commit */
	{
		struct evbuffer_iovec v[1];
		char *buf;
		int i, j, r;

		for (i = 0; i < 3; ++i) {
			r = evbuffer_reserve_space(evb, 10000, v, 1);
			tt_int_op(r, ==, 1);
			tt_assert(v[0].iov_len >= 10000);
			tt_assert(v[0].iov_base != NULL);

			evbuffer_validate(evb);
			buf = v[0].iov_base;
			for (j = 0; j < 10000; ++j) {
				buf[j] = j;
			}
			evbuffer_validate(evb);

			tt_int_op(evbuffer_commit_space(evb, v, 1), ==, 0);
			evbuffer_validate(evb);

			tt_assert(evbuffer_get_length(evb) >= 10000);

			evbuffer_drain(evb, j * 5000);
			evbuffer_validate(evb);
		}
	}

 end:
	evbuffer_free(evb);
	evbuffer_free(evb_two);
}
コード例 #30
0
ファイル: read_cb.cpp プロジェクト: shanoasaber/server_src
void conn_read_cb(struct bufferevent *bev, void *arg)
{
    conn *c = (conn *)arg;
    user_callback *cb = (user_callback *)(c->data);

    struct evbuffer* input = bufferevent_get_input(bev);
    size_t total_len = evbuffer_get_length(input);

    while (1)
    {
        if (total_len < MSG_HEAD_SIZE) {
            goto conti;
        }
        else {
            unsigned char *buffer = evbuffer_pullup(input, MSG_HEAD_SIZE);
            if (NULL == buffer)
            {
                merror("evbuffer_pullup MSG_HEAD_SIZE failed!");
                goto err;
            }

            unsigned short *cur = (unsigned short *)buffer;
            unsigned int len = ntohs(*(unsigned int *)cur);
            cur += 2;

            if (MSG_MAX_SIZE < len)
            {
                merror("len:%d > MSG_MAX_SIZE!", len);
                goto err;
            }

            if (total_len < MSG_HEAD_SIZE + len)
                goto conti;

            size_t msg_len = MSG_HEAD_SIZE + len;
            buffer = evbuffer_pullup(input, msg_len);
            if (NULL == buffer)
            {
                merror("evbuffer_pullup msg_len failed!");
                goto err;
            }

            /* TODO frequency limit */

            /* callback */
            if (cb->rpc)
                (*(cb->rpc))(c, buffer, msg_len);

            if (evbuffer_drain(input, msg_len) < 0)
            {
                merror("evbuffer_drain failed!");
                goto err;
            }

            total_len -= msg_len;
        }
    }
    return;

err:
    mdebug("close sockect!");
    if (cb->disconnect) {
        (*(cb->disconnect))(c);
    }
    conn_decref(c);
    return;

conti:
    bufferevent_enable(bev, EV_READ);
    return;
}