]> git.proxmox.com Git - ceph.git/blob - ceph/src/jaegertracing/opentelemetry-cpp/third_party/prometheus-cpp/3rdparty/civetweb/src/mod_zlib.inl
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / jaegertracing / opentelemetry-cpp / third_party / prometheus-cpp / 3rdparty / civetweb / src / mod_zlib.inl
1 /* Experimental implementation for on-the-fly compression */
2 #if !defined(USE_ZLIB)
3 #error "This file must only be included, if USE_ZLIB is set"
4 #endif
5
6 #if !defined(MEM_LEVEL)
7 #define MEM_LEVEL (8)
8 #endif
9
10 static void *
11 zalloc(void *opaque, uInt items, uInt size)
12 {
13 struct mg_connection *conn = (struct mg_connection *)opaque;
14 void *ret = mg_calloc_ctx(items, size, conn->phys_ctx);
15 (void)conn; /* mg_calloc_ctx makro might not need it */
16
17 return ret;
18 }
19
20
21 static void
22 zfree(void *opaque, void *address)
23 {
24 struct mg_connection *conn = (struct mg_connection *)opaque;
25 (void)conn; /* not required */
26
27 mg_free(address);
28 }
29
30
31 static void
32 send_compressed_data(struct mg_connection *conn, struct mg_file *filep)
33 {
34
35 int zret;
36 z_stream zstream;
37 int do_flush;
38 unsigned bytes_avail;
39 unsigned char in_buf[MG_BUF_LEN];
40 unsigned char out_buf[MG_BUF_LEN];
41 FILE *in_file = filep->access.fp;
42
43 /* Prepare state buffer. User server context memory allocation. */
44 memset(&zstream, 0, sizeof(zstream));
45 zstream.zalloc = zalloc;
46 zstream.zfree = zfree;
47 zstream.opaque = (void *)conn;
48
49 /* Initialize for GZIP compression (MAX_WBITS | 16) */
50 zret = deflateInit2(&zstream,
51 Z_BEST_COMPRESSION,
52 Z_DEFLATED,
53 MAX_WBITS | 16,
54 MEM_LEVEL,
55 Z_DEFAULT_STRATEGY);
56
57 if (zret != Z_OK) {
58 mg_cry_internal(conn,
59 "GZIP init failed (%i): %s",
60 zret,
61 (zstream.msg ? zstream.msg : "<no error message>"));
62 deflateEnd(&zstream);
63 return;
64 }
65
66 /* Read until end of file */
67 do {
68 zstream.avail_in = fread(in_buf, 1, MG_BUF_LEN, in_file);
69 if (ferror(in_file)) {
70 mg_cry_internal(conn, "fread failed: %s", strerror(ERRNO));
71 (void)deflateEnd(&zstream);
72 return;
73 }
74
75 do_flush = (feof(in_file) ? Z_FINISH : Z_NO_FLUSH);
76 zstream.next_in = in_buf;
77
78 /* run deflate() on input until output buffer not full, finish
79 * compression if all of source has been read in */
80 do {
81 zstream.avail_out = MG_BUF_LEN;
82 zstream.next_out = out_buf;
83 zret = deflate(&zstream, do_flush);
84
85 if (zret == Z_STREAM_ERROR) {
86 /* deflate error */
87 zret = -97;
88 break;
89 }
90
91 bytes_avail = MG_BUF_LEN - zstream.avail_out;
92 if (bytes_avail) {
93 if (mg_send_chunk(conn, (char *)out_buf, bytes_avail) < 0) {
94 zret = -98;
95 break;
96 }
97 }
98
99 } while (zstream.avail_out == 0);
100
101 if (zret < -90) {
102 /* Forward write error */
103 break;
104 }
105
106 if (zstream.avail_in != 0) {
107 /* all input will be used, otherwise GZIP is incomplete */
108 zret = -99;
109 break;
110 }
111
112 /* done when last data in file processed */
113 } while (do_flush != Z_FINISH);
114
115 if (zret != Z_STREAM_END) {
116 /* Error: We did not compress everything. */
117 mg_cry_internal(conn,
118 "GZIP incomplete (%i): %s",
119 zret,
120 (zstream.msg ? zstream.msg : "<no error message>"));
121 }
122
123 deflateEnd(&zstream);
124
125 /* Send "end of chunked data" marker */
126 mg_write(conn, "0\r\n\r\n", 5);
127 }
128
129
130 #if defined(USE_WEBSOCKET) && defined(MG_EXPERIMENTAL_INTERFACES)
131 static int
132 websocket_deflate_initialize(struct mg_connection *conn, int server)
133 {
134 int zret =
135 deflateInit2(&conn->websocket_deflate_state,
136 Z_BEST_COMPRESSION,
137 Z_DEFLATED,
138 server
139 ? -1 * conn->websocket_deflate_server_max_windows_bits
140 : -1 * conn->websocket_deflate_client_max_windows_bits,
141 MEM_LEVEL,
142 Z_DEFAULT_STRATEGY);
143 if (zret != Z_OK) {
144 mg_cry_internal(conn,
145 "Websocket deflate init failed (%i): %s",
146 zret,
147 (conn->websocket_deflate_state.msg
148 ? conn->websocket_deflate_state.msg
149 : "<no error message>"));
150 deflateEnd(&conn->websocket_deflate_state);
151 return zret;
152 }
153
154 zret = inflateInit2(
155 &conn->websocket_inflate_state,
156 server ? -1 * conn->websocket_deflate_client_max_windows_bits
157 : -1 * conn->websocket_deflate_server_max_windows_bits);
158 if (zret != Z_OK) {
159 mg_cry_internal(conn,
160 "Websocket inflate init failed (%i): %s",
161 zret,
162 (conn->websocket_inflate_state.msg
163 ? conn->websocket_inflate_state.msg
164 : "<no error message>"));
165 inflateEnd(&conn->websocket_inflate_state);
166 return zret;
167 }
168 if ((conn->websocket_deflate_server_no_context_takeover && server)
169 || (conn->websocket_deflate_client_no_context_takeover && !server))
170 conn->websocket_deflate_flush = Z_FULL_FLUSH;
171 else
172 conn->websocket_deflate_flush = Z_SYNC_FLUSH;
173
174 conn->websocket_deflate_initialized = 1;
175 return Z_OK;
176 }
177
178
179 static void
180 websocket_deflate_negotiate(struct mg_connection *conn)
181 {
182 const char *extensions = mg_get_header(conn, "Sec-WebSocket-Extensions");
183 int val;
184 if (extensions && !strncmp(extensions, "permessage-deflate", 18)) {
185 conn->accept_gzip = 1;
186 conn->websocket_deflate_client_max_windows_bits = 15;
187 conn->websocket_deflate_server_max_windows_bits = 15;
188 conn->websocket_deflate_server_no_context_takeover = 0;
189 conn->websocket_deflate_client_no_context_takeover = 0;
190 extensions += 18;
191 while (*extensions != '\0') {
192 if (*extensions == ';' || *extensions == ' ')
193 ++extensions;
194 else if (!strncmp(extensions, "server_no_context_takeover", 26)) {
195 extensions += 26;
196 conn->websocket_deflate_server_no_context_takeover = 1;
197 } else if (!strncmp(extensions, "client_no_context_takeover", 26)) {
198 extensions += 26;
199 conn->websocket_deflate_client_no_context_takeover = 1;
200 } else if (!strncmp(extensions, "server_max_window_bits", 22)) {
201 extensions += 22;
202 if (*extensions == '=') {
203 ++extensions;
204 if (*extensions == '"')
205 ++extensions;
206 val = 0;
207 while (*extensions >= '0' && *extensions <= '9') {
208 val = val * 10 + (*extensions - '0');
209 ++extensions;
210 }
211 if (val < 9 || val > 15) {
212 // The permessage-deflate spec specifies that a
213 // value of 8 is also allowed, but zlib doesn't accept
214 // that.
215 mg_cry_internal(conn,
216 "server-max-window-bits must be "
217 "between 9 and 15. Got %i",
218 val);
219 } else
220 conn->websocket_deflate_server_max_windows_bits = val;
221 if (*extensions == '"')
222 ++extensions;
223 }
224 } else if (!strncmp(extensions, "client_max_window_bits", 22)) {
225 extensions += 22;
226 if (*extensions == '=') {
227 ++extensions;
228 if (*extensions == '"')
229 ++extensions;
230 val = 0;
231 while (*extensions >= '0' && *extensions <= '9') {
232 val = val * 10 + (*extensions - '0');
233 ++extensions;
234 }
235 if (val < 9 || val > 15)
236 // The permessage-deflate spec specifies that a
237 // value of 8 is also allowed, but zlib doesn't
238 // accept that.
239 mg_cry_internal(conn,
240 "client-max-window-bits must be "
241 "between 9 and 15. Got %i",
242 val);
243 else
244 conn->websocket_deflate_client_max_windows_bits = val;
245 if (*extensions == '"')
246 ++extensions;
247 }
248 } else {
249 mg_cry_internal(conn,
250 "Unknown parameter %s for permessage-deflate",
251 extensions);
252 break;
253 }
254 }
255 } else {
256 conn->accept_gzip = 0;
257 }
258 conn->websocket_deflate_initialized = 0;
259 }
260
261
262 static void
263 websocket_deflate_response(struct mg_connection *conn)
264 {
265 if (conn->accept_gzip) {
266 mg_printf(conn,
267 "Sec-WebSocket-Extensions: permessage-deflate; "
268 "server_max_window_bits=%i; "
269 "client_max_window_bits=%i"
270 "%s%s\r\n",
271 conn->websocket_deflate_server_max_windows_bits,
272 conn->websocket_deflate_client_max_windows_bits,
273 conn->websocket_deflate_client_no_context_takeover
274 ? "; client_no_context_takeover"
275 : "",
276 conn->websocket_deflate_server_no_context_takeover
277 ? "; server_no_context_takeover"
278 : "");
279 };
280 }
281 #endif