aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsilvioprog <silvioprog@gmail.com>2019-01-08 03:00:17 -0300
committersilvioprog <silvioprog@gmail.com>2019-01-08 03:00:17 -0300
commitdad0746a1006e7c2bd856fd4767b34c7cd6e0f74 (patch)
treeed570cc192636e77af40252592cc8294f390ff56
parentb7052c04159e2d04482328f518dafc27e358cc65 (diff)
downloadlibmicrohttpd-dad0746a1006e7c2bd856fd4767b34c7cd6e0f74.tar.gz
libmicrohttpd-dad0746a1006e7c2bd856fd4767b34c7cd6e0f74.zip
Added minimal example for how to compress HTTP response. (#4914)
-rw-r--r--ChangeLog3
-rw-r--r--configure.ac3
-rw-r--r--src/examples/Makefile.am13
-rw-r--r--src/examples/http_compression.c177
4 files changed, 196 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 1227571f..aaf17bb2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
1Tue Jan 8 02:57:21 BRT 2019
2 Added minimal example for how to compress HTTP response. -SC
3
1Wed Dec 19 00:06:03 CET 2018 4Wed Dec 19 00:06:03 CET 2018
2 Check for GNUTLS_E_AGAIN instead of GNUTLS_E_INTERRUPTED when 5 Check for GNUTLS_E_AGAIN instead of GNUTLS_E_INTERRUPTED when
3 giving up on a TLS connection. -LM/CG 6 giving up on a TLS connection. -LM/CG
diff --git a/configure.ac b/configure.ac
index 44c7d294..cfe7af90 100644
--- a/configure.ac
+++ b/configure.ac
@@ -766,6 +766,9 @@ AM_CONDITIONAL([MHD_HAVE_TSEARCH], [[test "x$ac_cv_header_search_h" = xyes && te
766AC_CHECK_HEADERS([dlfcn.h],[have_tlsplugin=yes],[have_tlsplugin=no], [AC_INCLUDES_DEFAULT]) 766AC_CHECK_HEADERS([dlfcn.h],[have_tlsplugin=yes],[have_tlsplugin=no], [AC_INCLUDES_DEFAULT])
767AM_CONDITIONAL([MHD_HAVE_TLS_PLUGIN], [[test "x$have_tlsplugin" = xyes]]) 767AM_CONDITIONAL([MHD_HAVE_TLS_PLUGIN], [[test "x$have_tlsplugin" = xyes]])
768 768
769AC_CHECK_HEADERS([zlib.h],[have_zlib=yes],[have_zlib=no], [AC_INCLUDES_DEFAULT])
770AM_CONDITIONAL([HAVE_ZLIB], [[test "x$have_zlib" = xyes]])
771
769# Check for generic functions 772# Check for generic functions
770AC_CHECK_FUNCS([rand random]) 773AC_CHECK_FUNCS([rand random])
771 774
diff --git a/src/examples/Makefile.am b/src/examples/Makefile.am
index 545a236a..ce01107a 100644
--- a/src/examples/Makefile.am
+++ b/src/examples/Makefile.am
@@ -68,6 +68,11 @@ noinst_PROGRAMS += \
68endif 68endif
69endif 69endif
70 70
71if HAVE_ZLIB
72noinst_PROGRAMS += \
73 http_compression
74endif
75
71if HAVE_W32 76if HAVE_W32
72AM_CFLAGS += -DWINDOWS 77AM_CFLAGS += -DWINDOWS
73endif 78endif
@@ -198,3 +203,11 @@ https_fileserver_example_CPPFLAGS = \
198 $(AM_CPPFLAGS) $(GNUTLS_CPPFLAGS) 203 $(AM_CPPFLAGS) $(GNUTLS_CPPFLAGS)
199https_fileserver_example_LDADD = \ 204https_fileserver_example_LDADD = \
200 $(top_builddir)/src/microhttpd/libmicrohttpd.la 205 $(top_builddir)/src/microhttpd/libmicrohttpd.la
206
207http_compression_SOURCES = \
208 http_compression.c
209http_compression_LDADD = \
210 $(top_builddir)/src/microhttpd/libmicrohttpd.la
211if HAVE_ZLIB
212 http_compression_LDADD += -lz
213endif \ No newline at end of file
diff --git a/src/examples/http_compression.c b/src/examples/http_compression.c
new file mode 100644
index 00000000..a88be54e
--- /dev/null
+++ b/src/examples/http_compression.c
@@ -0,0 +1,177 @@
1/*
2 This file is part of libmicrohttpd
3 Copyright (C) 2019 Christian Grothoff (and other contributing authors)
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library 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 GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18*/
19/**
20 * @file http_compression.c
21 * @brief minimal example for how to compress HTTP response
22 * @author Silvio Clecio (silvioprog)
23 */
24
25#include "platform.h"
26#include <zlib.h>
27#include <microhttpd.h>
28
29#define PAGE \
30 "<html><head><title>HTTP compression</title></head><body>Hello, " \
31 "hello, hello. This is a 'hello world' message for the world, " \
32 "repeat, for the world.</body></html>"
33
34static int
35can_compress (struct MHD_Connection *con)
36{
37 const char *ae;
38 const char *de;
39
40 ae = MHD_lookup_connection_value (con,
41 MHD_HEADER_KIND,
42 MHD_HTTP_HEADER_ACCEPT_ENCODING);
43 if (NULL == ae)
44 return MHD_NO;
45 if (0 == strcmp (ae,
46 "*"))
47 return MHD_YES;
48 de = strstr (ae,
49 "deflate");
50 if (NULL == de)
51 return MHD_NO;
52 if (((de == ae) ||
53 (de[-1] == ',') ||
54 (de[-1] == ' ')) &&
55 ((de[strlen ("deflate")] == '\0') ||
56 (de[strlen ("deflate")] == ',') ||
57 (de[strlen ("deflate")] == ';')))
58 return MHD_YES;
59 return MHD_NO;
60}
61
62static int
63body_compress (void **buf,
64 size_t *buf_size)
65{
66 Bytef *cbuf;
67 uLongf cbuf_size;
68 int ret;
69
70 cbuf_size = compressBound (*buf_size);
71 cbuf = malloc (cbuf_size);
72 if (NULL == cbuf)
73 return MHD_NO;
74 ret = compress (cbuf,
75 &cbuf_size,
76 (const Bytef *) *buf,
77 *buf_size);
78 if ((Z_OK != ret) ||
79 (cbuf_size >= *buf_size))
80 {
81 /* compression failed */
82 free (cbuf);
83 return MHD_NO;
84 }
85 free (*buf);
86 *buf = (void *) cbuf;
87 *buf_size = (size_t) cbuf_size;
88 return MHD_YES;
89}
90
91static int
92ahc_echo (void *cls,
93 struct MHD_Connection *connection,
94 const char *url,
95 const char *method,
96 const char *version,
97 const char *upload_data, size_t *upload_data_size, void **ptr)
98{
99 struct MHD_Response *response;
100 int ret;
101 int comp;
102 size_t body_len;
103 char *body_str;
104 (void) url; /* Unused. Silent compiler warning. */
105 (void) version; /* Unused. Silent compiler warning. */
106 (void) upload_data; /* Unused. Silent compiler warning. */
107 (void) upload_data_size; /* Unused. Silent compiler warning. */
108
109 if (0 != strcmp (method, "GET"))
110 return MHD_NO; /* unexpected method */
111 if (!*ptr)
112 {
113 *ptr = (void *) 1;
114 return MHD_YES;
115 }
116 *ptr = NULL;
117
118 body_str = strdup (PAGE);
119 if (NULL == body_str)
120 {
121 return MHD_NO;
122 }
123 body_len = strlen (body_str);
124 /* try to compress the body */
125 comp = MHD_NO;
126 if (MHD_YES ==
127 can_compress (connection))
128 comp = body_compress ((void **) &body_str,
129 &body_len);
130 response = MHD_create_response_from_buffer (body_len,
131 body_str,
132 MHD_RESPMEM_MUST_FREE);
133 if (NULL == response)
134 {
135 free (body_str);
136 return MHD_NO;
137 }
138
139 if (MHD_YES == comp)
140 {
141 /* Need to indicate to client that body is compressed */
142 if (MHD_NO ==
143 MHD_add_response_header (response,
144 MHD_HTTP_HEADER_CONTENT_ENCODING,
145 "deflate"))
146 {
147 MHD_destroy_response (response);
148 return MHD_NO;
149 }
150 }
151 ret = MHD_queue_response (connection,
152 200,
153 response);
154 MHD_destroy_response (response);
155 return ret;
156}
157
158int
159main (int argc, char *const *argv)
160{
161 struct MHD_Daemon *d;
162
163 if (argc != 2)
164 {
165 printf ("%s PORT\n", argv[0]);
166 return 1;
167 }
168 d = MHD_start_daemon (MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
169 atoi (argv[1]), NULL, NULL,
170 &ahc_echo, NULL,
171 MHD_OPTION_END);
172 if (NULL == d)
173 return 1;
174 (void) getc (stdin);
175 MHD_stop_daemon (d);
176 return 0;
177}