コード例 #1
0
ファイル: http_ws.c プロジェクト: cyrusimap/cyrus-imapd
static ssize_t recv_cb(wslay_event_context_ptr ev,
                       uint8_t *buf, size_t len,
                       int flags __attribute__((unused)),
                       void *user_data)
{
    struct transaction_t *txn = (struct transaction_t *) user_data;
    struct protstream *pin = txn->conn->pin;
    ssize_t n;

    if (txn->conn->sess_ctx) {
        pin = ((struct ws_context *) txn->ws_ctx)->h2_pin;
    }

    n = prot_read(pin, (char *) buf, len);
    if (!n) {
        /* No data */
        if (pin->eof && !pin->fixedsize)
            wslay_event_set_error(ev, WSLAY_ERR_NO_MORE_MSG);
        else if (pin->error)
            wslay_event_set_error(ev, WSLAY_ERR_CALLBACK_FAILURE);
        else
            wslay_event_set_error(ev, WSLAY_ERR_WOULDBLOCK);

        n = -1;
    }

    syslog(LOG_DEBUG,
           "ws_recv_cb(%zu): n = %zd, eof = %d, err = '%s', errno = %m",
           len, n, pin->eof, pin->error ? pin->error : "");

    return n;
}
コード例 #2
0
ファイル: vs_websocket.c プロジェクト: zdenek-perutka/verse
/**
 * \brief WIP: Wslay send callback
 */
ssize_t vs_send_ws_callback_data(wslay_event_context_ptr ctx,
		const uint8_t *data,
		size_t len,
		int flags,
		void *user_data)
{
	struct vContext *C = (struct vContext*)user_data;
	struct IO_CTX *io_ctx = CTX_io_ctx(C);
	ssize_t r;
	int sflags = 0;

#ifdef MSG_MORE
if(flags & WSLAY_MSG_MORE) {
	sflags |= MSG_MORE;
}
#endif

	while((r = send(io_ctx->sockfd, data, len, sflags)) == -1 &&
			errno == EINTR);
	if(r == -1) {
		if(errno == EAGAIN || errno == EWOULDBLOCK) {
			wslay_event_set_error(ctx, WSLAY_ERR_WOULDBLOCK);
		} else {
			wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE);
		}
	}
	v_print_log(VRS_PRINT_DEBUG_MSG,
			"WS Callback Send Data\n");
	return r;
}
コード例 #3
0
ファイル: vs_websocket.c プロジェクト: zdenek-perutka/verse
/**
 * \brief WIP: Wslay receive callback
 */
