diff options
author | Christian Grothoff <christian@grothoff.org> | 2015-12-01 13:06:38 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2015-12-01 13:06:38 +0000 |
commit | fdc3e17e30e655e0a96e261f8c1a6682348db654 (patch) | |
tree | 16944a310a0f780515d88eb1746240502db11f39 /src/examples/spdy_fileserver.c | |
parent | ac599c6f9c149c26e46cf4dc5a4cd6fd906b1f68 (diff) | |
download | libmicrohttpd-fdc3e17e30e655e0a96e261f8c1a6682348db654.tar.gz libmicrohttpd-fdc3e17e30e655e0a96e261f8c1a6682348db654.zip |
killing libmicrospdy
Diffstat (limited to 'src/examples/spdy_fileserver.c')
-rw-r--r-- | src/examples/spdy_fileserver.c | 353 |
1 files changed, 0 insertions, 353 deletions
diff --git a/src/examples/spdy_fileserver.c b/src/examples/spdy_fileserver.c deleted file mode 100644 index 0a0254ff..00000000 --- a/src/examples/spdy_fileserver.c +++ /dev/null | |||
@@ -1,353 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of libmicrospdy | ||
3 | Copyright Copyright (C) 2013 Andrey Uzunov | ||
4 | |||
5 | This program is free software: you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published by | ||
7 | the Free Software Foundation, either version 3 of the License, or | ||
8 | (at your option) any later version. | ||
9 | |||
10 | This program is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | /** | ||
20 | * @file fileserver.c | ||
21 | * @brief Simple example how the lib can be used for serving | ||
22 | * files directly read from the system | ||
23 | * @author Andrey Uzunov | ||
24 | */ | ||
25 | |||
26 | //for asprintf | ||
27 | #define _GNU_SOURCE | ||
28 | |||
29 | #include <unistd.h> | ||
30 | #include <stdlib.h> | ||
31 | #include <stdint.h> | ||
32 | #include <stdbool.h> | ||
33 | #include <string.h> | ||
34 | #include <stdio.h> | ||
35 | #include <ctype.h> | ||
36 | #include <errno.h> | ||
37 | #include "microspdy.h" | ||
38 | #include "time.h" | ||
39 | |||
40 | |||
41 | int run = 1; | ||
42 | char* basedir; | ||
43 | |||
44 | |||
45 | #define GET_MIME_TYPE(fname, mime) do {\ | ||
46 | unsigned int __len = strlen(fname);\ | ||
47 | if (__len < 4 || '.' != (fname)[__len - 4]) \ | ||
48 | { \ | ||
49 | (mime) = strdup("application/octet-stream");\ | ||
50 | printf("MIME for %s is applic...\n", (fname));\ | ||
51 | }\ | ||
52 | else {\ | ||
53 | const char * __ext = &(fname)[__len - 3];\ | ||
54 | if(0 == strcmp(__ext, "jpg")) (mime) = strdup("image/jpeg");\ | ||
55 | else if(0 == strcmp(__ext, "png")) (mime) = strdup("image/png");\ | ||
56 | else if(0 == strcmp(__ext, "css")) (mime) = strdup("text/css");\ | ||
57 | else if(0 == strcmp(__ext, "gif")) (mime) = strdup("image/gif");\ | ||
58 | else if(0 == strcmp(__ext, "htm")) (mime) = strdup("text/html");\ | ||
59 | else \ | ||
60 | { \ | ||
61 | (mime) = strdup("application/octet-stream");\ | ||
62 | printf("MIME for %s is applic...\n", (fname));\ | ||
63 | }\ | ||
64 | }\ | ||
65 | if(NULL == (mime))\ | ||
66 | {\ | ||
67 | printf("no memory\n");\ | ||
68 | abort();\ | ||
69 | }\ | ||
70 | } while (0) | ||
71 | |||
72 | |||
73 | static const char *DAY_NAMES[] = | ||
74 | { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; | ||
75 | |||
76 | static const char *MONTH_NAMES[] = | ||
77 | { "Jan", "Feb", "Mar", "Apr", "May", "Jun", | ||
78 | "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; | ||
79 | |||
80 | //taken from http://stackoverflow.com/questions/2726975/how-can-i-generate-an-rfc1123-date-string-from-c-code-win32 | ||
81 | //and modified for linux | ||
82 | char *Rfc1123_DateTimeNow() | ||
83 | { | ||
84 | const int RFC1123_TIME_LEN = 29; | ||
85 | time_t t; | ||
86 | struct tm tm; | ||
87 | char * buf = malloc(RFC1123_TIME_LEN+1); | ||
88 | |||
89 | if (NULL == buf) | ||
90 | return NULL; | ||
91 | time(&t); | ||
92 | gmtime_r( &t, &tm); | ||
93 | |||
94 | strftime(buf, RFC1123_TIME_LEN+1, "---, %d --- %Y %H:%M:%S GMT", &tm); | ||
95 | memcpy(buf, DAY_NAMES[tm.tm_wday], 3); | ||
96 | memcpy(buf+8, MONTH_NAMES[tm.tm_mon], 3); | ||
97 | |||
98 | return buf; | ||
99 | } | ||
100 | |||
101 | |||
102 | ssize_t | ||
103 | response_callback (void *cls, | ||
104 | void *buffer, | ||
105 | size_t max, | ||
106 | bool *more) | ||
107 | { | ||
108 | FILE *fd =(FILE*)cls; | ||
109 | |||
110 | int ret = fread(buffer,1,max,fd); | ||
111 | *more = feof(fd) == 0; | ||
112 | |||
113 | //if(!(*more)) | ||
114 | // fclose(fd); | ||
115 | |||
116 | return ret; | ||
117 | } | ||
118 | |||
119 | |||
120 | void | ||
121 | response_done_callback(void *cls, | ||
122 | struct SPDY_Response *response, | ||
123 | struct SPDY_Request *request, | ||
124 | enum SPDY_RESPONSE_RESULT status, | ||
125 | bool streamopened) | ||
126 | { | ||
127 | (void)streamopened; | ||
128 | (void)status; | ||
129 | //printf("answer for %s was sent\n", (char *)cls); | ||
130 | |||
131 | /*if(SPDY_RESPONSE_RESULT_SUCCESS != status) | ||
132 | { | ||
133 | printf("answer for %s was NOT sent, %i\n", (char *)cls,status); | ||
134 | }*/ | ||
135 | |||
136 | SPDY_destroy_request(request); | ||
137 | SPDY_destroy_response(response); | ||
138 | if(NULL!=cls)fclose(cls); | ||
139 | } | ||
140 | |||
141 | void | ||
142 | standard_request_handler(void *cls, | ||
143 | struct SPDY_Request * request, | ||
144 | uint8_t priority, | ||
145 | const char *method, | ||
146 | const char *path, | ||
147 | const char *version, | ||
148 | const char *host, | ||
149 | const char *scheme, | ||
150 | struct SPDY_NameValue * headers, | ||
151 | bool more) | ||
152 | { | ||
153 | (void)cls; | ||
154 | (void)request; | ||
155 | (void)priority; | ||
156 | (void)host; | ||
157 | (void)scheme; | ||
158 | (void)headers; | ||
159 | (void)method; | ||
160 | (void)version; | ||
161 | (void)more; | ||
162 | |||
163 | struct SPDY_Response *response=NULL; | ||
164 | struct SPDY_NameValue *resp_headers; | ||
165 | char *fname; | ||
166 | char *fsize; | ||
167 | char *mime=NULL; | ||
168 | char *date=NULL; | ||
169 | ssize_t filesize = -666; | ||
170 | FILE *fd = NULL; | ||
171 | int ret = -666; | ||
172 | |||
173 | //printf("received request for '%s %s %s'\n", method, path, version); | ||
174 | if(strlen(path) > 1 && NULL == strstr(path, "..") && '/' == path[0]) | ||
175 | { | ||
176 | asprintf(&fname,"%s%s",basedir,path); | ||
177 | if(0 == access(fname, R_OK)) | ||
178 | { | ||
179 | if(NULL == (fd = fopen(fname,"r")) | ||
180 | || 0 != (ret = fseek(fd, 0L, SEEK_END)) | ||
181 | || -1 == (filesize = ftell(fd)) | ||
182 | || 0 != (ret = fseek(fd, 0L, SEEK_SET))) | ||
183 | { | ||
184 | printf("Error on opening %s\n%p %i %zd\n",fname, fd, ret, filesize); | ||
185 | response = SPDY_build_response(SPDY_HTTP_INTERNAL_SERVER_ERROR,NULL,SPDY_HTTP_VERSION_1_1,NULL,NULL,0); | ||
186 | } | ||
187 | else | ||
188 | { | ||
189 | if(NULL == (resp_headers = SPDY_name_value_create())) | ||
190 | { | ||
191 | printf("SPDY_name_value_create failed\n"); | ||
192 | abort(); | ||
193 | } | ||
194 | |||
195 | date = Rfc1123_DateTimeNow(); | ||
196 | if(NULL == date | ||
197 | || SPDY_YES != SPDY_name_value_add(resp_headers,SPDY_HTTP_HEADER_DATE,date)) | ||
198 | { | ||
199 | printf("SPDY_name_value_add or Rfc1123_DateTimeNow failed\n"); | ||
200 | abort(); | ||
201 | } | ||
202 | free(date); | ||
203 | |||
204 | if(-1 == asprintf(&fsize, "%zd", filesize) | ||
205 | || SPDY_YES != SPDY_name_value_add(resp_headers,SPDY_HTTP_HEADER_CONTENT_LENGTH,fsize)) | ||
206 | { | ||
207 | printf("SPDY_name_value_add or asprintf failed\n"); | ||
208 | abort(); | ||
209 | } | ||
210 | free(fsize); | ||
211 | |||
212 | GET_MIME_TYPE(path,mime); | ||
213 | if(SPDY_YES != SPDY_name_value_add(resp_headers,SPDY_HTTP_HEADER_CONTENT_TYPE,mime)) | ||
214 | { | ||
215 | printf("SPDY_name_value_add failed\n"); | ||
216 | abort(); | ||
217 | } | ||
218 | free(mime); | ||
219 | |||
220 | if(SPDY_YES != SPDY_name_value_add(resp_headers,SPDY_HTTP_HEADER_SERVER,"libmicrospdy/fileserver")) | ||
221 | { | ||
222 | printf("SPDY_name_value_add failed\n"); | ||
223 | abort(); | ||
224 | } | ||
225 | |||
226 | response = SPDY_build_response_with_callback(200,NULL, | ||
227 | SPDY_HTTP_VERSION_1_1,resp_headers,&response_callback,fd,SPDY_MAX_SUPPORTED_FRAME_SIZE); | ||
228 | SPDY_name_value_destroy(resp_headers); | ||
229 | } | ||
230 | |||
231 | if(NULL==response){ | ||
232 | printf("no response obj\n"); | ||
233 | abort(); | ||
234 | } | ||
235 | |||
236 | if(SPDY_queue_response(request,response,true,false,&response_done_callback,fd)!=SPDY_YES) | ||
237 | { | ||
238 | printf("queue\n"); | ||
239 | abort(); | ||
240 | } | ||
241 | |||
242 | free(fname); | ||
243 | return; | ||
244 | } | ||
245 | free(fname); | ||
246 | } | ||
247 | |||
248 | if(strcmp(path,"/close")==0) | ||
249 | { | ||
250 | run = 0; | ||
251 | } | ||
252 | |||
253 | response = SPDY_build_response(SPDY_HTTP_NOT_FOUND,NULL,SPDY_HTTP_VERSION_1_1,NULL,NULL,0); | ||
254 | printf("Not found %s\n",path); | ||
255 | |||
256 | if(NULL==response){ | ||
257 | printf("no response obj\n"); | ||
258 | abort(); | ||
259 | } | ||
260 | |||
261 | if(SPDY_queue_response(request,response,true,false,&response_done_callback,NULL)!=SPDY_YES) | ||
262 | { | ||
263 | printf("queue\n"); | ||
264 | abort(); | ||
265 | } | ||
266 | } | ||
267 | |||
268 | int | ||
269 | main (int argc, char *const *argv) | ||
270 | { | ||
271 | unsigned long long timeoutlong=0; | ||
272 | struct timeval timeout; | ||
273 | int ret; | ||
274 | fd_set read_fd_set; | ||
275 | fd_set write_fd_set; | ||
276 | fd_set except_fd_set; | ||
277 | int maxfd = -1; | ||
278 | struct SPDY_Daemon *daemon; | ||
279 | |||
280 | if(argc != 5) | ||
281 | { | ||
282 | printf("Usage: %s cert-file key-file base-dir port\n", argv[0]); | ||
283 | return 1; | ||
284 | } | ||
285 | |||
286 | SPDY_init(); | ||
287 | |||
288 | daemon = SPDY_start_daemon(atoi(argv[4]), | ||
289 | argv[1], | ||
290 | argv[2], | ||
291 | NULL, | ||
292 | NULL, | ||
293 | &standard_request_handler, | ||
294 | NULL, | ||
295 | NULL, | ||
296 | SPDY_DAEMON_OPTION_SESSION_TIMEOUT, | ||
297 | 1800, | ||
298 | SPDY_DAEMON_OPTION_END); | ||
299 | |||
300 | if(NULL==daemon){ | ||
301 | printf("no daemon\n"); | ||
302 | return 1; | ||
303 | } | ||
304 | |||
305 | basedir = argv[3]; | ||
306 | |||
307 | do | ||
308 | { | ||
309 | FD_ZERO(&read_fd_set); | ||
310 | FD_ZERO(&write_fd_set); | ||
311 | FD_ZERO(&except_fd_set); | ||
312 | |||
313 | ret = SPDY_get_timeout(daemon, &timeoutlong); | ||
314 | if(SPDY_NO == ret || timeoutlong > 1000) | ||
315 | { | ||
316 | timeout.tv_sec = 1; | ||
317 | timeout.tv_usec = 0; | ||
318 | } | ||
319 | else | ||
320 | { | ||
321 | timeout.tv_sec = timeoutlong / 1000; | ||
322 | timeout.tv_usec = (timeoutlong % 1000) * 1000; | ||
323 | } | ||
324 | |||
325 | maxfd = SPDY_get_fdset (daemon, | ||
326 | &read_fd_set, | ||
327 | &write_fd_set, | ||
328 | &except_fd_set); | ||
329 | |||
330 | ret = select(maxfd+1, &read_fd_set, &write_fd_set, &except_fd_set, &timeout); | ||
331 | |||
332 | switch(ret) { | ||
333 | case -1: | ||
334 | printf("select error: %i\n", errno); | ||
335 | break; | ||
336 | case 0: | ||
337 | |||
338 | break; | ||
339 | default: | ||
340 | SPDY_run(daemon); | ||
341 | |||
342 | break; | ||
343 | } | ||
344 | } | ||
345 | while(run); | ||
346 | |||
347 | SPDY_stop_daemon(daemon); | ||
348 | |||
349 | SPDY_deinit(); | ||
350 | |||
351 | return 0; | ||
352 | } | ||
353 | |||