diff options
Diffstat (limited to 'src/examples/http_chunked_compression.c')
-rw-r--r-- | src/examples/http_chunked_compression.c | 139 |
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 | ||
47 | struct Holder { | 47 | struct 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 | ||
53 | static int | 54 | static int |
54 | compress_buf (z_stream *strm, const void *src, size_t src_size, size_t *offset, void **dest, size_t *dest_size, | 55 | compress_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. */ |
134 | done: | 137 | done: |
135 | free (src); | 138 | free (src); |
@@ -147,7 +150,8 @@ free_cb (void *cls) | |||
147 | } | 150 | } |
148 | 151 | ||
149 | static int | 152 | static int |
150 | ahc_echo (void *cls, struct MHD_Connection *con, const char *url, const char *method, const char *version, | 153 | ahc_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; |