blob: ae4f4db989ecd3c031eeb5c406096843f352627e [file] [log] [blame]
Lucas Eckels9bd90e62012-08-06 15:07:02 -07001/*****************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 *
9 * An example source code that issues a HTTP POST and we provide the actual
10 * data through a read callback.
11 *
12 */
13#include <stdio.h>
14#include <string.h>
15#include <curl/curl.h>
16
17const char data[]="this is what we post to the silly web server";
18
19struct WriteThis {
20 const char *readptr;
21 int sizeleft;
22};
23
24static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp)
25{
26 struct WriteThis *pooh = (struct WriteThis *)userp;
27
28 if(size*nmemb < 1)
29 return 0;
30
31 if(pooh->sizeleft) {
32 *(char *)ptr = pooh->readptr[0]; /* copy one single byte */
33 pooh->readptr++; /* advance pointer */
34 pooh->sizeleft--; /* less data left */
35 return 1; /* we return 1 byte at a time! */
36 }
37
38 return 0; /* no more data left to deliver */
39}
40
41int main(void)
42{
43 CURL *curl;
44 CURLcode res;
45
46 struct WriteThis pooh;
47
48 pooh.readptr = data;
49 pooh.sizeleft = strlen(data);
50
51 curl = curl_easy_init();
52 if(curl) {
53 /* First set the URL that is about to receive our POST. */
54 curl_easy_setopt(curl, CURLOPT_URL, "http://example.com/index.cgi");
55
56 /* Now specify we want to POST data */
57 curl_easy_setopt(curl, CURLOPT_POST, 1L);
58
59 /* we want to use our own read function */
60 curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
61
62 /* pointer to pass to our read function */
63 curl_easy_setopt(curl, CURLOPT_READDATA, &pooh);
64
65 /* get verbose debug output please */
66 curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
67
68 /*
69 If you use POST to a HTTP 1.1 server, you can send data without knowing
70 the size before starting the POST if you use chunked encoding. You
71 enable this by adding a header like "Transfer-Encoding: chunked" with
72 CURLOPT_HTTPHEADER. With HTTP 1.0 or without chunked transfer, you must
73 specify the size in the request.
74 */
75#ifdef USE_CHUNKED
76 {
77 struct curl_slist *chunk = NULL;
78
79 chunk = curl_slist_append(chunk, "Transfer-Encoding: chunked");
80 res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
81 /* use curl_slist_free_all() after the *perform() call to free this
82 list again */
83 }
84#else
85 /* Set the expected POST size. If you want to POST large amounts of data,
86 consider CURLOPT_POSTFIELDSIZE_LARGE */
87 curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (curl_off_t)pooh.sizeleft);
88#endif
89
90#ifdef DISABLE_EXPECT
91 /*
92 Using POST with HTTP 1.1 implies the use of a "Expect: 100-continue"
93 header. You can disable this header with CURLOPT_HTTPHEADER as usual.
94 NOTE: if you want chunked transfer too, you need to combine these two
95 since you can only set one list of headers with CURLOPT_HTTPHEADER. */
96
97 /* A less good option would be to enforce HTTP 1.0, but that might also
98 have other implications. */
99 {
100 struct curl_slist *chunk = NULL;
101
102 chunk = curl_slist_append(chunk, "Expect:");
103 res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
104 /* use curl_slist_free_all() after the *perform() call to free this
105 list again */
106 }
107#endif
108
109 /* Perform the request, res will get the return code */
110 res = curl_easy_perform(curl);
111
112 /* always cleanup */
113 curl_easy_cleanup(curl);
114 }
115 return 0;
116}