case CURLMSG_DONE:
{
fr_curl_io_request_t *randle;
- request_t *request = NULL;
+ request_t *request = NULL;
CURL *candle = m->easy_handle;
CURLcode ret;
mhandle->transfers--;
ret = curl_easy_getinfo(candle, CURLINFO_PRIVATE, &randle);
+ /*
+ * In curl 7.61 we got bad request data returned
+ * here after cancellations were processed.
+ *
+ * For debug builds if the value is equal to
+ * 0xdeadc341, we know the request was cancelled.
+ *
+ * There is no good work around for this other than
+ * upgrading to a newer version of curl.
+ */
+ talloc_get_type_abort(randle, fr_curl_io_request_t);
if (!fr_cond_assert_msg(ret == CURLE_OK,
"Failed retrieving request data from CURL easy handle (candle)")) {
curl_multi_remove_handle(mandle, candle);
randle->result = m->data.result;
/*
- * Looks like this needs to be done last,
- * else m->data.result ends up being junk.
+ * This needs to be done last, else m->data.result
+ * ends up being junk.
*/
curl_multi_remove_handle(mandle, candle);
* Stick the current request in the curl handle's
* private data. This makes it simple to resume
* the request in the demux function later...
+ *
+ * Note: If you get 0xdeadc341 in the private data
+ * in the demux function, the result for the easy
+ * handle was erroneously delivered after a
+ * cancellation.
*/
ret = curl_easy_setopt(randle->candle, CURLOPT_PRIVATE, randle);
if (ret != CURLE_OK) {
return 0;
}
-static int _mod_conn_free(fr_curl_io_request_t *randle)
-{
- curl_easy_cleanup(randle->candle);
- return 0;
-}
-
/** Cleans up after a REST request.
*
* Resets all options associated with a CURL handle, and frees any headers
* @param[in] randle to cleanup.
* @param[in] uctx unused.
*/
-static int rest_request_cleanup(fr_curl_io_request_t *randle, UNUSED void *uctx)
+static int _rest_request_cleanup(fr_curl_io_request_t *randle, UNUSED void *uctx)
{
rlm_rest_curl_context_t *ctx = talloc_get_type_abort(randle->uctx, rlm_rest_curl_context_t);
CURL *candle = randle->candle;
ctx->headers = NULL;
}
+#ifndef NDEBUG
+ /*
+ * With curl 7.61 when a request in cancelled we get a result
+ * with a NULL (invalid) pointer to private data. This lets
+ * us know that it was request returned to the slab.
+ */
+ curl_easy_setopt(candle, CURLOPT_PRIVATE, (void *)0xdeadc341);
+#endif
+
/*
* Free response data
*/
return 0;
}
+static int _mod_conn_free(fr_curl_io_request_t *randle)
+{
+ curl_easy_cleanup(randle->candle);
+ return 0;
+}
+
static int rest_conn_alloc(fr_curl_io_request_t *randle, void *uctx)
{
rlm_rest_t const *inst = talloc_get_type_abort(uctx, rlm_rest_t);
randle->uctx = curl_ctx;
talloc_set_destructor(randle, _mod_conn_free);
- rest_slab_element_set_destructor(randle, rest_request_cleanup, NULL);
+ rest_slab_element_set_destructor(randle, _rest_request_cleanup, NULL);
return 0;
}