Пример #1
0
static void send_response(wurfld_connection_context *ctx) {
    char *useragent = ctx->useragent;
    DEBUG1("Worker %p is looking up useragent : %s", pthread_self(), useragent);

    // this might be unnecessary if libwurfl is thread-safe
    // XXX - needs to be checked
    wurfld_get_capabilities(useragent, ctx->output);

    if (use_http) {
        char response_header[1024];
        sprintf(response_header, "%s 200 OK\r\n"
                "Content-Type: application/json\r\n"
                "Content-length: %d\r\n"
                "Server: wurfld\r\n"
                "Connection: Close\r\n\r\n",
                ctx->is_http10 ? "HTTP/1.0" : "HTTP/1.1", fbuf_used(ctx->output));

        int err = write_socket(ctx->fd, response_header, strlen(response_header));
        if (err != 0) {
            ERROR("(%p) Can't write the response header : %s", pthread_self(), strerror(errno));
        }
    }

    if (write_socket(ctx->fd, fbuf_data(ctx->output), fbuf_used(ctx->output)) != 0) {
        ERROR("(%p) Can't write the response data : %s", pthread_self(), strerror(errno));
    }
}
Пример #2
0
size_t
shardcache_client_offset(shardcache_client_t *c, void *key, size_t klen, uint32_t offset, void *data, uint32_t dlen)
{
    int fd = -1;
    char *addr = select_node(c, key, klen, &fd);
    if (fd < 0) {
        c->errno = SHARDCACHE_CLIENT_ERROR_NETWORK;
        snprintf(c->errstr, sizeof(c->errstr), "Can't connect to '%s'", addr);
        return 0;
    }

    fbuf_t value = FBUF_STATIC_INITIALIZER;
    int rc = offset_from_peer(addr, (char *)c->auth, SHC_HDR_SIGNATURE_SIP, key, klen, offset, dlen, &value, fd);
    if (rc == 0) {
        uint32_t to_copy = dlen > fbuf_used(&value) ? fbuf_used(&value) : dlen;
        if (data)
            memcpy(data, fbuf_data(&value), to_copy);

        c->errno = SHARDCACHE_CLIENT_OK;
        c->errstr[0] = 0;

        connections_pool_add(c->connections, addr, fd);
        fbuf_destroy(&value);
        return to_copy;
    } else {
        close(fd);
        c->errno = SHARDCACHE_CLIENT_ERROR_NODE;
        snprintf(c->errstr, sizeof(c->errstr), "Can't fetch data from node '%s'", addr);
    }
    fbuf_destroy(&value);
    return 0;
}
Пример #3
0
static void wurfld_input_handler(iomux_t *iomux, int fd, void *data, int len, void *priv) {
    wurfld_connection_context *ctx = (wurfld_connection_context *)priv;
    if (!ctx)
        return;
    DEBUG1("New data on fd %d", fd);
    fbuf_add_binary(ctx->input, data, len);

    if (fbuf_used(ctx->input) < 4)
        return;

    // check if we have a complete requset
    char *current_data = fbuf_end(ctx->input) - (use_http ? 4 : 1);
    char *request_terminator = use_http ? strstr(current_data, "\r\n\r\n") : strstr(current_data, "\n");
    if (!request_terminator && use_http) { // support some broken clients/requests
        request_terminator = strstr(current_data, "\n\n");
    }
    if (request_terminator) {
        // we have a complete request so we can now start 
        // background worker to handle it
        pthread_t worker_thread;
        ctx->fd = fd;
        // let the worker take care of the fd from now on
        iomux_remove(iomux, fd);
        if (single_thread) {
            worker(ctx);
        } else {
            pthread_create(&worker_thread, NULL, worker, ctx);
            pthread_detach(worker_thread);
        }
    }
}
Пример #4
0
size_t
shardcache_client_get(shardcache_client_t *c, void *key, size_t klen, void **data)
{
    int fd = -1;
    char *addr = select_node(c, key, klen, &fd);

    if (fd < 0) {
        c->errno = SHARDCACHE_CLIENT_ERROR_NETWORK;
        snprintf(c->errstr, sizeof(c->errstr), "Can't connect to '%s'", addr);
        return 0;
    }

    fbuf_t value = FBUF_STATIC_INITIALIZER;
    int rc = fetch_from_peer(addr, (char *)c->auth, SHC_HDR_SIGNATURE_SIP, key, klen, &value, fd);
    if (rc == 0) {
        size_t size = fbuf_used(&value);
        if (data)
            *data = fbuf_data(&value);
        else
            fbuf_destroy(&value);

        c->errno = SHARDCACHE_CLIENT_OK;
        c->errstr[0] = 0;

        connections_pool_add(c->connections, addr, fd);
        return size;
    } else {
        close(fd);
        c->errno = SHARDCACHE_CLIENT_ERROR_NODE;
        snprintf(c->errstr, sizeof(c->errstr), "Can't fetch data from node '%s'", addr);
        return 0;
    }
    return 0;
}
Пример #5
0
int
shardcache_client_migration_begin(shardcache_client_t *c, shardcache_node_t **nodes, int num_nodes)
{
    fbuf_t mgb_message = FBUF_STATIC_INITIALIZER;

    int i;
    for (i = 0; i < num_nodes; i++) {
        if (i > 0)
            fbuf_add(&mgb_message, ",");
        fbuf_printf(&mgb_message, "%s:%s", shardcache_node_get_string(nodes[i]));
    }

    for (i = 0; i < c->num_shards; i++) {
        char *addr = shardcache_node_get_address(c->shards[i]);
        int fd = connections_pool_get(c->connections, addr);
        if (fd < 0) {
            c->errno = SHARDCACHE_CLIENT_ERROR_NETWORK;
            snprintf(c->errstr, sizeof(c->errstr), "Can't connect to '%s'", addr);
            fbuf_destroy(&mgb_message);
            return -1;
        }

        int rc = migrate_peer(addr,
                              (char *)c->auth,
                              SHC_HDR_SIGNATURE_SIP,
                              fbuf_data(&mgb_message),
                              fbuf_used(&mgb_message), fd);
        if (rc != 0) {
            close(fd);
            c->errno = SHARDCACHE_CLIENT_ERROR_NODE;
            snprintf(c->errstr, sizeof(c->errstr), "Node '%s' (%s) didn't aknowledge the migration\n",
                    shardcache_node_get_label(c->shards[i]), addr);
            fbuf_destroy(&mgb_message);
            // XXX - should we abort migration on peers that have been notified (if any)?
            return -1;
        }
        connections_pool_add(c->connections, addr, fd);
    }
    fbuf_destroy(&mgb_message);

    c->errno = SHARDCACHE_CLIENT_OK;
    c->errstr[0] = 0;

    return 0;
}