示例#1
0
LIBCOUCHBASE_API
lcb_error_t
lcb_cbflush3(lcb_t instance, const void *cookie, const lcb_CMDBASE *cmd)
{
    lcb_http_request_t htr;
    lcb_CMDHTTP htcmd = { 0 };
    lcb_string urlpath;
    lcb_error_t rc;

    (void)cmd;

    lcb_string_init(&urlpath);
    lcb_string_appendz(&urlpath, "/pools/default/buckets/");
    lcb_string_appendz(&urlpath, LCBT_SETTING(instance, bucket));
    lcb_string_appendz(&urlpath, "/controller/doFlush");


    htcmd.type = LCB_HTTP_TYPE_MANAGEMENT;
    htcmd.method = LCB_HTTP_METHOD_POST;
    htcmd.reqhandle = &htr;
    LCB_CMD_SET_KEY(&htcmd, urlpath.base, urlpath.nused);

    rc = lcb_http3(instance, cookie, &htcmd);
    lcb_string_release(&urlpath);

    if (rc != LCB_SUCCESS) {
        return rc;
    }
    lcb_htreq_setcb(htr, flush_cb);
    return LCB_SUCCESS;
}
示例#2
0
static const char *
mk_scratch_host(lcb_t instance, const lcb_host_t *host)
{
    if (!ensure_scratch(instance, strlen(host->host)+strlen(host->port)+2)) {
        return NULL;
    }
    lcb_string_appendz(instance->scratch, host->host);
    lcb_string_appendz(instance->scratch, ":");
    lcb_string_appendz(instance->scratch, host->port);
    return instance->scratch->base;
}
示例#3
0
static lcb_error_t parse_body(struct htvb_st *vbs, int *done)
{
    lcb_error_t err = LCB_BUSY;
    char *term;


    if ((err = parse_chunk(vbs)) != LCB_SUCCESS) {
        *done = 1; /* no data */
        lcb_assert(err == LCB_BUSY);
        return err;
    }

    if (lcb_string_append(&vbs->input, vbs->chunk.base, vbs->chunk_size)) {
        return LCB_CLIENT_ENOMEM;
    }


    lcb_string_erase_end(&vbs->input, 2);
    lcb_string_erase_beginning(&vbs->chunk, vbs->chunk_size);

    vbs->chunk_size = (lcb_size_t) - 1;

    if (vbs->chunk.nused > 0) {
        *done = 0;
    }

    term = strstr(vbs->input.base, "\n\n\n\n");

    if (term != NULL) {
        lcb_string tmp;
        lcb_error_t ret;

        /** Next input */
        lcb_string_init(&tmp);
        lcb_string_appendz(&tmp, term + 4);

        *term = '\0';
        ret = set_next_config(vbs);

        /** Now, erase everything until the end of the 'term' */
        if (vbs->input.base) {
            lcb_string_release(&vbs->input);
        }

        lcb_string_transfer(&tmp, &vbs->input);
        return ret;
    }


    return err;
}
示例#4
0
static void sanitize_config(
    const lcb_string *src, const char *host, lcb_string *dst)
{
    char *cur = src->base, *last = src->base;

    while ((cur = strstr(cur, HOST_TOKEN))) {
        lcb_string_append(dst, last, cur-last);
        lcb_string_appendz(dst, host);
        cur += sizeof(HOST_TOKEN)-1;
        last = cur;
    }

    lcb_string_append(dst, last, src->base + src->nalloc - last);
}
示例#5
0
/**
 * Try to parse the headers in the input chunk.
 *
 * @param instance the instance containing the data
 * @return 0 success, 1 we need more data, -1 incorrect response
 */
static lcb_error_t parse_header(struct htvb_st *vbs, lcb_type_t btype)
{
    int response_code;
    lcb_string *chunk = &vbs->chunk;
    char *ptr = strstr(chunk->base, "\r\n\r\n");

    if (ptr != NULL) {
        *ptr = '\0';
        ptr += 4;
    } else if ((ptr = strstr(chunk->base, "\n\n")) != NULL) {
        *ptr = '\0';
        ptr += 2;
    } else {
        /* We need more data! */
        return LCB_BUSY;
    }

    /* parse the headers I care about... */
    if (sscanf(chunk->base, "HTTP/1.1 %d", &response_code) != 1) {
        return LCB_PROTOCOL_ERROR;

    } else if (response_code != 200) {
        switch (response_code) {
        case 401:
            return LCB_AUTH_ERROR;
        case 404:
            return LCB_BUCKET_ENOENT;
        default:
            return LCB_PROTOCOL_ERROR;
            break;
        }
    }

    /** TODO: Isn't a vBucket config only for BUCKET types? */
    if (btype == LCB_TYPE_BUCKET &&
            strstr(chunk->base, "Transfer-Encoding: chunked") == NULL &&
            strstr(chunk->base, "Transfer-encoding: chunked") == NULL) {
        return LCB_PROTOCOL_ERROR;
    }

    lcb_string_appendz(&vbs->header, chunk->base);


    /* realign remaining data.. */
    lcb_string_erase_beginning(chunk, ptr-chunk->base);
    vbs->chunk_size = (lcb_size_t) - 1;

    return LCB_SUCCESS;
}
示例#6
0
/**
 * Called to retrive the mechlist from the packet.
 * @return 0 to continue authentication, 1 if no authentication needed, or
 * -1 on error.
 */
