aboutsummaryrefslogtreecommitdiff
path: root/src/examples/http_chunked_compression.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/examples/http_chunked_compression.c')
-rw-r--r--src/examples/http_chunked_compression.c139
1 files changed, 74 insertions, 65 deletions
diff --git a/src/examples/http_chunked_compression.c b/src/examples/http_chunked_compression.c
index 9c3f629f..461f4d3a 100644
--- a/src/examples/http_chunked_compression.c
+++ b/src/examples/http_chunked_compression.c
@@ -38,20 +38,22 @@
38#elif defined(INTPTR_MAX) 38#elif defined(INTPTR_MAX)
39#define SSIZE_MAX INTPTR_MAX 39#define SSIZE_MAX INTPTR_MAX
40#else 40#else
41#define SSIZE_MAX ((ssize_t)(((size_t)-1)>>1)) 41#define SSIZE_MAX ((ssize_t) (((size_t) -1) >> 1))
42#endif 42#endif
43#endif /* ! SSIZE_MAX */ 43#endif /* ! SSIZE_MAX */
44 44
45#define CHUNK 16384 45#define CHUNK 16384
46 46
47struct Holder { 47struct Holder
48 FILE *file; 48{
49 z_stream stream; 49 FILE *file;
50 void *buf; 50 z_stream stream;
51 void *buf;
51}; 52};
52 53
53static int 54static int
54compress_buf (z_stream *strm, const void *src, size_t src_size, size_t *offset, void **dest, size_t *dest_size, 55compress_buf (z_stream *strm, const void *src, size_t src_size, size_t *offset,
56 void **dest, size_t *dest_size,
55 void *tmp) 57 void *tmp)
56{ 58{
57 unsigned int have; 59 unsigned int have;
@@ -61,39 +63,39 @@ compress_buf (z_stream *strm, const void *src, size_t src_size, size_t *offset,
61 *dest = NULL; 63 *dest = NULL;
62 *dest_size = 0; 64 *dest_size = 0;
63 do 65 do
66 {
67 if (src_size > CHUNK)
64 { 68 {
65 if (src_size > CHUNK) 69 strm->avail_in = CHUNK;
66 { 70 src_size -= CHUNK;
67 strm->avail_in = CHUNK; 71 flush = Z_NO_FLUSH;
68 src_size -= CHUNK;
69 flush = Z_NO_FLUSH;
70 }
71 else
72 {
73 strm->avail_in = (uInt) src_size;
74 flush = Z_SYNC_FLUSH;
75 }
76 *offset += strm->avail_in;
77 strm->next_in = (Bytef *) src;
78 do
79 {
80 strm->avail_out = CHUNK;
81 strm->next_out = tmp;
82 ret = deflate (strm, flush);
83 have = CHUNK - strm->avail_out;
84 *dest_size += have;
85 tmp_dest = realloc (*dest, *dest_size);
86 if (NULL == tmp_dest)
87 {
88 free (*dest);
89 *dest = NULL;
90 return MHD_NO;
91 }
92 *dest = tmp_dest;
93 memcpy ((*dest) + ((*dest_size) - have), tmp, have);
94 }
95 while (0 == strm->avail_out);
96 } 72 }
73 else
74 {
75 strm->avail_in = (uInt) src_size;
76 flush = Z_SYNC_FLUSH;
77 }
78 *offset += strm->avail_in;
79 strm->next_in = (Bytef *) src;
80 do
81 {
82 strm->avail_out = CHUNK;
83 strm->next_out = tmp;
84 ret = deflate (strm, flush);
85 have = CHUNK - strm->avail_out;
86 *dest_size += have;
87 tmp_dest = realloc (*dest, *dest_size);
88 if (NULL == tmp_dest)
89 {
90 free (*dest);
91 *dest = NULL;
92 return MHD_NO;
93 }
94 *dest = tmp_dest;
95 memcpy ((*dest) + ((*dest_size) - have), tmp, have);
96 }
97 while (0 == strm->avail_out);
98 }
97 while (flush != Z_SYNC_FLUSH); 99 while (flush != Z_SYNC_FLUSH);
98 return (Z_OK == ret) ? MHD_YES : MHD_NO; 100 return (Z_OK == ret) ? MHD_YES : MHD_NO;
99} 101}
@@ -114,22 +116,23 @@ read_cb (void *cls, uint64_t pos, char *mem, size_t size)
114 return MHD_CONTENT_READER_END_WITH_ERROR; 116 return MHD_CONTENT_READER_END_WITH_ERROR;
115 ret = fread (src, 1, size, holder->file); 117 ret = fread (src, 1, size, holder->file);
116 if (ret < 0) 118 if (ret < 0)
117 { 119 {
118 ret = MHD_CONTENT_READER_END_WITH_ERROR; 120 ret = MHD_CONTENT_READER_END_WITH_ERROR;
119 goto done; 121 goto done;
120 } 122 }
121 if (0 == size) 123 if (0 == size)
122 { 124 {
123 ret = MHD_CONTENT_READER_END_OF_STREAM; 125 ret = MHD_CONTENT_READER_END_OF_STREAM;
124 goto done; 126 goto done;
125 } 127 }
126 if (MHD_YES != compress_buf (&holder->stream, src, ret, &offset, &buf, &size, holder->buf)) 128 if (MHD_YES != compress_buf (&holder->stream, src, ret, &offset, &buf, &size,
129 holder->buf))
127 ret = MHD_CONTENT_READER_END_WITH_ERROR; 130 ret = MHD_CONTENT_READER_END_WITH_ERROR;
128 else 131 else
129 { 132 {
130 memcpy (mem, buf, size); 133 memcpy (mem, buf, size);
131 ret = size; 134 ret = size;
132 } 135 }
133 free (buf); /* Buf may be set even on error return. */ 136 free (buf); /* Buf may be set even on error return. */
134done: 137done:
135 free (src); 138 free (src);
@@ -147,7 +150,8 @@ free_cb (void *cls)
147} 150}
148 151
149static int 152static int
150ahc_echo (void *cls, struct MHD_Connection *con, const char *url, const char *method, const char *version, 153ahc_echo (void *cls, struct MHD_Connection *con, const char *url, const
154 char *method, const char *version,
151 const char *upload_data, size_t *upload_size, void **ptr) 155 const char *upload_data, size_t *upload_size, void **ptr)
152{ 156{
153 struct Holder *holder; 157 struct Holder *holder;
@@ -160,27 +164,29 @@ ahc_echo (void *cls, struct MHD_Connection *con, const char *url, const char *me
160 (void) upload_data; 164 (void) upload_data;
161 (void) upload_size; 165 (void) upload_size;
162 if (NULL == *ptr) 166 if (NULL == *ptr)
163 { 167 {
164 *ptr = (void *) 1; 168 *ptr = (void *) 1;
165 return MHD_YES; 169 return MHD_YES;
166 } 170 }
167 *ptr = NULL; 171 *ptr = NULL;
168 holder = calloc (1, sizeof (struct Holder)); 172 holder = calloc (1, sizeof (struct Holder));
169 if (!holder) 173 if (! holder)
170 return MHD_NO; 174 return MHD_NO;
171 holder->file = fopen (__FILE__, "rb"); 175 holder->file = fopen (__FILE__, "rb");
172 if (NULL == holder->file) 176 if (NULL == holder->file)
173 goto file_error; 177 goto file_error;
174 ret = deflateInit(&holder->stream, Z_BEST_COMPRESSION); 178 ret = deflateInit (&holder->stream, Z_BEST_COMPRESSION);
175 if (ret != Z_OK) 179 if (ret != Z_OK)
176 goto stream_error; 180 goto stream_error;
177 holder->buf = malloc (CHUNK); 181 holder->buf = malloc (CHUNK);
178 if (NULL == holder->buf) 182 if (NULL == holder->buf)
179 goto buf_error; 183 goto buf_error;
180 res = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN, 1024, &read_cb, holder, &free_cb); 184 res = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN, 1024, &read_cb,
185 holder, &free_cb);
181 if (NULL == res) 186 if (NULL == res)
182 goto error; 187 goto error;
183 ret = MHD_add_response_header (res, MHD_HTTP_HEADER_CONTENT_ENCODING, "deflate"); 188 ret = MHD_add_response_header (res, MHD_HTTP_HEADER_CONTENT_ENCODING,
189 "deflate");
184 if (MHD_YES != ret) 190 if (MHD_YES != ret)
185 goto res_error; 191 goto res_error;
186 ret = MHD_add_response_header (res, MHD_HTTP_HEADER_CONTENT_TYPE, "text/x-c"); 192 ret = MHD_add_response_header (res, MHD_HTTP_HEADER_CONTENT_TYPE, "text/x-c");
@@ -209,18 +215,21 @@ main (int argc, char *const *argv)
209 if ((argc != 2) || 215 if ((argc != 2) ||
210 (1 != sscanf (argv[1], "%u", &port)) || 216 (1 != sscanf (argv[1], "%u", &port)) ||
211 (UINT16_MAX < port)) 217 (UINT16_MAX < port))
212 { 218 {
213 fprintf (stderr, "%s PORT\n", argv[0]); 219 fprintf (stderr, "%s PORT\n", argv[0]);
214 return 1; 220 return 1;
215 } 221 }
216 d = MHD_start_daemon (MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD, (uint16_t) port, NULL, NULL, 222 d = MHD_start_daemon (MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD,
223 (uint16_t) port, NULL, NULL,
217 &ahc_echo, NULL, 224 &ahc_echo, NULL,
218 MHD_OPTION_END); 225 MHD_OPTION_END);
219 if (NULL == d) 226 if (NULL == d)
220 return 1; 227 return 1;
221 if (0 == port) 228 if (0 == port)
222 MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT, &port); 229 MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT, &port);
223 fprintf (stdout, "HTTP server running at http://localhost:%u\n\nPress ENTER to stop the server ...\n", port); 230 fprintf (stdout,
231 "HTTP server running at http://localhost:%u\n\nPress ENTER to stop the server ...\n",
232 port);
224 (void) getc (stdin); 233 (void) getc (stdin);
225 MHD_stop_daemon (d); 234 MHD_stop_daemon (d);
226 return 0; 235 return 0;