summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfsbs <fsbs@users.noreply.github.com>2021-10-31 04:40:28 +0000
committerfsbs <fsbs@users.noreply.github.com>2021-10-31 05:40:28 +0100
commitfecd18940a1064761929f828e907ecca548706dc (patch)
treea5d524730b552661fc852981351563ba74671495
parente7d8329ad29a046488390a0d4d41e5878104cb75 (diff)
downloadpycurl-fecd18940a1064761929f828e907ecca548706dc.tar.gz
Wrap curl_httppost in a Python object
-rw-r--r--src/easy.c43
-rw-r--r--src/easyopt.c16
-rw-r--r--src/module.c6
-rw-r--r--src/pycurl.h13
4 files changed, 61 insertions, 17 deletions
diff --git a/src/easy.c b/src/easy.c
index 9fd8be9..f9db731 100644
--- a/src/easy.c
+++ b/src/easy.c
@@ -37,6 +37,43 @@ PYCURL_INTERNAL PyTypeObject CurlSlist_Type = {
/*************************************************************************
+// CurlHttppostObject
+**************************************************************************/
+
+PYCURL_INTERNAL void
+util_curlhttppost_update(CurlObject *obj, struct curl_httppost *httppost, PyObject *reflist)
+{
+ /* Decref previous object */
+ Py_XDECREF(obj->httppost);
+ /* Create a new object */
+ obj->httppost = PyObject_New(CurlHttppostObject, p_CurlHttppost_Type);
+ assert(obj->httppost != NULL);
+ /* Store curl_httppost and reflist into the new object */
+ obj->httppost->httppost = httppost;
+ obj->httppost->reflist = reflist;
+}
+
+PYCURL_INTERNAL void
+do_curl_httppost_dealloc(CurlHttppostObject *self) {
+ if (self->httppost != NULL) {
+ curl_formfree(self->httppost);
+ self->httppost = NULL;
+ }
+ Py_CLEAR(self->reflist);
+ Py_TYPE(self)->tp_free((PyObject *) self);
+}
+
+/* TODO: Python 2 compatible */
+PYCURL_INTERNAL PyTypeObject CurlHttppost_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ .tp_name = "pycurl.CurlHttppost",
+ .tp_basicsize = sizeof(CurlHttppostObject),
+ .tp_itemsize = 0,
+ .tp_dealloc = (destructor) do_curl_httppost_dealloc,
+};
+
+
+/*************************************************************************
// static utility functions
**************************************************************************/
@@ -229,8 +266,8 @@ util_curl_xdecref(CurlObject *self, int flags, CURL *handle)
}
if (flags & PYCURL_MEMGROUP_HTTPPOST) {
- /* Decrement refcounts for httppost related references. */
- Py_CLEAR(self->httppost_ref_list);
+ /* Decrement refcounts for httppost object. */
+ Py_CLEAR(self->httppost);
}
if (flags & PYCURL_MEMGROUP_CACERTS) {
@@ -401,6 +438,8 @@ do_curl_traverse(CurlObject *self, visitproc visit, void *arg)
VISIT((PyObject *) self->connect_to);
#endif
+ VISIT((PyObject *) self->httppost);
+
return 0;
#undef VISIT
}
diff --git a/src/easyopt.c b/src/easyopt.c
index 5c6f29e..026eb46 100644
--- a/src/easyopt.c
+++ b/src/easyopt.c
@@ -67,8 +67,7 @@ util_curl_unsetopt(CurlObject *self, int option)
break;
case CURLOPT_HTTPPOST:
SETOPT((void *) 0);
- curl_formfree(self->httppost);
- util_curl_xdecref(self, PYCURL_MEMGROUP_HTTPPOST, self->handle);
+ Py_CLEAR(self->httppost);
self->httppost = NULL;
/* FIXME: what about data->set.httpreq ?? */
break;
@@ -690,16 +689,9 @@ do_curl_setopt_httppost(CurlObject *self, int option, int which, PyObject *obj)
CURLERROR_SET_RETVAL();
goto error;
}
- /* Finally, free previously allocated httppost, ZAP any
- * buffer references, and update */
- curl_formfree(self->httppost);
- util_curl_xdecref(self, PYCURL_MEMGROUP_HTTPPOST, self->handle);
- self->httppost = post;
-
- /* The previous list of INCed references was ZAPed above; save
- * the new one so that we can clean it up on the next
- * self->httppost free. */
- self->httppost_ref_list = ref_params;
+ /* Finally, decref previous httppost object and replace it with a
+ * new one. */
+ util_curlhttppost_update(self, post, ref_params);
Py_RETURN_NONE;
diff --git a/src/module.c b/src/module.c
index 2f40e98..24e8191 100644
--- a/src/module.c
+++ b/src/module.c
@@ -29,6 +29,7 @@ PYCURL_INTERNAL char *g_pycurl_useragent = NULL;
PYCURL_INTERNAL PyObject *ErrorObject = NULL;
PYCURL_INTERNAL PyTypeObject *p_Curl_Type = NULL;
PYCURL_INTERNAL PyTypeObject *p_CurlSlist_Type = NULL;
+PYCURL_INTERNAL PyTypeObject *p_CurlHttppost_Type = NULL;
PYCURL_INTERNAL PyTypeObject *p_CurlMulti_Type = NULL;
PYCURL_INTERNAL PyTypeObject *p_CurlShare_Type = NULL;
#ifdef HAVE_CURL_7_19_6_OPTS
@@ -418,10 +419,12 @@ initpycurl(void)
* is required for portability to Windows without requiring C++. */
p_Curl_Type = &Curl_Type;
p_CurlSlist_Type = &CurlSlist_Type;
+ p_CurlHttppost_Type = &CurlHttppost_Type;
p_CurlMulti_Type = &CurlMulti_Type;
p_CurlShare_Type = &CurlShare_Type;
Py_SET_TYPE(&Curl_Type, &PyType_Type);
Py_SET_TYPE(&CurlSlist_Type, &PyType_Type);
+ Py_SET_TYPE(&CurlHttppost_Type, &PyType_Type);
Py_SET_TYPE(&CurlMulti_Type, &PyType_Type);
Py_SET_TYPE(&CurlShare_Type, &PyType_Type);
@@ -432,6 +435,9 @@ initpycurl(void)
if (PyType_Ready(&CurlSlist_Type) < 0)
goto error;
+ if (PyType_Ready(&CurlHttppost_Type) < 0)
+ goto error;
+
if (PyType_Ready(&CurlMulti_Type) < 0)
goto error;
diff --git a/src/pycurl.h b/src/pycurl.h
index f4f71f6..f5507de 100644
--- a/src/pycurl.h
+++ b/src/pycurl.h
@@ -388,6 +388,13 @@ typedef struct CurlSlistObject {
struct curl_slist *slist;
} CurlSlistObject;
+typedef struct CurlHttppostObject {
+ PyObject_HEAD
+ struct curl_httppost *httppost;
+ /* List of INC'ed references associated with httppost. */
+ PyObject *reflist;
+} CurlHttppostObject;
+
typedef struct CurlObject {
PyObject_HEAD
PyObject *dict; /* Python attributes dictionary */
@@ -399,9 +406,7 @@ typedef struct CurlObject {
#endif
struct CurlMultiObject *multi_stack;
struct CurlShareObject *share;
- struct curl_httppost *httppost;
- /* List of INC'ed references associated with httppost. */
- PyObject *httppost_ref_list;
+ struct CurlHttppostObject *httppost;
struct CurlSlistObject *httpheader;
#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 37, 0)
struct CurlSlistObject *proxyheader;
@@ -627,12 +632,14 @@ ssl_ctx_callback(CURL *curl, void *ssl_ctx, void *ptr);
/* Type objects */
extern PyTypeObject Curl_Type;
extern PyTypeObject CurlSlist_Type;
+extern PyTypeObject CurlHttppost_Type;
extern PyTypeObject CurlMulti_Type;
extern PyTypeObject CurlShare_Type;
extern PyObject *ErrorObject;
extern PyTypeObject *p_Curl_Type;
extern PyTypeObject *p_CurlSlist_Type;
+extern PyTypeObject *p_CurlHttppost_Type;
extern PyTypeObject *p_CurlMulti_Type;
extern PyTypeObject *p_CurlShare_Type;
extern PyObject *khkey_type;