aboutsummaryrefslogtreecommitdiff
path: root/doc/examples/largepost.c
diff options
context:
space:
mode:
Diffstat (limited to 'doc/examples/largepost.c')
-rw-r--r--doc/examples/largepost.c204
1 files changed, 204 insertions, 0 deletions
diff --git a/doc/examples/largepost.c b/doc/examples/largepost.c
new file mode 100644
index 00000000..3dff5e90
--- /dev/null
+++ b/doc/examples/largepost.c
@@ -0,0 +1,204 @@
1#include <platform.h>
2#include <microhttpd.h>
3#include <string.h>
4#include <stdlib.h>
5#include <stdio.h>
6
7#define PORT 8888
8#define POSTBUFFERSIZE 512
9#define MAXCLIENTS 2
10
11#define GET 0
12#define POST 1
13
14static unsigned char nr_of_uploading_clients = 0;
15
16struct connection_info_struct
17{
18 int connectiontype;
19 struct MHD_PostProcessor *postprocessor;
20 FILE *fp;
21 const char *answerstring;
22 int answercode;
23};
24
25const char* askpage = "<html><body>\n\
26 Upload a file, please!<br>\n\
27 There are %d clients uploading at the moment.<br>\n\
28 <form action=\"/filepost\" method=\"post\" enctype=\"multipart/form-data\">\n\
29 <input name=\"file\" type=\"file\">\n\
30 <input type=\"submit\" value=\" Send \"></form>\n\
31 </body></html>";
32
33const char* busypage = "<html><body>This server is busy, please try again later.</body></html>";
34
35const char* completepage = "<html><body>The upload has been completed.</body></html>";
36
37const char* errorpage = "<html><body>This doesn't seem to be right.</body></html>";
38const char* servererrorpage = "<html><body>An internal server error has occured.</body></html>";
39const char* fileexistspage = "<html><body>This file already exists.</body></html>";
40
41
42int
43send_page (struct MHD_Connection *connection, const char* page, int status_code)
44{
45 int ret;
46 struct MHD_Response *response;
47
48
49 response = MHD_create_response_from_data (strlen (page), (void*) page, MHD_NO, MHD_YES);
50 if (!response) return MHD_NO;
51
52 ret = MHD_queue_response (connection, status_code, response);
53 MHD_destroy_response (response);
54
55 return ret;
56}
57
58
59int
60iterate_post (void *coninfo_cls, enum MHD_ValueKind kind, const char *key,
61 const char *filename, const char *content_type,
62 const char *transfer_encoding, const char *data, size_t off, size_t size)
63{
64 FILE *fp;
65 struct connection_info_struct *con_info = (struct connection_info_struct*) coninfo_cls;
66
67 con_info->answerstring = servererrorpage;
68 con_info->answercode = MHD_HTTP_INTERNAL_SERVER_ERROR;
69
70 if (0 != strcmp (key, "file")) return MHD_NO;
71
72 if (!con_info->fp)
73 {
74 if (NULL != (fp = fopen (filename, "r")) )
75 {
76 fclose (fp);
77 con_info->answerstring = fileexistspage;
78 con_info->answercode = MHD_HTTP_FORBIDDEN;
79 return MHD_NO;
80 }
81
82 con_info->fp = fopen (filename, "ab");
83 if (!con_info->fp) return MHD_NO;
84 }
85
86 if (size > 0)
87 {
88 if (!fwrite (data, size, sizeof(char), con_info->fp)) return MHD_NO;
89 }
90
91 con_info->answerstring = completepage;
92 con_info->answercode = MHD_HTTP_OK;
93
94 return MHD_YES;
95}
96
97void
98request_completed (void *cls, struct MHD_Connection *connection,
99 void **con_cls, enum MHD_RequestTerminationCode toe)
100{
101 struct connection_info_struct *con_info = (struct connection_info_struct*) *con_cls;
102
103 if (NULL == con_info) return;
104
105 if (con_info->connectiontype == POST)
106 {
107 if (NULL != con_info->postprocessor)
108 {
109 MHD_destroy_post_processor (con_info->postprocessor);
110 nr_of_uploading_clients--;
111 }
112
113 if (con_info->fp) fclose (con_info->fp);
114 }
115
116 free (con_info);
117 *con_cls = NULL;
118}
119
120
121int
122answer_to_connection (void *cls, struct MHD_Connection *connection, const char *url,
123 const char *method, const char *version, const char *upload_data,
124 unsigned int *upload_data_size, void **con_cls)
125{
126 if (NULL == *con_cls)
127 {
128 struct connection_info_struct *con_info;
129
130 if (nr_of_uploading_clients >= MAXCLIENTS)
131 return send_page(connection, busypage, MHD_HTTP_SERVICE_UNAVAILABLE);
132
133 con_info = malloc (sizeof (struct connection_info_struct));
134 if (NULL == con_info) return MHD_NO;
135
136 con_info->fp = NULL;
137
138 if (0 == strcmp (method, "POST"))
139 {
140 con_info->postprocessor = MHD_create_post_processor (connection, POSTBUFFERSIZE,
141 iterate_post, (void*) con_info);
142
143 if (NULL == con_info->postprocessor)
144 {
145 free (con_info);
146 return MHD_NO;
147 }
148
149 nr_of_uploading_clients++;
150
151 con_info->connectiontype = POST;
152 con_info->answercode = MHD_HTTP_OK;
153 con_info->answerstring = completepage;
154 }
155 else con_info->connectiontype = GET;
156
157 *con_cls = (void*) con_info;
158
159 return MHD_YES;
160 }
161
162 if (0 == strcmp (method, "GET"))
163 {
164 int ret;
165 char buffer[1024] = {0};
166
167 sprintf (buffer, askpage, nr_of_uploading_clients);
168 return send_page (connection, buffer, MHD_HTTP_OK);
169 }
170
171 if (0 == strcmp (method, "POST"))
172 {
173 struct connection_info_struct *con_info = *con_cls;
174
175 if (0 != *upload_data_size)
176 {
177 MHD_post_process(con_info->postprocessor, upload_data, *upload_data_size);
178 *upload_data_size = 0;
179
180 return MHD_YES;
181 }
182 else return send_page (connection, con_info->answerstring, con_info->answercode);
183 }
184
185 return send_page(connection, errorpage, MHD_HTTP_BAD_REQUEST);
186}
187
188int
189main ()
190{
191 struct MHD_Daemon *daemon;
192
193
194 daemon = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY, PORT, NULL, NULL,
195 &answer_to_connection, NULL, MHD_OPTION_NOTIFY_COMPLETED,
196 request_completed, NULL, MHD_OPTION_END);
197 if (NULL == daemon) return 1;
198
199 getchar ();
200
201 MHD_stop_daemon (daemon);
202
203 return 0;
204}