diff options
Diffstat (limited to 'doc/examples/largepost.c')
-rw-r--r-- | doc/examples/largepost.c | 204 |
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 | |||
14 | static unsigned char nr_of_uploading_clients = 0; | ||
15 | |||
16 | struct connection_info_struct | ||
17 | { | ||
18 | int connectiontype; | ||
19 | struct MHD_PostProcessor *postprocessor; | ||
20 | FILE *fp; | ||
21 | const char *answerstring; | ||
22 | int answercode; | ||
23 | }; | ||
24 | |||
25 | const 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 | |||
33 | const char* busypage = "<html><body>This server is busy, please try again later.</body></html>"; | ||
34 | |||
35 | const char* completepage = "<html><body>The upload has been completed.</body></html>"; | ||
36 | |||
37 | const char* errorpage = "<html><body>This doesn't seem to be right.</body></html>"; | ||
38 | const char* servererrorpage = "<html><body>An internal server error has occured.</body></html>"; | ||
39 | const char* fileexistspage = "<html><body>This file already exists.</body></html>"; | ||
40 | |||
41 | |||
42 | int | ||
43 | send_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 | |||
59 | int | ||
60 | iterate_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 | |||
97 | void | ||
98 | request_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 | |||
121 | int | ||
122 | answer_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 | |||
188 | int | ||
189 | main () | ||
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 | } | ||