示例#1
0
文件: zloop.c 项目: Cargo-Labs/czmq
zloop_t *
zloop_new (void)
{
    zloop_t
    *self;

    self = (zloop_t *) zmalloc (sizeof (zloop_t));
    if (!self)
        return NULL;

    self->readers = zlistx_new ();
    if (self->readers)
        self->pollers = zlistx_new ();
    if (self->pollers)
        self->timers = zlistx_new ();
    if (self->timers)
        self->zombies = zlistx_new ();
    if (self->zombies)
        self->tickets = zlistx_new ();
    if (self->tickets) {
        self->last_timer_id = 0;
        zlistx_set_destructor (self->readers, (czmq_destructor *) s_reader_destroy);
        zlistx_set_destructor (self->pollers, (czmq_destructor *) s_poller_destroy);
        zlistx_set_destructor (self->timers, (czmq_destructor *) s_timer_destroy);
        zlistx_set_comparator (self->timers, (czmq_comparator *) s_timer_comparator);
        zlistx_set_destructor (self->tickets, (czmq_destructor *) s_ticket_destroy);
        zlistx_set_comparator (self->tickets, (czmq_comparator *) s_ticket_comparator);
    }
    else
        zloop_destroy (&self);
    return self;
}
示例#2
0
static int
client_initialize (client_t *self)
{
    //  We'll ping the server once every two seconds
    self->heartbeat_timer = 2500;
    self->replays = zlistx_new ();
    zlistx_set_destructor (self->replays, (czmq_destructor *) s_replay_destroy);
    return 0;
}
示例#3
0
static service_t *
s_service_new (const char *name)
{
    service_t *self = (service_t *) zmalloc (sizeof (service_t));
    if (self) {
        self->name = strdup (name);
        if (self->name)
            self->queue = zlistx_new ();
        if (self->queue)
            self->offers = zlistx_new ();
        if (self->offers) {
            zlistx_set_destructor (self->queue, (czmq_destructor *) mlm_msg_destroy);
            zlistx_set_destructor (self->offers, (czmq_destructor *) s_offer_destroy);
        }
        else
            s_service_destroy (&self);
    }
    return self;
}
示例#4
0
ziflist_t *
ziflist_new (void)
{
    zlistx_t *list = zlistx_new ();
    ziflist_t *self = (ziflist_t *) list;
    if (self) {
        zlistx_set_destructor (list, (czmq_destructor *) s_interface_destroy);
        ziflist_reload (self);
    }
    return self;
}
示例#5
0
void
zhttp_client_test (bool verbose)
{
#if defined(HAVE_LIBCURL) && defined(ZMQ_STREAM)
    printf (" * zhttp_client: ");
    zsock_t *server = zsock_new_stream (NULL);
    int port = zsock_bind (server, "tcp://127.0.0.1:*");
    char url[255];
    sprintf (url, "http://127.0.0.1:%d", port);

    //  @selftest
    //  Simple create/destroy test
    zhttp_client_t *self = zhttp_client_new (verbose);
    assert (self);

    //  Send the get request
    zlistx_t *headers = zlistx_new ();
    zlistx_add_end (headers, "Host: zeromq.org");
    zhttp_client_get (self, url, headers, NULL);
    zlistx_destroy (&headers);

    //  Receive request on the server
    zchunk_t *routing_id;
    char *request;
    int rc = zsock_recv (server, "cs", &routing_id, &request);
    assert (rc == 0);

    //  Send the response
    char* response = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\nHello";
    zsock_send (server, "cs", routing_id, response);

    //  Receive the response on the http client
    int code;
    zchunk_t *data;

    zhttp_client_recv (self, &code, &data, NULL);
    assert (zchunk_streq (data, "Hello"));

    //  Sending another request, without being answer
    //  Checking the client ability to stop while request are inprogres
    zhttp_client_get (self, url, NULL, NULL);

    zchunk_destroy (&data);
    zchunk_destroy (&routing_id);
    zstr_free (&request);
    zhttp_client_destroy (&self);
    zsock_destroy (&server);

    //  @end
    printf ("OK\n");
#endif
}
示例#6
0
文件: zgossip.c 项目: Cargo-Labs/czmq
static int
server_initialize (server_t *self)
{
    //  Default timeout for clients is one second; the caller can
    //  override this with a SET message.
    engine_configure (self, "server/timeout", "1000");
    self->message = zgossip_msg_new ();
    
    self->remotes = zlistx_new ();
    assert (self->remotes);
    zlistx_set_destructor (self->remotes, (czmq_destructor *) zsock_destroy_);
    
    self->tuples = zhashx_new ();
    assert (self->tuples);
    return 0;
}
示例#7
0
static selector_t *
s_selector_new (void *client, const char *pattern)
{
    selector_t *self = (selector_t *) zmalloc (sizeof (selector_t));
    if (self) {
        self->rex = zrex_new (pattern);
        if (self->rex)
            self->pattern = strdup (pattern);
        if (self->pattern)
            self->clients = zlistx_new ();
        if (self->clients)
            zlistx_add_end (self->clients, client);
        else
            s_selector_destroy (&self);
    }
    return self;
}
示例#8
0
static stream_engine_t *
s_stream_engine_new (zsock_t *cmdpipe, zsock_t *msgpipe)
{
    stream_engine_t *self = (stream_engine_t *) zmalloc (sizeof (stream_engine_t));
    if (self) {
        self->cmdpipe = cmdpipe;
        self->msgpipe = msgpipe;
        self->poller = zpoller_new (self->cmdpipe, self->msgpipe, NULL);
        if (self->poller)
            self->selectors = zlistx_new ();
        if (self->selectors)
            zlistx_set_destructor (self->selectors, (czmq_destructor *) s_selector_destroy);
        else
            s_stream_engine_destroy (&self);
    }
    return self;
}
示例#9
0
ztrie_t *
ztrie_new (char delimiter)
{
    ztrie_t *self = (ztrie_t *) zmalloc (sizeof (ztrie_t));
    assert (self);

    //  Initialize properties
    if (delimiter)
        self->delimiter = delimiter;
    else
        self->delimiter = '/';
    self->root = s_ztrie_node_new (NULL, "", 0,  NULL, NODE_TYPE_STRING);
    self->match = NULL;
    self->params = zlistx_new ();

    return self;
}
示例#10
0
static ztrie_node_t *
s_ztrie_node_new (ztrie_node_t *parent, char *token, int token_len, zlistx_t *param_keys, int token_type)
{
    ztrie_node_t *self = (ztrie_node_t *) zmalloc (sizeof (ztrie_node_t));
    assert (self);

    //  Initialize properties
    self->token = s_strndup (token, token_len);
    self->token_type = token_type;
    self->token_len = token_len;
    self->endpoint = false;
    self->parameter_count = 0;
    self->parameter_names = NULL;
    self->parameter_values = NULL;
    if (param_keys && zlistx_size (param_keys) > 0) {
        self->parameter_count = zlistx_size (param_keys);
        self->parameter_names = (char **) malloc (sizeof (char *) * self->parameter_count);
        self->parameter_values = (char **) malloc (sizeof (char *) * self->parameter_count);
        char *key = (char *) zlistx_first (param_keys);
        int index;
        for (index = 0; index < zlistx_size (param_keys); index++) {
            self->parameter_names [index] = key;
            self->parameter_values [index] = NULL;
            key = (char *) zlistx_next (param_keys);
        }
    }
    if (self->token_type == NODE_TYPE_REGEX || self->token_type == NODE_TYPE_PARAM)
        self->regex = zrex_new (self->token);
    self->data = NULL;
    //  Initialize relationships
    self->parent = parent;
    if (self->parent) {
        zlistx_add_end (self->parent->children, self);
        //  Sort regexes to the end to avoid conlficts
        zlistx_sort (self->parent->children);
    }
    size_t parent_path_len = self->parent? self->parent->path_len: 0;
    self->path_len = parent_path_len + strlen (self->token) + 1; // +1 path delimiter
    self->children = zlistx_new ();
    zlistx_set_comparator (self->children, s_ztrie_node_compare);

    return self;
}
示例#11
0
static service_t *
s_service_new (const char *name, const server_t *server)
{
    service_t *self = (service_t *) zmalloc (sizeof (service_t));
    if (self) {
        self->name = strdup (name);
        if (self->name)
            self->queue = mlm_msgq_new ();
        if (self->queue)
            self->offers = zlistx_new ();
        if (self->offers) {
            mlm_msgq_set_cfg (self->queue, server->service_queue_cfg);
            mlm_msgq_set_name (self->queue, "service %s", self->name);
            zlistx_set_destructor (self->offers, (czmq_destructor *) s_offer_destroy);
        }
        else
            s_service_destroy (&self);
    }
    return self;
}
示例#12
0
文件: zlistx.c 项目: AxelVoitier/czmq
zlistx_t *
zlistx_dup (zlistx_t *self)
{
    if (!self)
        return NULL;

    zlistx_t *copy = zlistx_new ();
    if (copy) {
        //  Copy item handlers
        copy->destructor = self->destructor;
        copy->duplicator = self->duplicator;
        copy->comparator = self->comparator;

        //  Copy nodes
        node_t *node;
        for (node = self->head->next; node != self->head; node = node->next)
            zlistx_add_end (copy, node->item);
    }
    return copy;
}
示例#13
0
文件: zgossip.c 项目: taotetek/czmq
static int
server_initialize (server_t *self)
{
    //  Default timeout for clients is one second; the caller can
    //  override this with a SET message.
    engine_configure (self, "server/timeout", "1000");
    self->message = zgossip_msg_new ();

    self->remotes = zlistx_new ();
    assert (self->remotes);
    zlistx_set_destructor (self->remotes, (czmq_destructor *) zsock_destroy);

    self->tuples = zhashx_new ();
    assert (self->tuples);

#ifdef CZMQ_BUILD_DRAFT_API
    self->zap_domain = strdup(CZMQ_ZGOSSIP_ZAP_DOMAIN);
#endif
    return 0;
}
示例#14
0
文件: zhashx.c 项目: claws/czmq
void
zhashx_comment (zhashx_t *self, const char *format, ...)
{
    if (format) {
        if (!self->comments) {
            self->comments = zlistx_new ();
            if (!self->comments)
                return;
            zlistx_set_destructor (self->comments, (czmq_destructor *) zstr_free);
        }
        va_list argptr;
        va_start (argptr, format);
        char *string = zsys_vprintf (format, argptr);
        va_end (argptr);
        if (string)
            zlistx_add_end (self->comments, string);
    }
    else
        zlistx_destroy (&self->comments);
}
示例#15
0
static twps_server_t *twps_new(bool verbose, bool proxy_log) {
    zsys_info("twps: TWPS is initializing.");
    twps_server_t *self = (twps_server_t *) calloc(1, sizeof(twps_server_t));
    self->verbose = verbose;
    self->ticket_printers = zlistx_new();
    self->ticket_store = zactor_new(ticket_store, NULL);
    self->printer_store = zactor_new(printer_store, NULL);
    self->client_proxy = zactor_new(client_proxy, NULL);
    zsys_info("twps: actors created.");
    if (verbose) {
        zstr_send(self->ticket_store, "VERBOSE");
        zstr_send(self->printer_store, "VERBOSE");
    }
    if (proxy_log)
        zstr_send(self->client_proxy, "VERBOSE");
    zstr_sendx(self->ticket_store, "START", TICKET_STORE_REP_ENDPOINT, TICKET_STORE_PUB_ENDPOINT, NULL);
    zsock_wait(self->ticket_store);
    zsys_info("twps: ticket store started listening on %s and publishing on %s", TICKET_STORE_REP_ENDPOINT,
              TICKET_STORE_PUB_ENDPOINT);
    zstr_sendx(self->printer_store, "START", PRINTER_STORE_REP_ENDPOINT, PRINTER_STORE_PUB_ENDPOINT, NULL);
    zsock_wait(self->printer_store);
    zsys_info("twps: printer store started listening on %s and publishing on %s", PRINTER_STORE_REP_ENDPOINT,
              PRINTER_STORE_PUB_ENDPOINT);
    zstr_sendx(self->client_proxy, "START", CLIENT_PROXY_ROUTE_ENDPOINT, CLIENT_PROXY_PUB_ENDPOINT, NULL);
    zsock_wait(self->client_proxy);
    zsys_info("twps: client proxy started listening on %s and publishing on %s", CLIENT_PROXY_ROUTE_ENDPOINT,
              CLIENT_PROXY_PUB_ENDPOINT);

    zstr_sendx(self->client_proxy, "SETTICKETSTORE", TICKET_STORE_REP_ENDPOINT, TICKET_STORE_PUB_ENDPOINT, NULL);
    zsock_wait(self->client_proxy);
    zstr_sendx(self->client_proxy, "SETPRINTERSTORE", PRINTER_STORE_REP_ENDPOINT, PRINTER_STORE_PUB_ENDPOINT, NULL);
    zsock_wait(self->client_proxy);
    self->printer_store_sub = zsock_new_sub(PRINTER_STORE_PUB_ENDPOINT, "");
    zsys_info("twps: initialized with ticket store, printer store and client proxy");
    zsys_info("twps: scanning for printers");
    zstr_send(self->printer_store,"SCANPRINTERS");
    return self;
}
示例#16
0
文件: zhashx.c 项目: claws/czmq
zlistx_t *zhashx_values(zhashx_t *self) {
    assert(self);
    zlistx_t *values = zlistx_new ();
    if (!values)
        return NULL;

    zlistx_set_destructor (values, self->destructor);
    zlistx_set_duplicator (values, self->duplicator);

    uint index;
    size_t limit = primes [self->prime_index];
    for (index = 0; index < limit; index++) {
        item_t *item = self->items [index];
        while (item) {
            if (zlistx_add_end (values, (void *) item->value) == NULL) {
                zlistx_destroy (&values);
                return NULL;
            }
            item = item->next;
        }
     }

    return values;
}
示例#17
0
文件: zlistx.c 项目: AxelVoitier/czmq
void
zlistx_test (bool verbose)
{
    printf (" * zlistx: ");

    //  @selftest
    zlistx_t *list = zlistx_new ();
    assert (list);
    assert (zlistx_size (list) == 0);

    //  Test operations on an empty list
    assert (zlistx_first (list) == NULL);
    assert (zlistx_last (list) == NULL);
    assert (zlistx_next (list) == NULL);
    assert (zlistx_prev (list) == NULL);
    assert (zlistx_find (list, "hello") == NULL);
    assert (zlistx_delete (list, NULL) == -1);
    assert (zlistx_detach (list, NULL) == NULL);
    assert (zlistx_delete (list, NULL) == -1);
    assert (zlistx_detach (list, NULL) == NULL);
    zlistx_purge (list);
    zlistx_sort (list);

    //  Use item handlers
    zlistx_set_destructor (list, (zlistx_destructor_fn *) zstr_free);
    zlistx_set_duplicator (list, (zlistx_duplicator_fn *) strdup);
    zlistx_set_comparator (list, (zlistx_comparator_fn *) strcmp);

    //  Try simple insert/sort/delete/next
    assert (zlistx_next (list) == NULL);
    zlistx_add_end (list, "world");
    assert (streq ((char *) zlistx_next (list), "world"));
    zlistx_add_end (list, "hello");
    assert (streq ((char *) zlistx_prev (list), "hello"));
    zlistx_sort (list);
    assert (zlistx_size (list) == 2);
    void *handle = zlistx_find (list, "hello");
    char *item1 = (char *) zlistx_item (list);
    char *item2 = (char *) zlistx_handle_item (handle);
    assert (item1 == item2);
    assert (streq (item1, "hello"));
    zlistx_delete (list, handle);
    assert (zlistx_size (list) == 1);
    char *string = (char *) zlistx_detach (list, NULL);
    assert (streq (string, "world"));
    free (string);
    assert (zlistx_size (list) == 0);

    //  Check next/back work
    //  Now populate the list with items
    zlistx_add_start (list, "five");
    zlistx_add_end   (list, "six");
    zlistx_add_start (list, "four");
    zlistx_add_end   (list, "seven");
    zlistx_add_start (list, "three");
    zlistx_add_end   (list, "eight");
    zlistx_add_start (list, "two");
    zlistx_add_end   (list, "nine");
    zlistx_add_start (list, "one");
    zlistx_add_end   (list, "ten");

    //  Test our navigation skills
    assert (zlistx_size (list) == 10);
    assert (streq ((char *) zlistx_last (list), "ten"));
    assert (streq ((char *) zlistx_prev (list), "nine"));
    assert (streq ((char *) zlistx_prev (list), "eight"));
    assert (streq ((char *) zlistx_prev (list), "seven"));
    assert (streq ((char *) zlistx_prev (list), "six"));
    assert (streq ((char *) zlistx_prev (list), "five"));
    assert (streq ((char *) zlistx_first (list), "one"));
    assert (streq ((char *) zlistx_next (list), "two"));
    assert (streq ((char *) zlistx_next (list), "three"));
    assert (streq ((char *) zlistx_next (list), "four"));

    //  Sort by alphabetical order
    zlistx_sort (list);
    assert (streq ((char *) zlistx_first (list), "eight"));
    assert (streq ((char *) zlistx_last (list), "two"));

    //  Moving items around
    handle = zlistx_find (list, "six");
    zlistx_move_start (list, handle);
    assert (streq ((char *) zlistx_first (list), "six"));
    zlistx_move_end (list, handle);
    assert (streq ((char *) zlistx_last (list), "six"));
    zlistx_sort (list);
    assert (streq ((char *) zlistx_last (list), "two"));

    //  Copying a list
    zlistx_t *copy = zlistx_dup (list);
    assert (copy);
    assert (zlistx_size (copy) == 10);
    assert (streq ((char *) zlistx_first (copy), "eight"));
    assert (streq ((char *) zlistx_last (copy), "two"));
    zlistx_destroy (&copy);

    //  Delete items while iterating
    string = (char *) zlistx_first (list);
    assert (streq (string, "eight"));
    string = (char *) zlistx_next (list);
    assert (streq (string, "five"));
    zlistx_delete (list, zlistx_cursor (list));
    string = (char *) zlistx_next (list);
    assert (streq (string, "four"));

    zlistx_purge (list);
    zlistx_destroy (&list);
    //  @end

    printf ("OK\n");
}
示例#18
0
void
mlm_server_test (bool verbose)
{
    printf (" * mlm_server: ");
    if (verbose)
        printf ("\n");

    //  @selftest
    zactor_t *server = zactor_new (mlm_server, "mlm_server_test");
    if (verbose)
        zstr_send (server, "VERBOSE");
    zstr_sendx (server, "BIND", "tcp://127.0.0.1:*", NULL);
    zstr_sendx (server, "PORT", NULL);
    char *command, *port;
    int rc = zstr_recvx (server, &command, &port, NULL);
    assert (rc == 2);
    assert (streq (command, "PORT"));
    assert (strlen (port) > 0 && strlen (port) < 6);
    assert (!streq (port, "-1"));

    zsock_t *reader = zsock_new (ZMQ_DEALER);
    assert (reader);
    zsock_connect (reader, "tcp://127.0.0.1:%s", port);
    zsock_set_rcvtimeo (reader, 500);

    mlm_proto_t *proto = mlm_proto_new ();

    //  Server insists that connection starts properly
    mlm_proto_set_id (proto, MLM_PROTO_STREAM_WRITE);
    mlm_proto_send (proto, reader);
    zclock_sleep (500); //  to calm things down && make memcheck pass. Thanks @malanka
    mlm_proto_recv (proto, reader);
    zclock_sleep (500); //  detto as above
    assert (mlm_proto_id (proto) == MLM_PROTO_ERROR);
    assert (mlm_proto_status_code (proto) == MLM_PROTO_COMMAND_INVALID);

    //  Now do a stream publish-subscribe test
    zsock_t *writer = zsock_new (ZMQ_DEALER);
    assert (writer);
    zsock_connect (writer, "tcp://127.0.0.1:%s", port);
    zsock_set_rcvtimeo (reader, 500);

    //  Open connections from both reader and writer
    mlm_proto_set_id (proto, MLM_PROTO_CONNECTION_OPEN);
    mlm_proto_send (proto, reader);
    mlm_proto_recv (proto, reader);
    assert (mlm_proto_id (proto) == MLM_PROTO_OK);

    mlm_proto_set_id (proto, MLM_PROTO_CONNECTION_OPEN);
    mlm_proto_send (proto, writer);
    mlm_proto_recv (proto, writer);
    assert (mlm_proto_id (proto) == MLM_PROTO_OK);

    //  Prepare to write and read a "weather" stream
    mlm_proto_set_id (proto, MLM_PROTO_STREAM_WRITE);
    mlm_proto_set_stream (proto, "weather");
    mlm_proto_send (proto, writer);
    mlm_proto_recv (proto, writer);
    assert (mlm_proto_id (proto) == MLM_PROTO_OK);

    mlm_proto_set_id (proto, MLM_PROTO_STREAM_READ);
    mlm_proto_set_pattern (proto, "temp.*");
    mlm_proto_send (proto, reader);
    mlm_proto_recv (proto, reader);
    assert (mlm_proto_id (proto) == MLM_PROTO_OK);

    //  Now send some weather data, with null contents
    mlm_proto_set_id (proto, MLM_PROTO_STREAM_SEND);
    mlm_proto_set_subject (proto, "temp.moscow");
    mlm_proto_send (proto, writer);
    mlm_proto_set_subject (proto, "rain.moscow");
    mlm_proto_send (proto, writer);
    mlm_proto_set_subject (proto, "temp.chicago");
    mlm_proto_send (proto, writer);
    mlm_proto_set_subject (proto, "rain.chicago");
    mlm_proto_send (proto, writer);
    mlm_proto_set_subject (proto, "temp.london");
    mlm_proto_send (proto, writer);
    mlm_proto_set_subject (proto, "rain.london");
    mlm_proto_send (proto, writer);

    //  We should receive exactly three deliveries, in order
    mlm_proto_recv (proto, reader);
    assert (mlm_proto_id (proto) == MLM_PROTO_STREAM_DELIVER);
    assert (streq (mlm_proto_subject (proto), "temp.moscow"));

    mlm_proto_recv (proto, reader);
    assert (mlm_proto_id (proto) == MLM_PROTO_STREAM_DELIVER);
    assert (streq (mlm_proto_subject (proto), "temp.chicago"));

    mlm_proto_recv (proto, reader);
    assert (mlm_proto_id (proto) == MLM_PROTO_STREAM_DELIVER);
    assert (streq (mlm_proto_subject (proto), "temp.london"));

    mlm_proto_destroy (&proto);

    //  Finished, we can clean up
    zsock_destroy (&writer);
    zsock_destroy (&reader);
    zactor_destroy (&server);
    zstr_free (&port);
    zstr_free (&command);

    // Test Case:
    //      CLIENTLIST command
    {
        const char *endpoint = "inproc://mlm_server_clientlist_test";
        zactor_t *server = zactor_new (mlm_server, "mlm_server_clientlist_test");
        if (verbose)
            zstr_send (server, "VERBOSE");
        zstr_sendx (server, "BIND", endpoint, NULL);

        mlm_client_t *client_1 = mlm_client_new ();
        int rv = mlm_client_connect (client_1, endpoint, 1000, "Karol");
        assert (rv >= 0);

        mlm_client_t *client_2 = mlm_client_new ();
        rv = mlm_client_connect (client_2, endpoint, 1000, "Tomas");
        assert (rv >= 0);

        mlm_client_t *client_3 = mlm_client_new ();
        rv = mlm_client_connect (client_3, endpoint, 1000, "Alenka");
        assert (rv >= 0);

        zclock_sleep (500);

        zstr_sendx (server, "CLIENTLIST", NULL);

        zmsg_t *message = zmsg_recv (server);
        assert (message);
        assert (zmsg_size (message) == 4);

        char *pop = zmsg_popstr (message);
        assert (streq (pop, "CLIENTLIST"));
        zstr_free (&pop);

        zlistx_t *expected_names = zlistx_new ();
        assert (expected_names);
        zlistx_set_destructor (expected_names, (czmq_destructor *) zstr_free);
        zlistx_set_duplicator (expected_names, (czmq_duplicator *) strdup);
        zlistx_set_comparator (expected_names, (czmq_comparator *) strcmp);

        zlistx_add_end (expected_names, (void *) "Karol");
        zlistx_add_end (expected_names, (void *) "Tomas");
        zlistx_add_end (expected_names, (void *) "Alenka");

        pop = zmsg_popstr (message);
        assert (pop);
        void *handle = zlistx_find (expected_names, pop);
        assert (handle);
        rv = zlistx_delete (expected_names, handle);
        assert (rv == 0);
        zstr_free (&pop);

        pop = zmsg_popstr (message);
        assert (pop);
        handle = zlistx_find (expected_names, pop);
        assert (handle);
        rv = zlistx_delete (expected_names, handle);
        assert (rv == 0);
        zstr_free (&pop);

        pop = zmsg_popstr (message);
        assert (pop);
        handle = zlistx_find (expected_names, pop);
        assert (handle);
        rv = zlistx_delete (expected_names, handle);
        assert (rv == 0);
        zstr_free (&pop);

        pop = zmsg_popstr (message);
        assert (pop == NULL);
        assert (zlistx_size (expected_names) == 0);


        zmsg_destroy (&message);

        // remove a client Karol
        mlm_client_destroy (&client_1);

        zlistx_add_end (expected_names, (void *) "Tomas");
        zlistx_add_end (expected_names, (void *) "Alenka");

        zstr_sendx (server, "CLIENTLIST", NULL);
        zclock_sleep (100);

        message = zmsg_recv (server);
        assert (message);
        assert (zmsg_size (message) == 3);

        pop = zmsg_popstr (message);
        assert (streq (pop, "CLIENTLIST"));
        zstr_free (&pop);

        pop = zmsg_popstr (message);
        assert (pop);
        handle = zlistx_find (expected_names, pop);
        assert (handle);
        rv = zlistx_delete (expected_names, handle);
        assert (rv == 0);
        zstr_free (&pop);

        pop = zmsg_popstr (message);
        assert (pop);
        handle = zlistx_find (expected_names, pop);
        assert (handle);
        rv = zlistx_delete (expected_names, handle);
        assert (rv == 0);
        zstr_free (&pop);

        pop = zmsg_popstr (message);
        assert (pop == NULL);
        assert (zlistx_size (expected_names) == 0);

        zlistx_destroy (&expected_names);
        zmsg_destroy (&message);

        mlm_client_destroy (&client_2);
        mlm_client_destroy (&client_3);
        zactor_destroy (&server);
    }

    // Test Case:
    //      STREAMLIST command
    {
        const char *endpoint = "inproc://mlm_server_streamlist_test";
        zactor_t *server = zactor_new (mlm_server, "mlm_server_streamlist_test");
        if (verbose)
            zstr_send (server, "VERBOSE");
        zstr_sendx (server, "BIND", endpoint, NULL);

        mlm_client_t *client_1 = mlm_client_new ();
        int rv = mlm_client_connect (client_1, endpoint, 1000, "Karol");
        assert (rv != -1);
        rv = mlm_client_set_producer (client_1, "STREAM_1");
        assert (rv != -1);

        mlm_client_t *client_2 = mlm_client_new ();
        rv = mlm_client_connect (client_2, endpoint, 1000, "Tomas");
        assert (rv != -1);
        rv = mlm_client_set_producer (client_2, "STREAM_2");
        assert (rv != -1);

        mlm_client_t *client_3 = mlm_client_new ();
        rv = mlm_client_connect (client_3, endpoint, 1000, "Alenka");
        assert (rv != -1);
        rv = mlm_client_set_consumer (client_3, "STREAM_2", ".*");
        assert (rv != -1);

        zclock_sleep (100);

        zlistx_t *expected_streams = zlistx_new ();
        assert (expected_streams);
        zlistx_set_destructor (expected_streams, (czmq_destructor *) zstr_free);
        zlistx_set_duplicator (expected_streams, (czmq_duplicator *) strdup);
        zlistx_set_comparator (expected_streams, (czmq_comparator *) strcmp);

        zlistx_add_end (expected_streams, (void *) "STREAM_1");
        zlistx_add_end (expected_streams, (void *) "STREAM_2");

        zstr_sendx (server, "STREAMLIST", NULL);

        zmsg_t *message = zmsg_recv (server);
        assert (message);
        assert (zmsg_size (message) == 3);

        char *pop = zmsg_popstr (message);
        assert (streq (pop, "STREAMLIST"));
        zstr_free (&pop);

        pop = zmsg_popstr (message);
        assert (pop);
        void *handle = zlistx_find (expected_streams, pop);
        assert (handle);
        rv = zlistx_delete (expected_streams, handle);
        assert (rv == 0);
        zstr_free (&pop);

        pop = zmsg_popstr (message);
        assert (pop);
        handle = zlistx_find (expected_streams, pop);
        assert (handle);
        rv = zlistx_delete (expected_streams, handle);
        assert (rv == 0);
        zstr_free (&pop);

        pop = zmsg_popstr (message);
        assert (pop == NULL);
        assert (zlistx_size (expected_streams) == 0);

        zmsg_destroy (&message);

        //  NOTE: Currently when producer disconnects, malamute does not destroy the stream
        //  Therefore it doesn't make sense to test removal of streams, but addition
        mlm_client_t *client_4 = mlm_client_new ();
        rv = mlm_client_connect (client_4, endpoint, 1000, "Michal");
        assert (rv >= 0);
        rv = mlm_client_set_producer (client_4, "New stream");
        assert (rv >= 0);

        zlistx_add_end (expected_streams, (void *) "STREAM_1");
        zlistx_add_end (expected_streams, (void *) "STREAM_2");
        zlistx_add_end (expected_streams, (void *) "New stream");
        zclock_sleep (100);

        zstr_sendx (server, "STREAMLIST", NULL);
        zclock_sleep (100);

        message = zmsg_recv (server);
        assert (message);
        assert (zmsg_size (message) == 4);

        pop = zmsg_popstr (message);
        assert (streq (pop, "STREAMLIST"));
        zstr_free (&pop);

        pop = zmsg_popstr (message);
        assert (pop);
        handle = zlistx_find (expected_streams, pop);
        assert (handle);
        rv = zlistx_delete (expected_streams, handle);
        assert (rv == 0);
        zstr_free (&pop);

        pop = zmsg_popstr (message);
        assert (pop);
        handle = zlistx_find (expected_streams, pop);
        assert (handle);
        rv = zlistx_delete (expected_streams, handle);
        assert (rv == 0);
        zstr_free (&pop);

        pop = zmsg_popstr (message);
        assert (pop);
        handle = zlistx_find (expected_streams, pop);
        assert (handle);
        rv = zlistx_delete (expected_streams, handle);
        assert (rv == 0);
        zstr_free (&pop);

        pop = zmsg_popstr (message);
        assert (pop == NULL);
        assert (zlistx_size (expected_streams) == 0);

        zlistx_destroy (&expected_streams);
        zmsg_destroy (&message);

        mlm_client_destroy (&client_1);
        mlm_client_destroy (&client_2);
        mlm_client_destroy (&client_3);
        mlm_client_destroy (&client_4);
        zactor_destroy (&server);
    }

    // Regression Test Case:
    //      Segfault from deregistering zombie connection
    {
        const char *endpoint = "inproc://mlm_server_deregister_zombie_connection_test";
        zactor_t *server = zactor_new (mlm_server, "mlm_server_deregister_zombie_connection_test");
        if (verbose)
            zstr_send (server, "VERBOSE");
        zstr_sendx (server, "BIND", endpoint, NULL);
        zstr_sendx (server, "SET", "server/timeout", "3000", NULL); // 3 second client timeout

        zsock_t *reader = zsock_new (ZMQ_DEALER);
        assert (reader);
        zsock_connect (reader, "inproc://mlm_server_deregister_zombie_connection_test");
        zsock_set_rcvtimeo (reader, 500);

        mlm_proto_t *proto = mlm_proto_new ();

        // If the malamute server is restarted and clients have queued
        // up ping messages, the'll be sent before any
        // CONNECTION_OPEN.  The server eventually tries to deregister
        // this and (previously) would derefence a null pointer for
        // the client address.
        mlm_proto_set_id (proto, MLM_PROTO_CONNECTION_PING);
        mlm_proto_send (proto, reader);

        printf("Regression test for segfault due to leftover client messages after restart...\n");
        // Give the server more than 3 seconds to time out the client...
        zclock_sleep (3100);
        printf("passed\n");

        mlm_proto_destroy (&proto);
        zsock_destroy (&reader);
        zactor_destroy (&server);
    }

    {
        const char *endpoint = "inproc://mlm_server_disconnect_pending_stream_traffic";
        zactor_t *server = zactor_new (mlm_server, "mlm_server_disconnect_pending_stream_traffic");
        if (verbose) {
            zstr_send (server, "VERBOSE");
            printf("Regression test for use-after-free with pending stream traffic after disconnect\n");
        }
        zstr_sendx (server, "BIND", endpoint, NULL);

        mlm_client_t *producer = mlm_client_new ();
        assert (mlm_client_connect (producer, endpoint, 1000, "producer") >= 0);
        assert (mlm_client_set_producer (producer, "STREAM_TEST") >= 0);

        zstr_sendx (server, "SLOW_TEST_MODE", NULL);

        mlm_client_t *consumer = mlm_client_new ();
        assert (mlm_client_connect (consumer, endpoint, 1000, "consumer") >= 0);
        assert (mlm_client_set_consumer (consumer, "STREAM_TEST", ".*") >= 0);

        zmsg_t *msg = zmsg_new ();
        zmsg_addstr (msg, "world");
        assert (mlm_client_send (producer, "hello", &msg) >= 0);

        mlm_client_destroy (&consumer);

        zclock_sleep (2000);

        mlm_client_destroy (&producer);
        zactor_destroy (&server);
    }

    //  @end
    printf ("OK\n");
}
示例#19
0
static int
client_initialize (client_t *self)
{
    self->readers = zlistx_new ();
    return 0;
}
示例#20
0
static void handler (zsock_t *pipe, void *args) {
    curl_global_init(CURL_GLOBAL_ALL);
    CURLM *multi = curl_multi_init ();
    CURLSH *share = curl_share_init ();
    curl_share_setopt (share, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
    curl_share_setopt (share, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION);
    curl_share_setopt (share, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT);

    long verbose = (*(bool *) args) ? 1L : 0L;
    long timeout = 30;
    CURLMcode code;

    SOCKET pipefd = zsock_fd (pipe);
    struct curl_waitfd waitfd = {pipefd, CURL_WAIT_POLLIN};

    //  List to hold pending curl handles, in case we are destroy the client
    //  while request are inprogress
    zlistx_t *pending_handles = zlistx_new ();
    zlistx_set_destructor (pending_handles, (zlistx_destructor_fn *) curl_destructor);

    zsock_signal (pipe, 0);

    bool terminated = false;
    while (!terminated) {
        int events = zsock_events (pipe);
        if ((events & ZMQ_POLLIN) == 0) {
            code = curl_multi_wait (multi, &waitfd, 1, 1000, NULL);
            assert (code == CURLM_OK);
        }

        events = zsock_events (pipe);
        if (events & ZMQ_POLLIN) {
            char* command = zstr_recv (pipe);
            if (!command)
                break;          //  Interrupted

            //  All actors must handle $TERM in this way
            if (streq (command, "$TERM"))
                terminated = true;
            else if (streq (command, "GET")) {
                char *url;
                zlistx_t *headers;
                void *userp;
                int rc = zsock_recv (pipe, "slp", &url, &headers, &userp);
                assert (rc == 0);

                zchunk_t *data = zchunk_new (NULL, 100);
                assert (data);
                struct curl_slist *curl_headers = zlistx_to_slist (headers);
                CURL *curl = curl_easy_init ();
                zlistx_add_end (pending_handles, curl);
                http_request *request = (http_request *) zmalloc (sizeof (http_request));
                assert (request);
                request->userp = userp;
                request->curl = curl;
                request->data = data;
                request->headers = curl_headers;

                curl_easy_setopt (curl, CURLOPT_SHARE, share);
                curl_easy_setopt (curl, CURLOPT_TIMEOUT, timeout);
                curl_easy_setopt (curl, CURLOPT_VERBOSE, verbose);
                curl_easy_setopt (curl, CURLOPT_HTTPHEADER, curl_headers);
                curl_easy_setopt (curl, CURLOPT_URL, url);
                curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, write_data);
                curl_easy_setopt (curl, CURLOPT_WRITEDATA, data);
                curl_easy_setopt (curl, CURLOPT_PRIVATE, request);

                code = curl_multi_add_handle (multi, curl);
                assert (code == CURLM_OK);
                zlistx_destroy (&headers);
                zstr_free (&url);
           }
           else {
               puts ("E: invalid message to actor");
               assert (false);
           }
           zstr_free (&command);
        }

        int still_running;
        code = curl_multi_perform (multi, &still_running);
        assert (code == CURLM_OK);

        int msgq = 0;
        struct CURLMsg *msg = curl_multi_info_read(multi, &msgq);

        while (msg) {
            if(msg->msg == CURLMSG_DONE) {
                CURL *curl = msg->easy_handle;
                http_request *request;
                curl_easy_getinfo(curl, CURLINFO_PRIVATE, &request);

                long response_code_long;
                curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &response_code_long);
                int response_code = (int)response_code_long;

                int rc = zsock_send (pipe, "icp", response_code, request->data, request->userp);
                assert (rc == 0);

                curl_multi_remove_handle (multi, curl);

                //  Remove curl from the pending handles and delete it
                void *handle = zlistx_find (pending_handles, curl);
                assert (handle);
                rc = zlistx_delete (pending_handles, handle);
                assert (rc == 0);
            }

            msg = curl_multi_info_read(multi, &msgq);
        }
    }

    zlistx_destroy (&pending_handles);
    curl_share_cleanup (share);
    curl_multi_cleanup (multi);
    curl_global_cleanup ();
}
示例#21
0
void
zhttp_client_test (bool verbose) {
#if defined(HAVE_LIBCURL) && defined(ZMQ_STREAM)
    printf (" * zhttp_client: ");
    zsock_t *server = zsock_new_stream (NULL);
    int port = zsock_bind (server, "tcp://127.0.0.1:*");
    char url[255];
    sprintf (url, "http://127.0.0.1:%d", port);

    //  @selftest
    //  Simple create/destroy test
    zhttp_client_t *self = zhttp_client_new (verbose);
    assert (self);

    //  Send the get request
    bool event = false;
    zlistx_t *headers = zlistx_new ();
    zlistx_add_end (headers, "Host: zeromq.org");
    zhttp_client_get (self, url, headers, -1, test_handler, &event);
    zlistx_destroy (&headers);

    //  Receive request on the server
    zchunk_t *routing_id = recv_http_request (server);

    //  Send the response
    char* response = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\nHello";
    zsock_send (server, "cs", routing_id, response);
    zchunk_destroy (&routing_id);

    //  Receive the response on the http client
    int rc = zhttp_client_wait (self, -1);
    assert (rc == 0);
    zhttp_client_execute (self);
    assert (event);

    // Send a POST request
    event = false;
    zchunk_t *body = zchunk_new ("World", 5);
    zhttp_client_post (self, url, NULL, body, -1, test_handler, &event);

    //  Receive request on the server
    routing_id = recv_http_request (server);

    //  Send the response
    zsock_send (server, "cs", routing_id, response);
    zchunk_destroy (&routing_id);

    //  Receive the response on the http client
    rc = zhttp_client_wait (self, -1);
    assert (rc == 0);
    zhttp_client_execute (self);
    assert (event);

    //  Timeout check
    event = false;
    zhttp_client_get (self, url, NULL, 1000, test_handler, &event);
    rc = zhttp_client_wait (self, 1200);
    assert (rc == 0);
    zhttp_client_execute (self);
    assert (event);

    //  Sending another request, without being answer
    //  Checking the client ability to stop while request are inprogres
    zhttp_client_get (self, url, NULL, -1, test_handler, NULL);

    zchunk_destroy (&body);
    zhttp_client_destroy (&self);
    zsock_destroy (&server);

    //  @end
    printf ("OK\n");
#endif
}
示例#22
0
///
//  Create a new, empty list.
QZlistx::QZlistx (QObject *qObjParent) : QObject (qObjParent)
{
    this->self = zlistx_new ();
}