diff options
Diffstat (limited to 'src/examples/fileserver_example.c')
-rw-r--r-- | src/examples/fileserver_example.c | 84 |
1 files changed, 43 insertions, 41 deletions
diff --git a/src/examples/fileserver_example.c b/src/examples/fileserver_example.c index b8935fa1..46e6aad6 100644 --- a/src/examples/fileserver_example.c +++ b/src/examples/fileserver_example.c | |||
@@ -34,7 +34,8 @@ | |||
34 | #include <fcntl.h> | 34 | #include <fcntl.h> |
35 | #endif /* HAVE_FCNTL_H */ | 35 | #endif /* HAVE_FCNTL_H */ |
36 | 36 | ||
37 | #define PAGE "<html><head><title>File not found</title></head><body>File not found</body></html>" | 37 | #define PAGE \ |
38 | "<html><head><title>File not found</title></head><body>File not found</body></html>" | ||
38 | 39 | ||
39 | #ifndef S_ISREG | 40 | #ifndef S_ISREG |
40 | #define S_ISREG(x) (S_IFREG == (x & S_IFREG)) | 41 | #define S_ISREG(x) (S_IFREG == (x & S_IFREG)) |
@@ -47,67 +48,67 @@ ahc_echo (void *cls, | |||
47 | const char *method, | 48 | const char *method, |
48 | const char *version, | 49 | const char *version, |
49 | const char *upload_data, | 50 | const char *upload_data, |
50 | size_t *upload_data_size, void **ptr) | 51 | size_t *upload_data_size, void **ptr) |
51 | { | 52 | { |
52 | static int aptr; | 53 | static int aptr; |
53 | struct MHD_Response *response; | 54 | struct MHD_Response *response; |
54 | int ret; | 55 | int ret; |
55 | int fd; | 56 | int fd; |
56 | struct stat buf; | 57 | struct stat buf; |
57 | (void)cls; /* Unused. Silent compiler warning. */ | 58 | (void) cls; /* Unused. Silent compiler warning. */ |
58 | (void)version; /* Unused. Silent compiler warning. */ | 59 | (void) version; /* Unused. Silent compiler warning. */ |
59 | (void)upload_data; /* Unused. Silent compiler warning. */ | 60 | (void) upload_data; /* Unused. Silent compiler warning. */ |
60 | (void)upload_data_size; /* Unused. Silent compiler warning. */ | 61 | (void) upload_data_size; /* Unused. Silent compiler warning. */ |
61 | 62 | ||
62 | if ( (0 != strcmp (method, MHD_HTTP_METHOD_GET)) && | 63 | if ( (0 != strcmp (method, MHD_HTTP_METHOD_GET)) && |
63 | (0 != strcmp (method, MHD_HTTP_METHOD_HEAD)) ) | 64 | (0 != strcmp (method, MHD_HTTP_METHOD_HEAD)) ) |
64 | return MHD_NO; /* unexpected method */ | 65 | return MHD_NO; /* unexpected method */ |
65 | if (&aptr != *ptr) | 66 | if (&aptr != *ptr) |
66 | { | 67 | { |
67 | /* do never respond on first call */ | 68 | /* do never respond on first call */ |
68 | *ptr = &aptr; | 69 | *ptr = &aptr; |
69 | return MHD_YES; | 70 | return MHD_YES; |
70 | } | 71 | } |
71 | *ptr = NULL; /* reset when done */ | 72 | *ptr = NULL; /* reset when done */ |
72 | /* WARNING: direct usage of url as filename is for example only! | 73 | /* WARNING: direct usage of url as filename is for example only! |
73 | * NEVER pass received data directly as parameter to file manipulation | 74 | * NEVER pass received data directly as parameter to file manipulation |
74 | * functions. Always check validity of data before using. | 75 | * functions. Always check validity of data before using. |
75 | */ | 76 | */ |
76 | if (NULL != strstr(url, "../")) /* Very simplified check! */ | 77 | if (NULL != strstr (url, "../")) /* Very simplified check! */ |
77 | fd = -1; /* Do not allow usage of parent directories. */ | 78 | fd = -1; /* Do not allow usage of parent directories. */ |
78 | else | 79 | else |
79 | fd = open (url + 1, O_RDONLY); | 80 | fd = open (url + 1, O_RDONLY); |
80 | if (-1 != fd) | 81 | if (-1 != fd) |
82 | { | ||
83 | if ( (0 != fstat (fd, &buf)) || | ||
84 | (! S_ISREG (buf.st_mode)) ) | ||
81 | { | 85 | { |
82 | if ( (0 != fstat (fd, &buf)) || | 86 | /* not a regular file, refuse to serve */ |
83 | (! S_ISREG (buf.st_mode)) ) | 87 | if (0 != close (fd)) |
84 | { | 88 | abort (); |
85 | /* not a regular file, refuse to serve */ | 89 | fd = -1; |
86 | if (0 != close (fd)) | ||
87 | abort (); | ||
88 | fd = -1; | ||
89 | } | ||
90 | } | 90 | } |
91 | } | ||
91 | if (-1 == fd) | 92 | if (-1 == fd) |
92 | { | 93 | { |
93 | response = MHD_create_response_from_buffer (strlen (PAGE), | 94 | response = MHD_create_response_from_buffer (strlen (PAGE), |
94 | (void *) PAGE, | 95 | (void *) PAGE, |
95 | MHD_RESPMEM_PERSISTENT); | 96 | MHD_RESPMEM_PERSISTENT); |
96 | ret = MHD_queue_response (connection, MHD_HTTP_NOT_FOUND, response); | 97 | ret = MHD_queue_response (connection, MHD_HTTP_NOT_FOUND, response); |
97 | MHD_destroy_response (response); | 98 | MHD_destroy_response (response); |
98 | } | 99 | } |
99 | else | 100 | else |
101 | { | ||
102 | response = MHD_create_response_from_fd64 (buf.st_size, fd); | ||
103 | if (NULL == response) | ||
100 | { | 104 | { |
101 | response = MHD_create_response_from_fd64 (buf.st_size, fd); | 105 | if (0 != close (fd)) |
102 | if (NULL == response) | 106 | abort (); |
103 | { | 107 | return MHD_NO; |
104 | if (0 != close (fd)) | ||
105 | abort (); | ||
106 | return MHD_NO; | ||
107 | } | ||
108 | ret = MHD_queue_response (connection, MHD_HTTP_OK, response); | ||
109 | MHD_destroy_response (response); | ||
110 | } | 108 | } |
109 | ret = MHD_queue_response (connection, MHD_HTTP_OK, response); | ||
110 | MHD_destroy_response (response); | ||
111 | } | ||
111 | return ret; | 112 | return ret; |
112 | } | 113 | } |
113 | 114 | ||
@@ -118,11 +119,12 @@ main (int argc, char *const *argv) | |||
118 | struct MHD_Daemon *d; | 119 | struct MHD_Daemon *d; |
119 | 120 | ||
120 | if (argc != 2) | 121 | if (argc != 2) |
121 | { | 122 | { |
122 | printf ("%s PORT\n", argv[0]); | 123 | printf ("%s PORT\n", argv[0]); |
123 | return 1; | 124 | return 1; |
124 | } | 125 | } |
125 | d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG, | 126 | d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION |
127 | | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG, | ||
126 | atoi (argv[1]), | 128 | atoi (argv[1]), |
127 | NULL, NULL, &ahc_echo, PAGE, MHD_OPTION_END); | 129 | NULL, NULL, &ahc_echo, PAGE, MHD_OPTION_END); |
128 | if (d == NULL) | 130 | if (d == NULL) |