static int
set_chosen_mech(mc_pSESSREQ sreq, lcb_string *mechlist, const char **data,
                unsigned int *ndata)
{
    cbsasl_error_t saslerr;
    const char *chosenmech;
    mc_pSESSINFO ctx = sreq->inner;

    lcb_assert(sreq->inner);
    if (ctx->settings->sasl_mech_force) {
        char *forcemech = ctx->settings->sasl_mech_force;
        if (!strstr(mechlist->base, forcemech)) {
            /** Requested mechanism not found */
            set_error_ex(sreq, LCB_SASLMECH_UNAVAILABLE, mechlist->base);
            return -1;
        }

        lcb_string_clear(mechlist);
        if (lcb_string_appendz(mechlist, forcemech)) {
            set_error_ex(sreq, LCB_CLIENT_ENOMEM, NULL);
            return -1;
        }
    }

    saslerr = cbsasl_client_start(ctx->sasl, mechlist->base,
                                  NULL, data, ndata, &chosenmech);
    switch (saslerr) {
    case SASL_OK:
        ctx->nmech = strlen(chosenmech);
        if (! (ctx->mech = strdup(chosenmech)) ) {
            set_error_ex(sreq, LCB_CLIENT_ENOMEM, NULL);
            return -1;
        }
        return 0;
    case SASL_NOMECH:
        lcb_log(LOGARGS(sreq, INFO), SESSREQ_LOGFMT "Server does not support SASL (no mechanisms supported)", SESSREQ_LOGID(sreq));
        return 1;
        break;
    default:
        lcb_log(LOGARGS(sreq, INFO), SESSREQ_LOGFMT "cbsasl_client_start returned %d", SESSREQ_LOGID(sreq), saslerr);
        set_error_ex(sreq, LCB_EINTERNAL, "Couldn't start SASL client");
        return -1;
    }
}
示例#7
0
LIBCOUCHBASE_API
const char *
lcb_get_node(lcb_t instance, lcb_GETNODETYPE type, unsigned ix)
{
    if (type & LCB_NODE_HTCONFIG) {
        if (type & LCB_NODE_CONNECTED) {
            const lcb_host_t *host = lcb_confmon_get_rest_host(instance->confmon);
            if (host) {
                return mk_scratch_host(instance, host);
            } else {
                return return_badhost(type);
            }

        } else {
            /* Retrieve one from the vbucket configuration */
            lcbvb_CONFIG *vbc = LCBT_VBCONFIG(instance);
            lcbvb_SVCMODE mode;
            const char *hp = NULL;
            if (LCBT_SETTING(instance, sslopts) & LCB_SSL_ENABLED) {
                mode = LCBVB_SVCMODE_SSL;
            } else {
                mode = LCBVB_SVCMODE_PLAIN;
            }

            if (instance->type == LCB_TYPE_BUCKET) {
                if (vbc) {
                    ix %= LCBVB_NSERVERS(vbc);
                    hp = lcbvb_get_hostport(vbc, ix, LCBVB_SVCTYPE_MGMT, mode);

                } else if ((type & LCB_NODE_NEVERNULL) == 0) {
                    return NULL;
                }
            }
            if (hp == NULL && instance->ht_nodes && instance->ht_nodes->nentries) {
                ix %= instance->ht_nodes->nentries;
                hostlist_ensure_strlist(instance->ht_nodes);
                hp = instance->ht_nodes->slentries[ix];
            }
            if (!hp) {
                if ((hp = return_badhost(type)) == NULL) {
                    return NULL;
                }
            }
            if (!ensure_scratch(instance, strlen(hp)+1)) {
                return NULL;
            }
            lcb_string_appendz(instance->scratch, hp);
            return instance->scratch->base;
        }
    } else if (type & (LCB_NODE_DATA|LCB_NODE_VIEWS)) {
        const mc_SERVER *server;
        ix %= LCBT_NSERVERS(instance);
        server = LCBT_GET_SERVER(instance, ix);

        if ((type & LCB_NODE_CONNECTED) && server->connctx == NULL) {
            return return_badhost(type);
        }
        if (server->curhost == NULL) {
            return return_badhost(type);
        }

        /* otherwise, return the actual host:port of the server */
        if (type & LCB_NODE_DATA) {
            return mk_scratch_host(instance, server->curhost);
        } else {
            return server->viewshost;
        }
    } else {
        return NULL; /* don't know the type */
    }
}
示例#8
0
lcb_error_t hostlist_add_string(hostlist_t hostlist,
                                const char *spec,
                                int speclen,
                                int deflport)
{
    lcb_error_t err = LCB_SUCCESS;
    lcb_string str;

    char *delim;
    char *curstart;


    if (speclen < 0) {
        speclen = strlen(spec);
    }


    if (lcb_string_init(&str)) {
        return LCB_CLIENT_ENOMEM;
    }

    if (lcb_string_append(&str, spec, speclen)) {
        lcb_string_release(&str);
        return LCB_CLIENT_ENOMEM;
    }

    if (!str.nused) {
        lcb_string_release(&str);
        return LCB_SUCCESS;
    }

    if (str.base[str.nused-1] != ';') {
        if (lcb_string_appendz(&str, ";")) {
            lcb_string_release(&str);
            return LCB_CLIENT_ENOMEM;
        }
    }

    curstart = str.base;
    while ( (delim = strstr(curstart, ";"))) {
        lcb_host_t curhost;
        lcb_size_t curlen;

        if (delim == curstart) {
            curstart++;
            continue;
        }

        /** { 'f', 'o', 'o', ';' } */
        curlen = delim - curstart;

        err = lcb_host_parse(&curhost, curstart, curlen, deflport);
        if (err != LCB_SUCCESS) {
            break;
        }

        err = hostlist_add_host(hostlist, &curhost);
        if (err != LCB_SUCCESS) {
            break;
        }

        curstart = delim + 1;
    }

    lcb_string_release(&str);
    return err;
}