0

I am using pycurl.CurlMulti interface in python3 and I want to use info_read to check for the succeeded and failed connections.

According to the documentation of the c interface curl_multi_info_read of libcurl:

WARNING: The data the returned pointer points to will not survive calling curl_multi_cleanup, curl_multi_remove_handle or curl_easy_cleanup.

However, the documentation of pycurl.CurlMulti does not mention whether the curl error message in the return value of pycurl.CurlMulti.info_read() is valid after a call to curl_multi_remove_handle.

The only way to check this is read the source code of pycurl.

JiaHao Xu
  • 2,452
  • 16
  • 31

1 Answers1

0

I checked the source code for pycurl.CurlMulti.info_read and it shows that:

        /* When an error occurs */
        else {
            /* Create a result tuple that will get added to err_list. */
            PyObject *v = Py_BuildValue("(Ois)", (PyObject *)co, (int)msg->data.result, co->error);
            /* Append curl object to list of objects which failed */
            if (v == NULL || PyList_Append(err_list, v) != 0) {
                Py_XDECREF(v);
                goto error;
            }
            Py_DECREF(v);
        }

where co is retrieved from L781:

        /* Fetch the curl object that corresponds to the curl handle in the message */
        res = curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, (char **) &co);

And CURLINFO_PRIVATE and co->error is set at src/easy.c#L52:

    /* Set curl error buffer and zero it */
    res = curl_easy_setopt(self->handle, CURLOPT_ERRORBUFFER, self->error);
    if (res != CURLE_OK) {
        return (-1);
    }
    memset(self->error, 0, sizeof(self->error));

    /* Set backreference */
    res = curl_easy_setopt(self->handle, CURLOPT_PRIVATE, (char *) self);
    if (res != CURLE_OK) {
        return (-1);
    }

which means that given the pycurl.Curl object is not reused for another connection or destroyed, it should be pretty safe to use the curl error message in the return value of pycurl.CurlMulti.info_read().

This answer gives me another interesting fact:

It is not safe to set CURLOPT_PRIVATE on the pycurl.Curl object.

JiaHao Xu
  • 2,452
  • 16
  • 31