diff options
author | fsbs <fsbs@users.noreply.github.com> | 2021-10-31 04:40:28 +0000 |
---|---|---|
committer | fsbs <fsbs@users.noreply.github.com> | 2021-10-31 05:40:28 +0100 |
commit | fecd18940a1064761929f828e907ecca548706dc (patch) | |
tree | a5d524730b552661fc852981351563ba74671495 | |
parent | e7d8329ad29a046488390a0d4d41e5878104cb75 (diff) | |
download | pycurl-fecd18940a1064761929f828e907ecca548706dc.tar.gz |
Wrap curl_httppost in a Python object
-rw-r--r-- | src/easy.c | 43 | ||||
-rw-r--r-- | src/easyopt.c | 16 | ||||
-rw-r--r-- | src/module.c | 6 | ||||
-rw-r--r-- | src/pycurl.h | 13 |
4 files changed, 61 insertions, 17 deletions
@@ -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; |