ssize_t vs_recv_ws_callback_data(wslay_event_context_ptr ctx,
		uint8_t *buf,
		size_t len,
		int flags,
		void *user_data)
{
	struct vContext *C = (struct vContext*)user_data;
	struct IO_CTX *io_ctx = CTX_io_ctx(C);
	ssize_t r;
	(void)flags;

	while((r = recv(io_ctx->sockfd, buf, len, 0)) == -1 &&
			errno == EINTR);
	if(r == -1) {
		if(errno == EAGAIN || errno == EWOULDBLOCK) {
			wslay_event_set_error(ctx, WSLAY_ERR_WOULDBLOCK);
		} else {
			wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE);
		}
	} else if(r == 0) {
		/* Unexpected EOF is also treated as an error */
		wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE);
		r = -1;
	}
	v_print_log(VRS_PRINT_DEBUG_MSG,
			"WS Callback Received Data, len: %ld, flags: %d\n",
			len, flags);
	return r;
}
コード例 #4
0
ファイル: ws.c プロジェクト: kaendfinger/sdk-dslink-c
static
ssize_t want_read_cb(wslay_event_context_ptr ctx,
                     uint8_t *buf, size_t len,
                     int flags, void *user_data) {
    (void) flags;

    DSLink *link = user_data;
    if (link->_delay == 0) {
        wslay_event_set_error(ctx, WSLAY_ERR_WOULDBLOCK);
        return -1;
    }
    int read = dslink_socket_read_timeout(link->_socket,
                                          (char *) buf,len, link->_delay);
    link->_delay = 0;
    if (read == 0) {
        wslay_event_set_error(ctx, WSLAY_ERR_NO_MORE_MSG);
        return -1;
    } else if (read == DSLINK_SOCK_READ_ERR) {
        if (errno == MBEDTLS_ERR_SSL_WANT_READ
            || errno == MBEDTLS_ERR_SSL_TIMEOUT) {
            wslay_event_set_error(ctx, WSLAY_ERR_WOULDBLOCK);
        } else {
            wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE);
        }
        return -1;
    }
    return read;
}
コード例 #5
0
ファイル: mrb_wslay.c プロジェクト: Asmod4n/mruby-wslay
static ssize_t
mrb_wslay_event_recv_callback(wslay_event_context_ptr ctx,
  uint8_t *buf, size_t len, int flags, void *user_data)
{
  mrb_wslay_user_data *data = (mrb_wslay_user_data *) user_data;
  mrb_state*mrb = data->mrb;
  int ai = mrb_gc_arena_save(mrb);

  struct mrb_jmpbuf *prev_jmp = mrb->jmp;
  struct mrb_jmpbuf c_jmp;

  mrb_int ret = -1;
  MRB_TRY(&c_jmp) {
    mrb->jmp = &c_jmp;

    mrb_value argv[2];
    argv[0] = mrb_cptr_value(mrb, buf);
    argv[1] = mrb_fixnum_value(len);

    errno = 0;
    mrb_assert(mrb_type(data->recv_callback) == MRB_TT_PROC);
    mrb_value buf_obj = mrb_yield_argv(mrb, data->recv_callback, NELEMS(argv), argv);

    if (mrb_fixnum_p(buf_obj)) {
      ret = mrb_fixnum(buf_obj);
    } else {
      buf_obj = mrb_str_to_str(mrb, buf_obj);
      ret = RSTRING_LEN(buf_obj);
      if (ret < 0||ret > len) {
        mrb_raise(mrb, E_RANGE_ERROR, "returned buf doesn't fit");
      }
      if (ret > 0) {
        memmove(buf, (uint8_t *) RSTRING_PTR(buf_obj), ret);
      }
    }

    mrb->jmp = prev_jmp;
  } MRB_CATCH(&c_jmp) {
    mrb->jmp = prev_jmp;
    if (mrb_obj_is_kind_of(mrb,
        mrb_obj_value(mrb->exc),
            mrb_class_get_under(mrb,
                mrb_module_get(mrb, "Errno"), "EAGAIN"))||
    mrb_obj_is_kind_of(mrb,
        mrb_obj_value(mrb->exc),
            mrb_class_get_under(mrb,
                mrb_module_get(mrb, "Errno"), "EWOULDBLOCK"))) {
      mrb->exc = NULL;
      wslay_event_set_error(ctx, WSLAY_ERR_WOULDBLOCK);
    } else {
      wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE);
    }
  } MRB_END_EXC(&c_jmp);

  mrb_gc_arena_restore(mrb, ai);

  return ret;
}
コード例 #6
0
ファイル: test.c プロジェクト: GhostGumm/CarbonComet
ssize_t send_callback(wslay_event_context_ptr ctx,
                      const uint8_t *data, size_t len, int flags,
                      void *user_data)
{
  WebSocketClient *ws = (WebSocketClient*)user_data;
  ssize_t r = ws->send_data(data, len, flags);
  if(r == -1) {
    if(errno == EAGAIN || errno == EWOULDBLOCK) {
      wslay_event_set_error(ctx, WSLAY_ERR_WOULDBLOCK);
    } else {
      wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE);
    }
  }
  return r;
}
コード例 #7
0
ファイル: WebSocket.cpp プロジェクト: Andersbakken/plast
ssize_t WebSocket::wslaySendCallback(wslay_event_context* ctx,
                                     const uint8_t* data, size_t len, int /*flags*/,
                                     void* user_data)
{
    WebSocket* socket = static_cast<WebSocket*>(user_data);
    if (!socket->mClient) {
        wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE);
        return -1;
    }
    if (!socket->mClient->write(data, len)) {
        wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE);
        return -1;
    }
    return len;
}
コード例 #8
0
ファイル: http_ws.c プロジェクト: cyrusimap/cyrus-imapd
static ssize_t send_cb(wslay_event_context_ptr ev,
                       const uint8_t *data, size_t len,
                       int flags, void *user_data)
{
    struct transaction_t *txn = (struct transaction_t *) user_data;
    int r;

    if (txn->conn->sess_ctx) {
        int last_chunk =
            (txn->flags.conn & CONN_CLOSE) && !(flags & WSLAY_MSG_MORE);

        r = http2_data_chunk(txn, (const char *) data, len,
                             last_chunk, NULL /* md5ctx */);
    }
    else {
        r = prot_write(txn->conn->pout, (const char *) data, len);
    }

    syslog(LOG_DEBUG, "ws_send_cb(%zu): %d", len, r);

    if (r) {
        wslay_event_set_error(ev, WSLAY_ERR_CALLBACK_FAILURE);
        return -1;
    }

    return len;
}
コード例 #9
0
ファイル: mrb_wslay.c プロジェクト: Asmod4n/mruby-wslay
static ssize_t
mrb_wslay_event_send_callback(wslay_event_context_ptr ctx,
  const uint8_t *buf, size_t len,
  int flags, void *user_data)
{
  mrb_wslay_user_data *data = (mrb_wslay_user_data *) user_data;
  mrb_state* mrb = data->mrb;
  int ai = mrb_gc_arena_save(mrb);

  struct mrb_jmpbuf *prev_jmp = mrb->jmp;
  struct mrb_jmpbuf c_jmp;
  mrb_int ret = -1;
  MRB_TRY(&c_jmp) {
    data->mrb->jmp = &c_jmp;

    errno = 0;
    mrb_value buf_obj = mrb_str_new_static(mrb, (const char *) buf, len);
    mrb_assert(mrb_type(data->send_callback) == MRB_TT_PROC);
    mrb_value sent = mrb_yield(mrb, data->send_callback, buf_obj);

    ret = mrb_int(mrb, sent);

    mrb_assert(ret >= 0&&ret <= len);

    mrb->jmp = prev_jmp;
  } MRB_CATCH(&c_jmp) {
    mrb->jmp = prev_jmp;
    if (mrb_obj_is_kind_of(mrb,
        mrb_obj_value(mrb->exc),
            mrb_class_get_under(mrb,
                mrb_module_get(mrb, "Errno"), "EAGAIN"))||
    mrb_obj_is_kind_of(mrb,
        mrb_obj_value(mrb->exc),
            mrb_class_get_under(mrb,
                mrb_module_get(mrb, "Errno"), "EWOULDBLOCK"))) {
      mrb->exc = NULL;
      wslay_event_set_error(ctx, WSLAY_ERR_WOULDBLOCK);
    } else {
      wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE);
    }
  } MRB_END_EXC(&c_jmp);

  mrb_gc_arena_restore(mrb, ai);

  return ret;
}
コード例 #10
0
ファイル: ws.c プロジェクト: kaendfinger/sdk-dslink-c
static
ssize_t want_write_cb(wslay_event_context_ptr ctx,
                      const uint8_t *data, size_t len,
                      int flags, void *user_data) {
    (void) flags;

    DSLink *link = user_data;
    int written = dslink_socket_write(link->_socket, (char *) data, len);
    if (written < 0) {
        if (errno == MBEDTLS_ERR_SSL_WANT_WRITE) {
            wslay_event_set_error(ctx, WSLAY_ERR_WANT_WRITE);
        } else {
            wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE);
        }
        return -1;
    }

    return written;
}
コード例 #11
0
ファイル: vs_websocket.c プロジェクト: laishi/verse
/**
 * \brief WSLay send callback
 */
