1 /*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel (at) haxx.se>, et al. 9 * 10 * This software is licensed as described in the file COPYING, which 11 * you should have received as part of this distribution. The terms 12 * are also available at https://curl.haxx.se/docs/copyright.html. 13 * 14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15 * copies of the Software, and permit persons to whom the Software is 16 * furnished to do so, under the terms of the COPYING file. 17 * 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 * KIND, either express or implied. 20 * 21 ***************************************************************************/ 22 /* <DESC> 23 * Make a HTTP POST with data from memory and receive response in memory. 24 * </DESC> 25 */ 26 #include <stdio.h> 27 #include <stdlib.h> 28 #include <string.h> 29 #include <curl/curl.h> 30 31 struct MemoryStruct { 32 char *memory; 33 size_t size; 34 }; 35 36 static size_t 37 WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) 38 { 39 size_t realsize = size * nmemb; 40 struct MemoryStruct *mem = (struct MemoryStruct *)userp; 41 42 mem->memory = realloc(mem->memory, mem->size + realsize + 1); 43 if(mem->memory == NULL) { 44 /* out of memory! */ 45 printf("not enough memory (realloc returned NULL)\n"); 46 return 0; 47 } 48 49 memcpy(&(mem->memory[mem->size]), contents, realsize); 50 mem->size += realsize; 51 mem->memory[mem->size] = 0; 52 53 return realsize; 54 } 55 56 int main(void) 57 { 58 CURL *curl; 59 CURLcode res; 60 struct MemoryStruct chunk; 61 static const char *postthis = "Field=1&Field=2&Field=3"; 62 63 chunk.memory = malloc(1); /* will be grown as needed by realloc above */ 64 chunk.size = 0; /* no data at this point */ 65 66 curl_global_init(CURL_GLOBAL_ALL); 67 curl = curl_easy_init(); 68 if(curl) { 69 70 curl_easy_setopt(curl, CURLOPT_URL, "http://www.example.org/"); 71 72 /* send all data to this function */ 73 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); 74 75 /* we pass our 'chunk' struct to the callback function */ 76 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk); 77 78 /* some servers don't like requests that are made without a user-agent 79 field, so we provide one */ 80 curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0"); 81 82 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postthis); 83 84 /* if we don't provide POSTFIELDSIZE, libcurl will strlen() by 85 itself */ 86 curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)strlen(postthis)); 87 88 /* Perform the request, res will get the return code */ 89 res = curl_easy_perform(curl); 90 /* Check for errors */ 91 if(res != CURLE_OK) { 92 fprintf(stderr, "curl_easy_perform() failed: %s\n", 93 curl_easy_strerror(res)); 94 } 95 else { 96 /* 97 * Now, our chunk.memory points to a memory block that is chunk.size 98 * bytes big and contains the remote file. 99 * 100 * Do something nice with it! 101 */ 102 printf("%s\n",chunk.memory); 103 } 104 105 /* always cleanup */ 106 curl_easy_cleanup(curl); 107 108 free(chunk.memory); 109 110 /* we're done with libcurl, so clean it up */ 111 curl_global_cleanup(); 112 } 113 return 0; 114 } 115