2 * libwebsockets - small server side websockets and web server implementation
4 * Copyright (C) 2010-2013 Andy Green <andy@warmcat.com>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation:
9 * version 2.1 of the License.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22 #include "private-libwebsockets.h"
29 libwebsocket_0405_frame_mask_generate(struct libwebsocket *wsi)
33 /* fetch the per-frame nonce */
35 n = libwebsockets_get_random(wsi->protocol->owning_server,
36 wsi->u.ws.frame_masking_nonce_04, 4);
38 lwsl_parser("Unable to read from random device %s %d\n",
39 SYSTEM_RANDOM_FILEPATH, n);
43 /* start masking from first byte of masking key buffer */
44 wsi->u.ws.frame_mask_index = 0;
51 void lwsl_hexdump(void *vbuf, size_t len)
56 unsigned char *buf = (unsigned char *)vbuf;
62 for (n = 0; n < len;) {
66 p += sprintf(p, "%04X: ", start);
68 for (m = 0; m < 16 && n < len; m++)
69 p += sprintf(p, "%02X ", buf[n++]);
75 for (m = 0; m < 16 && (start + m) < len; m++) {
76 if (buf[start + m] >= ' ' && buf[start + m] < 127)
77 *p++ = buf[start + m];
86 lwsl_debug("%s", line);
93 int lws_issue_raw(struct libwebsocket *wsi, unsigned char *buf, size_t len)
95 struct libwebsocket_context *context = wsi->protocol->owning_server;
97 #ifndef LWS_NO_EXTENSIONS
101 * one of the extensions is carrying our data itself? Like mux?
104 for (n = 0; n < wsi->count_active_extensions; n++) {
106 * there can only be active extensions after handshake completed
107 * so we can rely on protocol being set already in here
109 m = wsi->active_extensions[n]->callback(
110 wsi->protocol->owning_server,
111 wsi->active_extensions[n], wsi,
112 LWS_EXT_CALLBACK_PACKET_TX_DO_SEND,
113 wsi->active_extensions_user[n], &buf, len);
115 lwsl_ext("Extension reports fatal error\n");
118 if (m) /* handled */ {
119 /* lwsl_ext("ext sent it\n"); */
125 lwsl_warn("** error 0 sock but expected to send\n");
128 * nope, send it on the socket directly
133 lws_hexdump(buf, len);
136 lws_latency_pre(context, wsi);
137 #ifdef LWS_OPENSSL_SUPPORT
139 n = SSL_write(wsi->ssl, buf, len);
140 lws_latency(context, wsi, "SSL_write lws_issue_raw", n, n >= 0);
142 lwsl_debug("ERROR writing to socket\n");
147 n = send(wsi->sock, buf, len, MSG_NOSIGNAL);
148 lws_latency(context, wsi, "send lws_issue_raw", n, n == len);
150 lwsl_debug("ERROR writing len %d to socket %d\n", len, n);
153 #ifdef LWS_OPENSSL_SUPPORT
159 #ifdef LWS_NO_EXTENSIONS
161 lws_issue_raw_ext_access(struct libwebsocket *wsi,
162 unsigned char *buf, size_t len)
164 return lws_issue_raw(wsi, buf, len);
168 lws_issue_raw_ext_access(struct libwebsocket *wsi,
169 unsigned char *buf, size_t len)
172 struct lws_tokens eff_buf;
176 eff_buf.token = (char *)buf;
177 eff_buf.token_len = len;
180 * while we have original buf to spill ourselves, or extensions report
181 * more in their pipeline
187 /* default to nobody has more to spill */
191 /* show every extension the new incoming data */
193 for (n = 0; n < wsi->count_active_extensions; n++) {
194 m = wsi->active_extensions[n]->callback(
195 wsi->protocol->owning_server,
196 wsi->active_extensions[n], wsi,
197 LWS_EXT_CALLBACK_PACKET_TX_PRESEND,
198 wsi->active_extensions_user[n], &eff_buf, 0);
200 lwsl_ext("Extension: fatal error\n");
205 * at least one extension told us he has more
206 * to spill, so we will go around again after
211 /* assuming they left us something to send, send it */
213 if (eff_buf.token_len)
214 if (lws_issue_raw(wsi, (unsigned char *)eff_buf.token,
218 lwsl_parser("written %d bytes to client\n", eff_buf.token_len);
220 /* no extension has more to spill */
225 /* we used up what we had */
227 eff_buf.token = NULL;
228 eff_buf.token_len = 0;
231 * Did that leave the pipe choked?
234 if (!lws_send_pipe_choked(wsi))
235 /* no we could add more */
238 lwsl_debug("choked\n");
241 * Yes, he's choked. Don't spill the rest now get a callback
242 * when he is ready to send and take care of it there
244 libwebsocket_callback_on_writable(
245 wsi->protocol->owning_server, wsi);
246 wsi->extension_data_pending = 1;
255 * libwebsocket_write() - Apply protocol then write data to client
256 * @wsi: Websocket instance (available from user callback)
257 * @buf: The data to send. For data being sent on a websocket
258 * connection (ie, not default http), this buffer MUST have
259 * LWS_SEND_BUFFER_PRE_PADDING bytes valid BEFORE the pointer
260 * and an additional LWS_SEND_BUFFER_POST_PADDING bytes valid
261 * in the buffer after (buf + len). This is so the protocol
262 * header and trailer data can be added in-situ.
263 * @len: Count of the data bytes in the payload starting from buf
264 * @protocol: Use LWS_WRITE_HTTP to reply to an http connection, and one
265 * of LWS_WRITE_BINARY or LWS_WRITE_TEXT to send appropriate
266 * data on a websockets connection. Remember to allow the extra
267 * bytes before and after buf if LWS_WRITE_BINARY or LWS_WRITE_TEXT
270 * This function provides the way to issue data back to the client
271 * for both http and websocket protocols.
273 * In the case of sending using websocket protocol, be sure to allocate
274 * valid storage before and after buf as explained above. This scheme
275 * allows maximum efficiency of sending data and protocol in a single
276 * packet while not burdening the user code with any protocol knowledge.
279 int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf,
280 size_t len, enum libwebsocket_write_protocol protocol)
285 int masked7 = wsi->mode == LWS_CONNMODE_WS_CLIENT;
286 unsigned char *dropmask = NULL;
287 unsigned char is_masked_bit = 0;
288 #ifndef LWS_NO_EXTENSIONS
289 struct lws_tokens eff_buf;
293 if (len == 0 && protocol != LWS_WRITE_CLOSE) {
294 lwsl_warn("zero length libwebsocket_write attempt\n");
298 if (protocol == LWS_WRITE_HTTP)
301 /* websocket protocol, either binary or text */
303 if (wsi->state != WSI_STATE_ESTABLISHED)
306 #ifndef LWS_NO_EXTENSIONS
307 /* give a change to the extensions to modify payload */
308 eff_buf.token = (char *)buf;
309 eff_buf.token_len = len;
314 case LWS_WRITE_CLOSE:
318 for (n = 0; n < wsi->count_active_extensions; n++) {
319 m = wsi->active_extensions[n]->callback(
320 wsi->protocol->owning_server,
321 wsi->active_extensions[n], wsi,
322 LWS_EXT_CALLBACK_PAYLOAD_TX,
323 wsi->active_extensions_user[n], &eff_buf, 0);
329 buf = (unsigned char *)eff_buf.token;
330 len = eff_buf.token_len;
333 switch (wsi->ietf_spec_revision) {
337 dropmask = &buf[0 - pre];
338 is_masked_bit = 0x80;
341 switch (protocol & 0xf) {
343 n = LWS_WS_OPCODE_07__TEXT_FRAME;
345 case LWS_WRITE_BINARY:
346 n = LWS_WS_OPCODE_07__BINARY_FRAME;
348 case LWS_WRITE_CONTINUATION:
349 n = LWS_WS_OPCODE_07__CONTINUATION;
352 case LWS_WRITE_CLOSE:
353 n = LWS_WS_OPCODE_07__CLOSE;
356 * 06+ has a 2-byte status code in network order
357 * we can do this because we demand post-buf
360 if (wsi->u.ws.close_reason) {
361 /* reason codes count as data bytes */
363 buf[0] = wsi->u.ws.close_reason >> 8;
364 buf[1] = wsi->u.ws.close_reason;
369 n = LWS_WS_OPCODE_07__PING;
372 n = LWS_WS_OPCODE_07__PONG;
375 lwsl_warn("libwebsocket_write: unknown write "
376 "opcode / protocol\n");
380 if (!(protocol & LWS_WRITE_NO_FIN))
386 buf[-pre + 1] = len | is_masked_bit;
391 buf[-pre + 1] = 126 | is_masked_bit;
392 buf[-pre + 2] = len >> 8;
397 buf[-pre + 1] = 127 | is_masked_bit;
399 buf[-pre + 2] = (len >> 56) & 0x7f;
400 buf[-pre + 3] = len >> 48;
401 buf[-pre + 4] = len >> 40;
402 buf[-pre + 5] = len >> 32;
409 buf[-pre + 6] = len >> 24;
410 buf[-pre + 7] = len >> 16;
411 buf[-pre + 8] = len >> 8;
419 * Deal with masking if we are in client -> server direction and
420 * the protocol demands it
423 if (wsi->mode == LWS_CONNMODE_WS_CLIENT) {
425 if (libwebsocket_0405_frame_mask_generate(wsi)) {
426 lwsl_err("libwebsocket_write: "
427 "frame mask generation failed\n");
432 * in v7, just mask the payload
434 for (n = 4; n < (int)len + 4; n++)
435 dropmask[n] = dropmask[n] ^ wsi->u.ws.frame_masking_nonce_04[(wsi->u.ws.frame_mask_index++) & 3];
438 /* copy the frame nonce into place */
440 wsi->u.ws.frame_masking_nonce_04, 4);
446 lwsl_debug("send %ld: ", len + post);
447 lwsl_hexdump(&buf[-pre], len + post);
451 case LWS_WRITE_CLOSE:
452 // lwsl_hexdump(&buf[-pre], len + post);
456 if (lws_issue_raw(wsi, (unsigned char *)buf - pre,
466 * give any active extensions a chance to munge the buffer
467 * before send. We pass in a pointer to an lws_tokens struct
468 * prepared with the default buffer and content length that's in
469 * there. Rather than rewrite the default buffer, extensions
470 * that expect to grow the buffer can adapt .token to
471 * point to their own per-connection buffer in the extension
472 * user allocation. By default with no extensions or no
473 * extension callback handling, just the normal input buffer is
474 * used then so it is efficient.
476 * callback returns 1 in case it wants to spill more buffers
479 return lws_issue_raw_ext_access(wsi, buf - pre, len + pre + post);
482 int libwebsockets_serve_http_file_fragment(struct libwebsocket_context *context,
483 struct libwebsocket *wsi)
488 while (!lws_send_pipe_choked(wsi)) {
489 n = read(wsi->u.http.fd, context->service_buffer, sizeof(context->service_buffer));
491 libwebsocket_write(wsi, context->service_buffer, n, LWS_WRITE_HTTP);
492 wsi->u.http.filepos += n;
496 return 1; /* caller will close */
498 if (n < sizeof(context->service_buffer) || wsi->u.http.filepos == wsi->u.http.filelen) {
499 wsi->state = WSI_STATE_HTTP;
501 if (wsi->protocol->callback)
502 ret = user_callback_handle_rxflow(wsi->protocol->callback, context, wsi, LWS_CALLBACK_HTTP_FILE_COMPLETION, wsi->user_space,
508 lwsl_notice("choked before able to send whole file (post)\n");
509 libwebsocket_callback_on_writable(context, wsi);
515 * libwebsockets_serve_http_file() - Send a file back to the client using http
516 * @context: libwebsockets context
517 * @wsi: Websocket instance (available from user callback)
518 * @file: The file to issue over http
519 * @content_type: The http content type, eg, text/html
521 * This function is intended to be called from the callback in response
522 * to http requests from the client. It allows the callback to issue
523 * local files down the http link in a single step.
525 * Returning <0 indicates error and the wsi should be closed. Returning
526 * >0 indicates the file was completely sent and the wsi should be closed.
527 * ==0 indicates the file transfer is started and needs more service later,
528 * the wsi should be left alone.
531 int libwebsockets_serve_http_file(struct libwebsocket_context *context,
532 struct libwebsocket *wsi, const char *file,
533 const char *content_type)
535 struct stat stat_buf;
536 unsigned char *p = context->service_buffer;
539 wsi->u.http.fd = open(file, O_RDONLY
545 if (wsi->u.http.fd < 1) {
546 p += sprintf((char *)p, "HTTP/1.0 400 Bad\x0d\x0a"
547 "Server: libwebsockets\x0d\x0a"
551 libwebsocket_write(wsi, context->service_buffer,
552 p - context->service_buffer, LWS_WRITE_HTTP);
557 fstat(wsi->u.http.fd, &stat_buf);
558 wsi->u.http.filelen = stat_buf.st_size;
559 p += sprintf((char *)p, "HTTP/1.0 200 OK\x0d\x0a"
560 "Server: libwebsockets\x0d\x0a"
561 "Content-Type: %s\x0d\x0a"
562 "Content-Length: %u\x0d\x0a"
563 "\x0d\x0a", content_type,
564 (unsigned int)stat_buf.st_size);
566 ret = libwebsocket_write(wsi, context->service_buffer,
567 p - context->service_buffer, LWS_WRITE_HTTP);
571 wsi->u.http.filepos = 0;
572 wsi->state = WSI_STATE_HTTP_ISSUING_FILE;
574 return libwebsockets_serve_http_file_fragment(context, wsi);