ssize_t vs_send_ws_callback_data(wslay_event_context_ptr ctx,
		const uint8_t *data,
		size_t len,
		int flags,
		void *user_data)
{
	struct vContext *C = (struct vContext*)user_data;
	struct IO_CTX *io_ctx = CTX_io_ctx(C);
	ssize_t ret = 0;
	int sflags = 0;

#ifdef MSG_MORE
	if(flags & WSLAY_MSG_MORE) {
		sflags |= MSG_MORE;
	}
#endif

	/* Try to send all data */
	while((ret = send(io_ctx->sockfd, data, len, sflags)) == -1 &&
			errno == EINTR) {
#if DEBUG_WEB_SOCKET
		v_print_log(VRS_PRINT_DEBUG_MSG,
				"WS Callback Send Data, len: %ld, flags: %d -> %ld\n",
				len, sflags, ret);
#endif
	}

#if DEBUG_WEB_SOCKET
	v_print_log(VRS_PRINT_DEBUG_MSG,
			"WS Callback Send Data, len: %ld, flags: %d -> ret: %ld\n",
			len, sflags, ret);
#endif

	if(ret == -1) {
		if(errno == EAGAIN || errno == EWOULDBLOCK) {
			wslay_event_set_error(ctx, WSLAY_ERR_WOULDBLOCK);
		} else {
			wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE);
		}
	}

	return ret;
}
コード例 #12
0
ファイル: fork-echoserv.c プロジェクト: Andersbakken/wslay
ssize_t recv_callback(wslay_event_context_ptr ctx, uint8_t *buf, size_t len,
                      int flags, void *user_data)
{
  struct Session *session = (struct Session*)user_data;
  ssize_t r;
  while((r = recv(session->fd, buf, len, 0)) == -1 && errno == EINTR);
  if(r == -1) {
    if(errno == EAGAIN || errno == EWOULDBLOCK) {
      wslay_event_set_error(ctx, WSLAY_ERR_WOULDBLOCK);
    } else {
      wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE);
    }
  } else if(r == 0) {
    /* Unexpected EOF is also treated as an error */
    wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE);
    r = -1;
  }
  return r;
}
コード例 #13
0
ファイル: websocket.c プロジェクト: drashti304/TizenRT
websocket_return_t websocket_set_error(websocket_t *websocket, int val)
{
	if (websocket == NULL) {
		WEBSOCKET_DEBUG("NULL parameter\n");
		return WEBSOCKET_ALLOCATION_ERROR;
	}

	wslay_event_set_error(websocket->ctx, val);

	return WEBSOCKET_SUCCESS;
}
コード例 #14
0
ファイル: fork-echoserv.c プロジェクト: Andersbakken/wslay
ssize_t send_callback(wslay_event_context_ptr ctx,
                      const uint8_t *data, size_t len, int flags,
                      void *user_data)
{
  struct Session *session = (struct Session*)user_data;
  ssize_t r;
  int sflags = 0;
#ifdef MSG_MORE
  if(flags & WSLAY_MSG_MORE) {
    sflags |= MSG_MORE;
  }
#endif // MSG_MORE
  while((r = send(session->fd, data, len, sflags)) == -1 && errno == EINTR);
  if(r == -1) {
    if(errno == EAGAIN || errno == EWOULDBLOCK) {
      wslay_event_set_error(ctx, WSLAY_ERR_WOULDBLOCK);
    } else {
      wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE);
    }
  }
  return r;
}
コード例 #15
0
ファイル: WebSocket.cpp プロジェクト: Andersbakken/plast
ssize_t WebSocket::wslayRecvCallback(wslay_event_context* ctx,
                                     uint8_t* data, size_t len, int /*flags*/,
                                     void* user_data)
{
    // return up to len bytes
    WebSocket* socket = static_cast<WebSocket*>(user_data);
    if (!socket->mClient) {
        wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE);
        return -1;
    }
    if (socket->mBuffers.isEmpty()) {
        wslay_event_set_error(ctx, WSLAY_ERR_WOULDBLOCK);
        return -1;
    }

    size_t rem = len;
    uint8_t* ptr = data;
    auto it = socket->mBuffers.begin();
    while (rem > 0 && it != socket->mBuffers.end()) {
        Buffer& buf = *it;
        if (rem >= buf.size()) {
            memcpy(ptr, buf.data(), buf.size());
            ptr += buf.size();
            rem -= buf.size();
        } else {
            // read and move
            memcpy(ptr, buf.data(), rem);

            memmove(buf.data(), buf.data() + rem, buf.size() - rem);
            buf.resize(buf.size() - rem);
            return len;
        }
        socket->mBuffers.erase(it++);
    }
    return ptr - data;
}
コード例 #16
0
ファイル: websocket.c プロジェクト: devnexen/h2o
static ssize_t recv_callback(wslay_event_context_ptr ctx, uint8_t *buf, size_t len, int flags, void *_conn)
{
    h2o_websocket_conn_t *conn = _conn;

    /* return WOULDBLOCK if no data */
    if (conn->sock->input->size == 0) {
        wslay_event_set_error(conn->ws_ctx, WSLAY_ERR_WOULDBLOCK);
        return -1;
    }

    if (conn->sock->input->size < len)
        len = conn->sock->input->size;
    memcpy(buf, conn->sock->input->bytes, len);
    h2o_buffer_consume(&conn->sock->input, len);
    return len;
}
コード例 #17
0
ファイル: websocket.c プロジェクト: devnexen/h2o
static ssize_t send_callback(wslay_event_context_ptr ctx, const uint8_t *data, size_t len, int flags, void *_conn)
{
    h2o_websocket_conn_t *conn = _conn;
    h2o_iovec_t *buf;

    /* return WOULDBLOCK if pending or no buffer available */
    if (h2o_socket_is_writing(conn->sock) ||
        conn->_write_buf.cnt == sizeof(conn->_write_buf.bufs) / sizeof(conn->_write_buf.bufs[0])) {
        wslay_event_set_error(conn->ws_ctx, WSLAY_ERR_WOULDBLOCK);
        return -1;
    }

    buf = &conn->_write_buf.bufs[conn->_write_buf.cnt];

    /* copy data */
    buf->base = h2o_mem_alloc(len);
    buf->len = len;
    memcpy(buf->base, data, len);
    ++conn->_write_buf.cnt;
    return len;
}
コード例 #18
0
ファイル: websocket.c プロジェクト: ConfusedReality/h2o
static ssize_t send_callback(wslay_event_context_ptr ctx, const uint8_t *data, size_t len, int flags, void *_conn)
{
    h2o_websocket_conn_t *conn = _conn;
    h2o_iovec_t buf;

    /* return WOULDBLOCK if pending (TODO: queue fixed number of chunks, instead of only one) */
    if (h2o_socket_is_writing(conn->sock)) {
        wslay_event_set_error(conn->ws_ctx, WSLAY_ERR_WOULDBLOCK);
        return -1;
    }

    /* copy data */
    conn->_write_buf = h2o_mem_realloc(conn->_write_buf, len);
    memcpy(conn->_write_buf, data, len);

    /* write */
    buf.base = conn->_write_buf;
    buf.len = len;
    h2o_socket_write(conn->sock, &buf, 1, on_write_complete);

    return len;
}
コード例 #19
0
ファイル: mrb_wslay.c プロジェクト: Asmod4n/mruby-wslay
static void
mrb_wslay_event_on_msg_recv_callback(wslay_event_context_ptr ctx,
  const struct wslay_event_on_msg_recv_arg *arg, void *user_data)
{
  mrb_wslay_user_data *data = (mrb_wslay_user_data *) user_data;
  mrb_state *mrb = data->mrb;

  int ai = mrb_gc_arena_save(mrb);
  struct mrb_jmpbuf *prev_jmp = mrb->jmp;
  struct mrb_jmpbuf c_jmp;

  MRB_TRY(&c_jmp) {
    mrb->jmp = &c_jmp;

    mrb_value argv[4];
    argv[0] = mrb_fixnum_value(arg->rsv);
    argv[1] = MRB_GET_OPCODE(mrb_fixnum_value(arg->opcode));
    argv[2] = mrb_str_new(mrb, (const char *) arg->msg, arg->msg_length);
    argv[3] = MRB_GET_STATUSCODE(mrb_fixnum_value(arg->status_code));

    mrb_value on_msg_recv_arg = mrb_obj_new(mrb,
      mrb_class_get_under(mrb,
        mrb_module_get_under(mrb,
          mrb_module_get(mrb, "Wslay"), "Event"), "OnMsgRecvArg"), NELEMS(argv), argv);

    mrb_assert(mrb_type(data->on_msg_recv_callback) == MRB_TT_PROC);
    mrb_yield(mrb, data->on_msg_recv_callback, on_msg_recv_arg);

    mrb_gc_arena_restore(mrb, ai);

    mrb->jmp = prev_jmp;
  } MRB_CATCH(&c_jmp) {
    mrb->jmp = prev_jmp;
    wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE);
    mrb_gc_arena_restore(mrb, ai);
    MRB_THROW(mrb->jmp);
  } MRB_END_EXC(&c_jmp);
}