@@ -79,6 +79,80 @@ int lcurl_mime_set_lua(lua_State *L, lcurl_mime_t *p, lua_State *v){
7979 return 0 ;
8080}
8181
82+ #define IS_NILORSTR (L , i ) (lua_type(L, i) == LUA_TSTRING) || (lua_type(L, i) == LUA_TNIL)
83+ #define IS_TABLE (L , i ) lua_type(L, i) == LUA_TTABLE
84+ #define IS_FALSE (L , i ) (lua_type(L, i) == LUA_TBOOLEAN) && (!lua_toboolean(L, i))
85+ #define IS_OPTSTR (L , i ) (IS_FALSE(L, i)) || (IS_NILORSTR(L, i))
86+
87+ static int lutil_isarray (lua_State * L , int i ){
88+ int ret = 0 ;
89+ lua_pushnil (L );
90+ if (lua_next (L , i )){
91+ ret = lua_isnumber (L , -2 );
92+ lua_pop (L , 2 );
93+ }
94+ return ret ;
95+ }
96+
97+ static int lcurl_mime_part_assig (lua_State * L , int part , const char * method ){
98+ int top = lua_gettop (L );
99+
100+ lua_pushvalue (L , part );
101+ lua_insert (L , -2 );
102+ lua_getfield (L , -2 , method );
103+ lua_insert (L , -3 );
104+ lua_call (L , 2 , LUA_MULTRET );
105+
106+ return lua_gettop (L ) - top + 1 ;
107+ }
108+
109+ static const char * lcurl_mime_part_fields [] = {
110+ "data" , "filedata" , "name" , "filename" , "headers" , "encoder" , NULL
111+ };
112+
113+ static int lcurl_mime_part_assing_table (lua_State * L , int part , int t ){
114+ int top = lua_gettop (L );
115+ const char * method ; int i ;
116+
117+ part = lua_absindex (L , part );
118+ t = lua_absindex (L , t );
119+
120+ if (lutil_isarray (L , t )){
121+ int ret ;
122+ lua_pushvalue (L , t );
123+ ret = lcurl_mime_part_assig (L , part , "headers" );
124+ if (ret != 1 ) return ret ;
125+
126+ lua_pop (L , 1 );
127+
128+ assert (top == lua_gettop (L ));
129+ }
130+ else {
131+ for (i = 0 ;method = lcurl_mime_part_fields [i ]; ++ i ){
132+ lua_getfield (L , t , method );
133+ if (!lua_isnil (L , -1 )){
134+ int ret = lcurl_mime_part_assig (L , part , method );
135+ if (ret != 1 ) return ret ;
136+ }
137+ lua_pop (L , 1 );
138+
139+ assert (top == lua_gettop (L ));
140+ }
141+
142+ lua_getfield (L , t , "subparts" );
143+ 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" );
146+ if (ret != 1 ) return ret ;
147+ }
148+ }
149+ lua_pop (L , 1 );
150+ assert (top == lua_gettop (L ));
151+ }
152+
153+ return 0 ;
154+ }
155+
82156//{ MIME
83157
84158static lcurl_mime_part_t * lcurl_mime_parts_append (lcurl_mime_t * m , lcurl_mime_part_t * p ){
@@ -149,12 +223,22 @@ static int lcurl_mime_free(lua_State *L){
149223
150224static int lcurl_mime_addpart (lua_State * L ){
151225 lcurl_mime_t * p = lcurl_getmime (L );
152- int ret = lcurl_mime_part_create (L , p -> err_mode );
226+ int ret ;
227+
228+ lua_settop (L , 2 );
229+
230+ ret = lcurl_mime_part_create (L , p -> err_mode );
153231 if (ret != 1 ) return ret ;
154232
155233 /* store mime part in storage */
156234 lcurl_storage_preserve_value (L , p -> storage , lua_absindex (L , -1 ));
157235 lcurl_mime_parts_append (p , lcurl_getmimepart_at (L , -1 ));
236+
237+ if (lua_istable (L , 2 )){
238+ ret = lcurl_mime_part_assing_table (L , 3 , 2 );
239+ if (ret ) return ret ;
240+ }
241+
158242 return 1 ;
159243}
160244
@@ -239,79 +323,77 @@ static void lcurl_mime_part_remove_subparts(lua_State *L, lcurl_mime_part_t *p,
239323 }
240324}
241325
242- #define IS_NILORSTR (L , i ) (lua_type(L, i) == LUA_TSTRING) || (lua_type(L, i) == LUA_TNIL)
243- #define IS_TABLE (L , i ) lua_type(L, i) == LUA_TTABLE
244- #define IS_FALSE (L , i ) (lua_type(L, i) == LUA_TBOOLEAN) && (!lua_toboolean(L, i))
245- #define IS_OPTSTR (L , i ) (IS_FALSE(L, i)) || (IS_NILORSTR(L, i))
326+ static int lcurl_mime_part_assing_ext (lua_State * L , int part , int i ){
327+ #define UNSET_VALUE (const char*)-1
246328
247- static int lcurl_mime_part_assing_ext (lua_State * L , lcurl_mime_part_t * p , int i ){
248- const char * mime_type = NULL , * mime_name = NULL ;
329+ const char * mime_type = NULL , * mime_name = NULL , * mime_fname = NULL ;
249330 int headers = 0 ;
250331 CURLcode ret ;
332+ lcurl_mime_part_t * p = lcurl_getmimepart_at (L , part );
251333
252334 if (IS_TABLE (L , i )) headers = i ;
253335 else if (IS_OPTSTR (L , i )) {
254- if (IS_FALSE (L , i )) {
255- ret = curl_mime_type (p -> part , NULL );
256- if (ret != CURLE_OK )
257- return lcurl_fail_ex (L , p -> err_mode , LCURL_ERROR_EASY , ret );
258- }
259- else {
260- mime_type = lua_tostring (L , i );
261- }
336+ mime_type = IS_FALSE (L , i ) ? UNSET_VALUE : lua_tostring (L , i );
262337 if (IS_TABLE (L , i + 1 )) headers = i + 1 ;
263338 else if (IS_OPTSTR (L , i + 1 )){
264- if (IS_FALSE (L , i + 1 )) {
265- ret = curl_mime_name (p -> part , NULL );
266- if (ret != CURLE_OK )
267- return lcurl_fail_ex (L , p -> err_mode , LCURL_ERROR_EASY , ret );
268- }
269- else {
270- mime_name = lua_tostring (L , i + 1 );
271- }
339+ mime_name = IS_FALSE (L , i + 1 ) ? UNSET_VALUE : lua_tostring (L , i + 1 );
272340 if (IS_TABLE (L , i + 2 )) headers = i + 2 ;
273- else if (IS_FALSE (L , i + 2 )){
274- ret = curl_mime_headers (p -> part , NULL , 0 );
275- if (ret != CURLE_OK )
276- return lcurl_fail_ex (L , p -> err_mode , LCURL_ERROR_EASY , ret );
341+ else if (IS_OPTSTR (L , i + 2 )){
342+ mime_fname = IS_FALSE (L , i + 2 ) ? UNSET_VALUE : lua_tostring (L , i + 2 );
343+ if (IS_TABLE (L , i + 3 )) headers = i + 3 ;
344+ else if (IS_FALSE (L , i + 3 )){
345+ headers = -1 ;
346+ }
277347 }
278348 }
279349 }
280350
281351 if (mime_type ){
282- ret = curl_mime_type (p -> part , mime_type );
352+ ret = curl_mime_type (p -> part , mime_type == UNSET_VALUE ? NULL : mime_type );
283353 if (ret != CURLE_OK ){
284354 return lcurl_fail_ex (L , p -> err_mode , LCURL_ERROR_EASY , ret );
285355 }
286356 }
287357
288358 if (mime_name ){
289- ret = curl_mime_name (p -> part , mime_name );
359+ ret = curl_mime_name (p -> part , mime_name == UNSET_VALUE ? NULL : mime_name );
290360 if (ret != CURLE_OK ){
291361 return lcurl_fail_ex (L , p -> err_mode , LCURL_ERROR_EASY , ret );
292362 }
293363 }
294364
295- if (headers ){
296- struct curl_slist * list = lcurl_util_to_slist (L , headers );
297- ret = curl_mime_headers (p -> part , list , 1 );
365+ if (mime_fname ){
366+ ret = curl_mime_filename (p -> part , mime_fname == UNSET_VALUE ? NULL : mime_fname );
298367 if (ret != CURLE_OK ){
299- curl_slist_free_all (list );
300368 return lcurl_fail_ex (L , p -> err_mode , LCURL_ERROR_EASY , ret );
301369 }
302370 }
303371
372+ if (headers ){
373+ if (-1 == headers ){
374+ ret = curl_mime_headers (p -> part , NULL , 0 );
375+ if (ret != CURLE_OK ){
376+ return lcurl_fail_ex (L , p -> err_mode , LCURL_ERROR_EASY , ret );
377+ }
378+ }
379+ else
380+ return lcurl_mime_part_assing_table (L , part , headers );
381+ }
382+
304383 return 0 ;
384+
385+ #undef UNSET_VALUE
305386}
306387
307- // part:data(str[, type[, name]][, headers])
388+ // part:data(str[, type[, name[, filename] ]][, headers])
308389static int lcurl_mime_part_data (lua_State * L ){
309390 lcurl_mime_part_t * p = lcurl_getmimepart (L );
310391 size_t len ; const char * data ;
311392 CURLcode ret ;
312393
313394 if (IS_FALSE (L , 2 )){
314395 data = NULL ;
396+ len = 0 ;
315397 }
316398 else {
317399 data = luaL_checklstring (L , 2 , & len );
@@ -328,7 +410,7 @@ static int lcurl_mime_part_data(lua_State *L){
328410 }
329411
330412 if (lua_gettop (L ) > 2 ){
331- int res = lcurl_mime_part_assing_ext (L , p , 3 );
413+ int res = lcurl_mime_part_assing_ext (L , 1 , 3 );
332414 if (res ) return res ;
333415 }
334416
@@ -360,15 +442,15 @@ static int lcurl_mime_part_subparts(lua_State *L){
360442 mime -> parent = p ;
361443
362444 if (lua_gettop (L ) > 2 ){
363- int res = lcurl_mime_part_assing_ext (L , p , 3 );
445+ int res = lcurl_mime_part_assing_ext (L , 1 , 3 );
364446 if (res ) return res ;
365447 }
366448
367449 lua_settop (L , 1 );
368450 return 1 ;
369451}
370452
371- // part:filedata(path[, type[, name]][, headers])
453+ // part:filedata(path[, type[, name[, filename] ]][, headers])
372454static int lcurl_mime_part_filedata (lua_State * L ){
373455 lcurl_mime_part_t * p = lcurl_getmimepart (L );
374456 const char * data = luaL_checkstring (L , 2 );
@@ -380,7 +462,7 @@ static int lcurl_mime_part_filedata(lua_State *L){
380462 }
381463
382464 if (lua_gettop (L ) > 2 ){
383- int res = lcurl_mime_part_assing_ext (L , p , 3 );
465+ int res = lcurl_mime_part_assing_ext (L , 1 , 3 );
384466 if (res ) return res ;
385467 }
386468
@@ -458,6 +540,49 @@ static int lcurl_mime_part_name(lua_State *L){
458540 return 1 ;
459541}
460542
543+ // part:filename(t)
544+ static int lcurl_mime_part_filename (lua_State * L ){
545+ lcurl_mime_part_t * p = lcurl_getmimepart (L );
546+ const char * mime_name ;
547+ CURLcode ret ;
548+
549+ if (IS_FALSE (L , 2 )){
550+ mime_name = NULL ;
551+ }
552+ else {
553+ mime_name = luaL_checkstring (L , 2 );
554+ }
555+ ret = curl_mime_filename (p -> part , mime_name );
556+
557+ if (ret != CURLE_OK ){
558+ return lcurl_fail_ex (L , p -> err_mode , LCURL_ERROR_EASY , ret );
559+ }
560+
561+ lua_settop (L , 1 );
562+ return 1 ;
563+ }
564+
565+ // part:encoder(t)
566+ static int lcurl_mime_part_encoder (lua_State * L ){
567+ lcurl_mime_part_t * p = lcurl_getmimepart (L );
568+ const char * mime_encode ;
569+ CURLcode ret ;
570+
571+ if (IS_FALSE (L , 2 )){
572+ mime_encode = NULL ;
573+ }
574+ else {
575+ mime_encode = luaL_checkstring (L , 2 );
576+ }
577+ ret = curl_mime_encoder (p -> part , mime_encode );
578+
579+ if (ret != CURLE_OK ){
580+ return lcurl_fail_ex (L , p -> err_mode , LCURL_ERROR_EASY , ret );
581+ }
582+
583+ lua_settop (L , 1 );
584+ return 1 ;
585+ }
461586
462587//}
463588
@@ -479,7 +604,10 @@ static const struct luaL_Reg lcurl_mime_part_methods[] = {
479604 {"filedata" , lcurl_mime_part_filedata },
480605 {"headers" , lcurl_mime_part_headers },
481606 {"name" , lcurl_mime_part_name },
607+ {"filename" , lcurl_mime_part_filename },
482608 {"type" , lcurl_mime_part_type },
609+ {"encoder" , lcurl_mime_part_encoder },
610+
483611
484612 {"free" , lcurl_mime_part_free },
485613 {"__gc" , lcurl_mime_part_free },
0 commit comments