// part:name(t) static int lcurl_mime_part_name(lua_State *L){ lcurl_mime_part_t *p = lcurl_getmimepart(L); const char *mime_name; CURLcode ret; if(IS_FALSE(L, 2)){ mime_name = NULL; } else{ mime_name = luaL_checkstring(L, 2); } ret = curl_mime_name(p->part, mime_name); if(ret != CURLE_OK){ return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, ret); } lua_settop(L, 1); return 1; }
int main(void) { CURL *curl; CURLM *multi_handle; int still_running; curl_mime *form = NULL; curl_mimepart *field = NULL; struct curl_slist *headerlist = NULL; static const char buf[] = "Expect:"; curl = curl_easy_init(); multi_handle = curl_multi_init(); if(curl && multi_handle) { /* Create the form */ form = curl_mime_init(curl); /* Fill in the file upload field */ field = curl_mime_addpart(form); curl_mime_name(field, "sendfile", CURL_ZERO_TERMINATED); curl_mime_filedata(field, "multi-post.c"); /* Fill in the filename field */ field = curl_mime_addpart(form); curl_mime_name(field, "filename", CURL_ZERO_TERMINATED); curl_mime_data(field, "multi-post.c", CURL_ZERO_TERMINATED); /* Fill in the submit field too, even if this is rarely needed */ field = curl_mime_addpart(form); curl_mime_name(field, "submit", CURL_ZERO_TERMINATED); curl_mime_data(field, "send", CURL_ZERO_TERMINATED); /* initialize custom header list (stating that Expect: 100-continue is not wanted */ headerlist = curl_slist_append(headerlist, buf); /* what URL that receives this POST */ curl_easy_setopt(curl, CURLOPT_URL, "http://www.example.com/upload.cgi"); curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist); curl_easy_setopt(curl, CURLOPT_MIMEPOST, form); curl_multi_add_handle(multi_handle, curl); curl_multi_perform(multi_handle, &still_running); do { struct timeval timeout; int rc; /* select() return code */ CURLMcode mc; /* curl_multi_fdset() return code */ fd_set fdread; fd_set fdwrite; fd_set fdexcep; int maxfd = -1; long curl_timeo = -1; FD_ZERO(&fdread); FD_ZERO(&fdwrite); FD_ZERO(&fdexcep); /* set a suitable timeout to play around with */ timeout.tv_sec = 1; timeout.tv_usec = 0; curl_multi_timeout(multi_handle, &curl_timeo); if(curl_timeo >= 0) { timeout.tv_sec = curl_timeo / 1000; if(timeout.tv_sec > 1) timeout.tv_sec = 1; else timeout.tv_usec = (curl_timeo % 1000) * 1000; } /* get file descriptors from the transfers */ mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); if(mc != CURLM_OK) { fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc); break; } /* On success the value of maxfd is guaranteed to be >= -1. We call select(maxfd + 1, ...); specially in case of (maxfd == -1) there are no fds ready yet so we call select(0, ...) --or Sleep() on Windows-- to sleep 100ms, which is the minimum suggested value in the curl_multi_fdset() doc. */ if(maxfd == -1) { #ifdef _WIN32 Sleep(100); rc = 0; #else /* Portable sleep for platforms other than Windows. */ struct timeval wait = { 0, 100 * 1000 }; /* 100ms */ rc = select(0, NULL, NULL, NULL, &wait); #endif } else { /* Note that on some platforms 'timeout' may be modified by select(). If you need access to the original value save a copy beforehand. */ rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); } switch(rc) { case -1: /* select error */ break; case 0: default: /* timeout or readable/writable sockets */ printf("perform!\n"); curl_multi_perform(multi_handle, &still_running); printf("running: %d!\n", still_running); break; } } while(still_running); curl_multi_cleanup(multi_handle); /* always cleanup */ curl_easy_cleanup(curl); /* then cleanup the form */ curl_mime_free(form); /* free slist */ curl_slist_free_all(headerlist); } return 0; }
static int lcurl_mime_part_assing_ext(lua_State *L, int part, int i){ #define UNSET_VALUE (const char*)-1 const char *mime_type = NULL, *mime_name = NULL, *mime_fname = NULL; int headers = 0; CURLcode ret; lcurl_mime_part_t *p = lcurl_getmimepart_at(L, part); if(IS_TABLE(L, i)) headers = i; else if (IS_OPTSTR(L, i)) { mime_type = IS_FALSE(L, i) ? UNSET_VALUE : lua_tostring(L, i); if(IS_TABLE(L, i+1)) headers = i+1; else if(IS_OPTSTR(L, i+1)){ mime_name = IS_FALSE(L, i+1) ? UNSET_VALUE : lua_tostring(L, i+1); if(IS_TABLE(L, i+2)) headers = i+2; else if(IS_OPTSTR(L, i+2)){ mime_fname = IS_FALSE(L, i+2) ? UNSET_VALUE : lua_tostring(L, i+2); if(IS_TABLE(L, i+3)) headers = i+3; else if(IS_FALSE(L, i+3)){ headers = -1; } } } } if(mime_type){ ret = curl_mime_type(p->part, mime_type == UNSET_VALUE ? NULL : mime_type); if(ret != CURLE_OK){ return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, ret); } } if(mime_name){ ret = curl_mime_name(p->part, mime_name == UNSET_VALUE ? NULL : mime_name); if(ret != CURLE_OK){ return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, ret); } } if(mime_fname){ ret = curl_mime_filename(p->part, mime_fname == UNSET_VALUE ? NULL : mime_fname); if(ret != CURLE_OK){ return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, ret); } } if(headers){ if(-1 == headers){ ret = curl_mime_headers(p->part, NULL, 0); if(ret != CURLE_OK){ return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, ret); } } else return lcurl_mime_part_assing_table(L, part, headers); } return 0; #undef UNSET_VALUE }
static int _piwigo_api_post_internal(_piwigo_api_context_t *ctx, GList *args, char *filename, gboolean isauth) { curl_mime *form = NULL; GString *url = g_string_new(ctx->url); // send the requests GString *response = g_string_new(""); dt_curl_init(ctx->curl_ctx, piwigo_EXTRA_VERBOSE); curl_easy_setopt(ctx->curl_ctx, CURLOPT_URL, url->str); curl_easy_setopt(ctx->curl_ctx, CURLOPT_POST, 1); curl_easy_setopt(ctx->curl_ctx, CURLOPT_WRITEFUNCTION, curl_write_data_cb); curl_easy_setopt(ctx->curl_ctx, CURLOPT_WRITEDATA, response); if(isauth) { /* construct a temporary file name */ char cookie_fmt[PATH_MAX] = { 0 }; dt_loc_get_tmp_dir(cookie_fmt, sizeof(cookie_fmt)); g_strlcat(cookie_fmt, "/cookies.%.4lf.txt", sizeof(cookie_fmt)); ctx->cookie_file = g_strdup_printf(cookie_fmt, dt_get_wtime()); // not that this is safe as the cookie file is written only when the curl context is finalized. // At this stage we unlink the file. curl_easy_setopt(ctx->curl_ctx, CURLOPT_COOKIEJAR, ctx->cookie_file); } else { curl_easy_setopt(ctx->curl_ctx, CURLOPT_COOKIEFILE, ctx->cookie_file); } if(filename) { curl_mimepart *field = NULL; form = curl_mime_init(ctx->curl_ctx); GList *a = args; while (a) { _curl_args_t *ca = (_curl_args_t *)a->data; field = curl_mime_addpart(form); curl_mime_name(field, ca->name); curl_mime_data(field, ca->value, CURL_ZERO_TERMINATED); a = g_list_next(a); } field = curl_mime_addpart(form); curl_mime_name(field, "image"); curl_mime_filedata(field, filename); curl_easy_setopt(ctx->curl_ctx, CURLOPT_MIMEPOST, form); } else { GString *gargs = g_string_new(""); GList *a = args; while (a) { _curl_args_t *ca = (_curl_args_t *)a->data; if(a!=args) g_string_append(gargs, "&"); g_string_append(gargs, ca->name); g_string_append(gargs, "="); g_string_append(gargs, ca->value); a = g_list_next(a); } curl_easy_setopt(ctx->curl_ctx, CURLOPT_COPYPOSTFIELDS, gargs->str); g_string_free(gargs, TRUE); } int res = curl_easy_perform(ctx->curl_ctx); #if piwigo_EXTRA_VERBOSE == TRUE g_printf("curl_easy_perform status %d\n", res); #endif if(filename) curl_mime_free(form); g_string_free(url, TRUE); ctx->response = NULL; if(res == CURLE_OK) { GError *error = NULL; gboolean ret = json_parser_load_from_data(ctx->json_parser, response->str, response->len, &error); if(!ret) goto cleanup; JsonNode *root = json_parser_get_root(ctx->json_parser); // we should always have a dict if(json_node_get_node_type(root) != JSON_NODE_OBJECT) goto cleanup; ctx->response = json_node_get_object(root); const char *status = json_object_get_string_member(ctx->response, "stat"); ctx->error_occured = (status && (strcmp(status,"fail")==0)); } else ctx->error_occured = TRUE; cleanup: g_string_free(response, TRUE); return res; }