1 #include "private-libwebsockets.h"
3 #include "extension-deflate-frame.h"
4 #include "extension-deflate-stream.h"
6 struct lws_extension lws_internal_extensions[] = {
7 #ifdef LWS_EXT_DEFLATE_STREAM
10 lws_extension_callback_deflate_stream,
11 sizeof(struct lws_ext_deflate_stream_conn)
15 "x-webkit-deflate-frame",
16 lws_extension_callback_deflate_frame,
17 sizeof(struct lws_ext_deflate_frame_conn)
21 lws_extension_callback_deflate_frame,
22 sizeof(struct lws_ext_deflate_frame_conn)
31 lws_context_init_extensions(struct lws_context_creation_info *info,
32 struct lws_context *context)
34 context->extensions = info->extensions;
35 lwsl_info(" LWS_MAX_EXTENSIONS_ACTIVE: %u\n", LWS_MAX_EXTENSIONS_ACTIVE);
38 LWS_VISIBLE struct lws_extension *lws_get_internal_extensions()
40 return lws_internal_extensions;
44 /* 0 = nobody had nonzero return, 1 = somebody had positive return, -1 = fail */
46 int lws_ext_callback_for_each_active(struct lws *wsi, int reason,
49 int n, m, handled = 0;
51 for (n = 0; n < wsi->count_active_extensions; n++) {
52 m = wsi->active_extensions[n]->callback(
54 wsi->active_extensions[n], wsi,
56 wsi->active_extensions_user[n],
60 "Extension '%s' failed to handle callback %d!\n",
61 wsi->active_extensions[n]->name, reason);
71 int lws_ext_callback_for_each_extension_type(
72 struct lws_context *context, struct lws *wsi,
73 int reason, void *arg, int len)
75 int n = 0, m, handled = 0;
76 const struct lws_extension *ext = context->extensions;
78 while (ext && ext->callback && !handled) {
79 m = ext->callback(context, ext, wsi, reason,
80 (void *)(long)n, arg, len);
83 "Extension '%s' failed to handle callback %d!\n",
84 wsi->active_extensions[n]->name, reason);
98 lws_issue_raw_ext_access(struct lws *wsi,
99 unsigned char *buf, size_t len)
102 struct lws_tokens eff_buf;
106 eff_buf.token = (char *)buf;
107 eff_buf.token_len = len;
110 * while we have original buf to spill ourselves, or extensions report
111 * more in their pipeline
117 /* default to nobody has more to spill */
121 /* show every extension the new incoming data */
122 m = lws_ext_callback_for_each_active(wsi,
123 LWS_EXT_CALLBACK_PACKET_TX_PRESEND, &eff_buf, 0);
129 if ((char *)buf != eff_buf.token)
131 * extension recreated it:
132 * need to buffer this if not all sent
134 wsi->u.ws.clean_buffer = 0;
136 /* assuming they left us something to send, send it */
138 if (eff_buf.token_len) {
139 n = lws_issue_raw(wsi, (unsigned char *)eff_buf.token,
142 lwsl_info("closing from ext access\n");
146 /* always either sent it all or privately buffered */
147 if (wsi->u.ws.clean_buffer)
151 lwsl_parser("written %d bytes to client\n", n);
153 /* no extension has more to spill? Then we can go */
158 /* we used up what we had */
160 eff_buf.token = NULL;
161 eff_buf.token_len = 0;
164 * Did that leave the pipe choked?
165 * Or we had to hold on to some of it?
168 if (!lws_send_pipe_choked(wsi) && !wsi->truncated_send_len)
169 /* no we could add more, lets's do that */
172 lwsl_debug("choked\n");
175 * Yes, he's choked. Don't spill the rest now get a callback
176 * when he is ready to send and take care of it there
178 lws_callback_on_writable(
179 lws_get_ctx(wsi), wsi);
180 wsi->extension_data_pending = 1;
188 lws_any_extension_handled(struct lws_context *context,
190 enum lws_extension_callback_reasons r,
196 /* maybe an extension will take care of it for us */
198 for (n = 0; n < wsi->count_active_extensions && !handled; n++) {
199 if (!wsi->active_extensions[n]->callback)
202 handled |= wsi->active_extensions[n]->callback(context,
203 wsi->active_extensions[n], wsi,
204 r, wsi->active_extensions_user[n], v, len);