14
14
#include "lcerror.h"
15
15
#include "lcutils.h"
16
16
17
+ /* API Notes.
18
+ * 1. Each mime can be root or child. If mime is a child (subpart) then curl free it
19
+ * when parent mime is freed or when remove this part from parent. There no way reuse same mime.
20
+ * Its not clear is it possible use mime created by one easy handle when do preform in another.
21
+ * `m=e1:mime() e2:setopt_httpmime(m) e1:close() e2:perform()`
22
+ *
23
+ * // Attach child to root (root also can have parent)
24
+ * curl_mime_subparts(root, child);
25
+ *
26
+ * // curl free `child` and all its childs
27
+ * curl_mime_subparts(root, other_child_or_null);
28
+ *
29
+ * // forbidden
30
+ * curl_mime_free(child);
31
+ */
32
+
17
33
#if LCURL_CURL_VER_GE (7 ,56 ,0 )
18
34
19
35
#define LCURL_MIME_NAME LCURL_PREFIX" MIME"
@@ -22,6 +38,8 @@ static const char *LCURL_MIME = LCURL_MIME_NAME;
22
38
#define LCURL_MIME_PART_NAME LCURL_PREFIX" MIME Part"
23
39
static const char * LCURL_MIME_PART = LCURL_MIME_PART_NAME ;
24
40
41
+ //{ Free mime and subparts
42
+
25
43
static void lcurl_mime_part_remove_subparts (lua_State * L , lcurl_mime_part_t * p , int free_it );
26
44
27
45
static lcurl_mime_t * lcurl_mime_part_get_subparts (lua_State * L , lcurl_mime_part_t * part ){
@@ -66,9 +84,45 @@ static int lcurl_mime_reset(lua_State *L, lcurl_mime_t *p){
66
84
p -> parts = p -> parent = NULL ;
67
85
p -> mime = NULL ;
68
86
87
+ /* remove weak reference to easy */
88
+ lua_pushnil (L );
89
+ lua_rawsetp (L , LCURL_MIME_EASY , p );
90
+
69
91
return 0 ;
70
92
}
71
93
94
+ static void lcurl_mime_part_remove_subparts (lua_State * L , lcurl_mime_part_t * p , int free_it ){
95
+ lcurl_mime_t * sub = lcurl_mime_part_get_subparts (L , p );
96
+ if (sub ){
97
+ assert (LUA_NOREF != p -> subpart_ref );
98
+ /* detach `subpart` mime from current mime part */
99
+ /* if set `sub->parent = NULL` then gc for mime will try free curl_mime_free. */
100
+
101
+ luaL_unref (L , LCURL_LUA_REGISTRY , p -> subpart_ref );
102
+ p -> subpart_ref = LUA_NOREF ;
103
+
104
+ if (p -> part && free_it ){
105
+ curl_mime_subparts (p -> part , NULL );
106
+ }
107
+
108
+ /* seems curl_mime_subparts(h, NULL) free asubparts.
109
+ so we have to invalidate all reference to all nested objects (part/mime).
110
+ NOTE. All resources already feed. So just need set all pointers to NULL
111
+ and free all Lua resources (like references and storages)
112
+ */
113
+ {
114
+ lcurl_mime_part_t * ptr ;
115
+ /* reset all parts*/
116
+ for (ptr = sub -> parts ; ptr ; ptr = ptr -> next ){
117
+ lcurl_mime_part_remove_subparts (L , p , 0 );
118
+ }
119
+ lcurl_mime_reset (L , sub );
120
+ }
121
+ }
122
+ }
123
+
124
+ //}
125
+
72
126
int lcurl_mime_set_lua (lua_State * L , lcurl_mime_t * p , lua_State * v ){
73
127
lcurl_mime_part_t * part ;
74
128
for (part = p -> parts ; part ; part = part -> next ){
@@ -86,6 +140,7 @@ int lcurl_mime_set_lua(lua_State *L, lcurl_mime_t *p, lua_State *v){
86
140
87
141
static int lutil_isarray (lua_State * L , int i ){
88
142
int ret = 0 ;
143
+ i = lua_absindex (L , i );
89
144
lua_pushnil (L );
90
145
if (lua_next (L , i )){
91
146
ret = lua_isnumber (L , -2 );
@@ -94,7 +149,7 @@ static int lutil_isarray(lua_State *L, int i){
94
149
return ret ;
95
150
}
96
151
97
- static int lcurl_mime_part_assig (lua_State * L , int part , const char * method ){
152
+ static int lcurl_mime_part_assign (lua_State * L , int part , const char * method ){
98
153
int top = lua_gettop (L );
99
154
100
155
lua_pushvalue (L , part );
@@ -107,7 +162,7 @@ static int lcurl_mime_part_assig(lua_State *L, int part, const char *method){
107
162
}
108
163
109
164
static const char * lcurl_mime_part_fields [] = {
110
- "data" , "filedata" , "name" , "filename" , "headers" , "encoder" , NULL
165
+ "data" , "filedata" , "name" , "filename" , "headers" , "encoder" , "type" , NULL
111
166
};
112
167
113
168
static int lcurl_mime_part_assing_table (lua_State * L , int part , int t ){
@@ -120,7 +175,7 @@ static int lcurl_mime_part_assing_table(lua_State *L, int part, int t){
120
175
if (lutil_isarray (L , t )){
121
176
int ret ;
122
177
lua_pushvalue (L , t );
123
- ret = lcurl_mime_part_assig (L , part , "headers" );
178
+ ret = lcurl_mime_part_assign (L , part , "headers" );
124
179
if (ret != 1 ) return ret ;
125
180
126
181
lua_pop (L , 1 );
@@ -131,7 +186,7 @@ static int lcurl_mime_part_assing_table(lua_State *L, int part, int t){
131
186
for (i = 0 ;method = lcurl_mime_part_fields [i ]; ++ i ){
132
187
lua_getfield (L , t , method );
133
188
if (!lua_isnil (L , -1 )){
134
- int ret = lcurl_mime_part_assig (L , part , method );
189
+ int ret = lcurl_mime_part_assign (L , part , method );
135
190
if (ret != 1 ) return ret ;
136
191
}
137
192
lua_pop (L , 1 );
@@ -141,8 +196,8 @@ static int lcurl_mime_part_assing_table(lua_State *L, int part, int t){
141
196
142
197
lua_getfield (L , t , "subparts" );
143
198
if (!lua_isnil (L , -1 )){
144
- if (IS_FALSE (L , -1 ) || lcurl_getmimepart_at (L , -1 )){
145
- int ret = lcurl_mime_part_assig (L , part , "subparts" );
199
+ if (IS_FALSE (L , -1 ) || lcurl_getmime_at (L , -1 )){
200
+ int ret = lcurl_mime_part_assign (L , part , "subparts" );
146
201
if (ret != 1 ) return ret ;
147
202
}
148
203
}
@@ -190,6 +245,10 @@ int lcurl_mime_create(lua_State *L, int error_mode){
190
245
p -> err_mode = error_mode ;
191
246
p -> parts = p -> parent = NULL ;
192
247
248
+ /* weak reference from mime to easy handle */
249
+ lua_pushvalue (L , 1 );
250
+ lua_rawsetp (L , LCURL_MIME_EASY , (void * )p );
251
+
193
252
return 1 ;
194
253
}
195
254
@@ -242,6 +301,12 @@ static int lcurl_mime_addpart(lua_State *L){
242
301
return 1 ;
243
302
}
244
303
304
+ static int lcurl_mime_easy (lua_State * L ){
305
+ lcurl_mime_t * p = lcurl_getmime (L );
306
+ lua_rawgetp (L , LCURL_MIME_EASY , p );
307
+ return 1 ;
308
+ }
309
+
245
310
//}
246
311
247
312
//{ MIME Part
@@ -289,40 +354,6 @@ static int lcurl_mime_part_free(lua_State *L){
289
354
return 0 ;
290
355
}
291
356
292
- static void lcurl_mime_part_remove_subparts (lua_State * L , lcurl_mime_part_t * p , int free_it ){
293
- lcurl_mime_t * sub = lcurl_mime_part_get_subparts (L , p );
294
- if (sub ){
295
- assert (LUA_NOREF != p -> subpart_ref );
296
- /* detach `subpart` mime from current mime part */
297
-
298
- /* if set `sub->parent = NULL` then gc for mime will try free curl_mime_free. */
299
- /* So do not set it unless `curl_mime_subparts(p->part, NULL)` does not free mime */
300
-
301
- luaL_unref (L , LCURL_LUA_REGISTRY , p -> subpart_ref );
302
- p -> subpart_ref = LUA_NOREF ;
303
-
304
- if (p -> part && free_it ){
305
- curl_mime_subparts (p -> part , NULL );
306
- }
307
-
308
- /* issues #1961 */
309
-
310
- /* seems curl_mime_subparts(h, NULL) free asubparts.
311
- so we have to invalidate all reference to all nested objects (part/mime).
312
- NOTE. All resources already feed. So just need set all pointers to NULL
313
- and free all Lua resources (like references and storages)
314
- */
315
- {
316
- lcurl_mime_part_t * ptr ;
317
- /* reset all parts*/
318
- for (ptr = sub -> parts ; ptr ; ptr = ptr -> next ){
319
- lcurl_mime_part_remove_subparts (L , p , 0 );
320
- }
321
- lcurl_mime_reset (L , sub );
322
- }
323
- }
324
- }
325
-
326
357
static int lcurl_mime_part_assing_ext (lua_State * L , int part , int i ){
327
358
#define UNSET_VALUE (const char*)-1
328
359
@@ -589,6 +620,7 @@ static int lcurl_mime_part_encoder(lua_State *L){
589
620
static const struct luaL_Reg lcurl_mime_methods [] = {
590
621
591
622
{"addpart" , lcurl_mime_addpart },
623
+ {"easy" , lcurl_mime_easy },
592
624
593
625
{"free" , lcurl_mime_free },
594
626
{"__gc" , lcurl_mime_free },
@@ -646,6 +678,7 @@ void lcurl_mime_initlib(lua_State *L, int nup){
646
678
if (!lutil_createmetap (L , LCURL_MIME_PART , lcurl_mime_part_methods , nup ))
647
679
lua_pop (L , nup );
648
680
lua_pop (L , 1 );
681
+
649
682
#else
650
683
lua_pop (L , nup );
651
684
#endif
0 commit comments