static int
maybe_raise(pycbc_HttpResult *htres)
{
    if (htres->htflags & PYCBC_HTRES_F_QUIET) {
        return 0;
    }
    if (pycbc_httpresult_ok(htres)) {
        return 0;
    }


    PYCBC_EXC_WRAP_EX(htres->rc ? PYCBC_EXC_LCBERR : PYCBC_EXC_HTTP,
                      htres->rc,
                      "HTTP Request failed. Examine 'objextra' for "
                      "full result",
                      htres->key,
                      (PyObject*)htres);

    return 1;
}
int
pycbc_tc_encode_value(pycbc_Bucket *conn,
                       PyObject **value,
                       PyObject *flag_v,
                       void **buf,
                       size_t *nbuf,
                       lcb_uint32_t *flags)
{
    PyObject *flags_obj;
    PyObject *orig_value;
    PyObject *new_value = NULL;
    PyObject *result_tuple = NULL;
    lcb_uint32_t flags_stackval;
    int rv;
    Py_ssize_t plen;

    orig_value = *value;

    if (!flag_v) {
        flag_v = conn->dfl_fmt;
    }

    if (!conn->tc) {

        if (flag_v == pycbc_helpers.fmt_auto) {
            flag_v = pycbc_tc_determine_format(*value);
        }

        rv = pycbc_get_u32(flag_v, &flags_stackval);
        if (rv < 0) {
            PYCBC_EXC_WRAP_OBJ(PYCBC_EXC_ARGUMENTS, 0,
                               "Bad value for flags",
                               flag_v);
            return -1;
        }

        *flags = flags_stackval;
        return encode_common(value, buf, nbuf, flags_stackval);
    }

    /**
     * Calling into Transcoder
     */

    rv = do_call_tc(conn, orig_value, flag_v, &result_tuple, ENCODE_VALUE);
    if (rv < 0) {
        return -1;
    }

    if (!PyTuple_Check(result_tuple) || PyTuple_GET_SIZE(result_tuple) != 2) {
        PYCBC_EXC_WRAP_EX(PYCBC_EXC_ENCODING, 0,
                          "Expected return of (bytes, flags)",
                          orig_value,
                          result_tuple);

        Py_XDECREF(result_tuple);
        return -1;

    }

    new_value = PyTuple_GET_ITEM(result_tuple, 0);
    flags_obj = PyTuple_GET_ITEM(result_tuple, 1);

    if (new_value == NULL || flags_obj == NULL) {
        PYCBC_EXC_WRAP_OBJ(PYCBC_EXC_INTERNAL, 0, "Tuple GET_ITEM had NULL",
                           result_tuple);

        Py_XDECREF(result_tuple);
        return -1;
    }

    rv = pycbc_get_u32(flags_obj, &flags_stackval);
    if (rv < 0) {
        Py_XDECREF(result_tuple);
        PYCBC_EXC_WRAP_VALUE(PYCBC_EXC_ENCODING, 0,
                             "Transcoder.encode_value() returned a bad "
                             "value for flags", orig_value);
        return -1;
    }

    *flags = flags_stackval;
    rv = PyBytes_AsStringAndSize(new_value, (char**)buf, &plen);
    if (rv == -1) {
        Py_XDECREF(result_tuple);

        PYCBC_EXC_WRAP_VALUE(PYCBC_EXC_ENCODING, 0,
                             "Value returned by Transcoder.encode_value() "
                             "could not be converted to bytes",
                orig_value);
        return -1;
    }

    *value = new_value;
    *nbuf = plen;

    Py_INCREF(new_value);
    Py_XDECREF(result_tuple);

    return 0;
}
Beispiel #3
0
PyObject *
pycbc_Connection__http_request(pycbc_Connection *self,
                               PyObject *args,
                               PyObject *kwargs)
{
    int rv;
    int method;
    int reqtype;
    int quiet = 0;
    unsigned short value_format = 0;
    lcb_error_t err;

    const char *body = NULL;
    PyObject *ret = NULL;
    PyObject *quiet_O = NULL;
    PyObject *fetch_headers_O = Py_False;
    pycbc_strlen_t nbody = 0;
    const char *path = NULL;
    const char *content_type = NULL;
    pycbc_HttpResult *htres;

    lcb_http_request_t htreq = NULL;
    lcb_http_cmd_t htcmd = { 0 };

    static char *kwlist[] = {
            "type", "method", "path", "content_type", "post_data",
            "response_format", "quiet", "fetch_headers", NULL
    };

    rv = PyArg_ParseTupleAndKeywords(args, kwargs,
                                     "iis|zz#HOO", kwlist,
                                     &reqtype,
                                     &method,
                                     &path,
                                     &content_type,
                                     &body,
                                     &nbody,
                                     &value_format,
                                     &quiet_O,
                                     &fetch_headers_O);
    if (!rv) {
        PYCBC_EXCTHROW_ARGS();
        return NULL;
    }
    if (quiet_O != NULL) {
        if (quiet_O == Py_None) {
            quiet = 0;
        } else {
            quiet = PyObject_IsTrue(quiet_O);
        }
    }

    htres = pycbc_httpresult_new(self);
    htres->key = pycbc_SimpleStringZ(path);
    htres->format = value_format;

    if (fetch_headers_O && PyObject_IsTrue(fetch_headers_O)) {
        htres->headers = PyDict_New();
    }

    htcmd.v.v1.body = body;
    htcmd.v.v1.nbody = nbody;
    htcmd.v.v1.content_type = content_type;
    htcmd.v.v1.path = path;
    htcmd.v.v1.npath = strlen(path);
    htcmd.v.v1.method = method;


    err = lcb_make_http_request(self->instance,
                                htres,
                                reqtype,
                                &htcmd,
                                &htreq);

    if (err != LCB_SUCCESS) {
        PYCBC_EXCTHROW_SCHED(err);
        goto GT_DONE;
    }

    err = pycbc_oputil_wait_common(self);

    if (err != LCB_SUCCESS) {
        PYCBC_EXCTHROW_WAIT(err);
        goto GT_DONE;
    }

    if (quiet == 0 && pycbc_httpresult_ok(htres) == 0) {
        PYCBC_EXC_WRAP_EX(htres->rc ? PYCBC_EXC_LCBERR : PYCBC_EXC_HTTP,
                          htres->rc,
                          "HTTP Request failed. Examine 'objextra' for "
                          "full result",
                          htres->key,
                          (PyObject*)htres);
        goto GT_DONE;
    }

    ret = (PyObject*)htres;
    htres = NULL;

    GT_DONE:
    Py_XDECREF(htres);
    return ret;
}
int
pycbc_tc_encode_value(pycbc_Bucket *conn, PyObject *srcbuf, PyObject *srcflags,
                      pycbc_pybuffer *dstbuf, lcb_U32 *dstflags)
{
    PyObject *flags_obj;
    PyObject *new_value = NULL;
    PyObject *result_tuple = NULL;
    lcb_U32 flags_stackval;
    int rv;
    Py_ssize_t plen;

    if (!srcflags) {
        srcflags = conn->dfl_fmt;
    }

    if (!conn->tc) {
        if (srcflags == pycbc_helpers.fmt_auto) {
            srcflags = pycbc_tc_determine_format(srcbuf);
        }

        rv = pycbc_get_u32(srcflags, &flags_stackval);
        if (rv < 0) {
            PYCBC_EXC_WRAP_OBJ(PYCBC_EXC_ARGUMENTS, 0,
                               "Bad value for flags", srcflags);
            return -1;
        }

        *dstflags = flags_stackval;
        return encode_common(srcbuf, dstbuf, flags_stackval);
    }

    /**
     * Calling into Transcoder
     */
    rv = do_call_tc(conn, srcbuf, srcflags, &result_tuple, ENCODE_VALUE);
    if (rv < 0) {
        return -1;
    }

    if (!PyTuple_Check(result_tuple) || PyTuple_GET_SIZE(result_tuple) != 2) {
        PYCBC_EXC_WRAP_EX(PYCBC_EXC_ENCODING, 0,
                          "Expected return of (bytes, flags)",
                          srcbuf, result_tuple);

        Py_XDECREF(result_tuple);
        return -1;

    }

    new_value = PyTuple_GET_ITEM(result_tuple, 0);
    flags_obj = PyTuple_GET_ITEM(result_tuple, 1);

    if (new_value == NULL || flags_obj == NULL) {
        PYCBC_EXC_WRAP_OBJ(PYCBC_EXC_INTERNAL, 0, "Tuple GET_ITEM had NULL",
                           result_tuple);

        Py_XDECREF(result_tuple);
        return -1;
    }

    rv = pycbc_get_u32(flags_obj, &flags_stackval);
    if (rv < 0) {
        Py_XDECREF(result_tuple);
        PYCBC_EXC_WRAP_VALUE(PYCBC_EXC_ENCODING, 0,
                             "Transcoder.encode_value() returned a bad "
                             "value for flags", srcbuf);
        return -1;
    }

    *dstflags = flags_stackval;
    rv = PyBytes_AsStringAndSize(new_value, (char**)&dstbuf->buffer, &plen);
    if (rv == -1) {
        Py_XDECREF(result_tuple);
        PYCBC_EXC_WRAP_VALUE(PYCBC_EXC_ENCODING, 0,
                             "Value returned by Transcoder.encode_value() "
                             "could not be converted to bytes", srcbuf);
        return -1;
    }

    dstbuf->pyobj = new_value;
    dstbuf->length = plen;

    Py_INCREF(new_value);
    Py_XDECREF(result_tuple);

    return 0;
}