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)
34 /* fetch the per-frame nonce */
36 n = libwebsockets_get_random(wsi->protocol->owning_server,
37 wsi->frame_masking_nonce_04, 4);
39 lwsl_parser("Unable to read from random device %s %d\n",
40 SYSTEM_RANDOM_FILEPATH, n);
44 /* start masking from first byte of masking key buffer */
45 wsi->frame_mask_index = 0;
47 if (wsi->ietf_spec_revision != 4)
50 /* 04 only does SHA-1 more complex key */
53 * the frame key is the frame nonce (4 bytes) followed by the
54 * connection masking key, hashed by SHA1
57 memcpy(buf, wsi->frame_masking_nonce_04, 4);
59 memcpy(buf + 4, wsi->masking_key_04, 20);
61 /* concatenate the nonce with the connection key then hash it */
63 SHA1((unsigned char *)buf, 4 + 20, wsi->frame_mask_04);
69 void lws_stderr_hexdump(unsigned char *buf, size_t len)
77 for (n = 0; n < len;) {
80 lwsl_debug("%04X: ", start);
82 for (m = 0; m < 16 && n < len; m++)
83 lwsl_debug("%02X ", buf[n++]);
89 for (m = 0; m < 16 && (start + m) < len; m++) {
90 if (buf[start + m] >= ' ' && buf[start + m] <= 127)
91 lwsl_debug("%c", buf[start + m]);
103 int lws_issue_raw(struct libwebsocket *wsi, unsigned char *buf, size_t len)
109 * one of the extensions is carrying our data itself? Like mux?
112 for (n = 0; n < wsi->count_active_extensions; n++) {
114 * there can only be active extensions after handshake completed
115 * so we can rely on protocol being set already in here
117 m = wsi->active_extensions[n]->callback(
118 wsi->protocol->owning_server,
119 wsi->active_extensions[n], wsi,
120 LWS_EXT_CALLBACK_PACKET_TX_DO_SEND,
121 wsi->active_extensions_user[n], &buf, len);
123 lwsl_ext("Extension reports fatal error\n");
126 if (m) /* handled */ {
127 /* lwsl_ext("ext sent it\n"); */
133 lwsl_warn("** error 0 sock but expected to send\n");
136 * nope, send it on the socket directly
141 lws_stderr_hexdump(buf, len);
144 #ifdef LWS_OPENSSL_SUPPORT
146 n = SSL_write(wsi->ssl, buf, len);
148 lwsl_debug("ERROR writing to socket\n");
153 n = send(wsi->sock, buf, len, MSG_NOSIGNAL);
155 lwsl_debug("ERROR writing to socket\n");
158 #ifdef LWS_OPENSSL_SUPPORT
165 lws_issue_raw_ext_access(struct libwebsocket *wsi,
166 unsigned char *buf, size_t len)
169 struct lws_tokens eff_buf;
173 eff_buf.token = (char *)buf;
174 eff_buf.token_len = len;
177 * while we have original buf to spill ourselves, or extensions report
178 * more in their pipeline
184 /* default to nobody has more to spill */
188 /* show every extension the new incoming data */
190 for (n = 0; n < wsi->count_active_extensions; n++) {
191 m = wsi->active_extensions[n]->callback(
192 wsi->protocol->owning_server,
193 wsi->active_extensions[n], wsi,
194 LWS_EXT_CALLBACK_PACKET_TX_PRESEND,
195 wsi->active_extensions_user[n], &eff_buf, 0);
197 lwsl_ext("Extension: fatal error\n");
202 * at least one extension told us he has more
203 * to spill, so we will go around again after
208 /* assuming they left us something to send, send it */
210 if (eff_buf.token_len)
211 if (lws_issue_raw(wsi, (unsigned char *)eff_buf.token,
215 lwsl_parser("written %d bytes to client\n", eff_buf.token_len);
217 /* no extension has more to spill */
222 /* we used up what we had */
224 eff_buf.token = NULL;
225 eff_buf.token_len = 0;
228 * Did that leave the pipe choked?
231 if (!lws_send_pipe_choked(wsi))
232 /* no we could add more */
235 lwsl_debug("choked\n");
238 * Yes, he's choked. Don't spill the rest now get a callback
239 * when he is ready to send and take care of it there
241 libwebsocket_callback_on_writable(
242 wsi->protocol->owning_server, wsi);
243 wsi->extension_data_pending = 1;
251 * libwebsocket_write() - Apply protocol then write data to client
252 * @wsi: Websocket instance (available from user callback)
253 * @buf: The data to send. For data being sent on a websocket
254 * connection (ie, not default http), this buffer MUST have
255 * LWS_SEND_BUFFER_PRE_PADDING bytes valid BEFORE the pointer
256 * and an additional LWS_SEND_BUFFER_POST_PADDING bytes valid
257 * in the buffer after (buf + len). This is so the protocol
258 * header and trailer data can be added in-situ.
259 * @len: Count of the data bytes in the payload starting from buf
260 * @protocol: Use LWS_WRITE_HTTP to reply to an http connection, and one
261 * of LWS_WRITE_BINARY or LWS_WRITE_TEXT to send appropriate
262 * data on a websockets connection. Remember to allow the extra
263 * bytes before and after buf if LWS_WRITE_BINARY or LWS_WRITE_TEXT
266 * This function provides the way to issue data back to the client
267 * for both http and websocket protocols.
269 * In the case of sending using websocket protocol, be sure to allocate
270 * valid storage before and after buf as explained above. This scheme
271 * allows maximum efficiency of sending data and protocol in a single
272 * packet while not burdening the user code with any protocol knowledge.
275 int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf,
276 size_t len, enum libwebsocket_write_protocol protocol)
282 int masked7 = wsi->mode == LWS_CONNMODE_WS_CLIENT &&
283 wsi->xor_mask != xor_no_mask;
284 unsigned char *dropmask = NULL;
285 unsigned char is_masked_bit = 0;
286 struct lws_tokens eff_buf;
289 if (len == 0 && protocol != LWS_WRITE_CLOSE) {
290 lwsl_warn("zero length libwebsocket_write attempt\n");
294 if (protocol == LWS_WRITE_HTTP)
297 /* websocket protocol, either binary or text */
299 if (wsi->state != WSI_STATE_ESTABLISHED)
302 /* give a change to the extensions to modify payload */
303 eff_buf.token = (char *)buf;
304 eff_buf.token_len = len;
306 for (n = 0; n < wsi->count_active_extensions; n++) {
307 m = wsi->active_extensions[n]->callback(
308 wsi->protocol->owning_server,
309 wsi->active_extensions[n], wsi,
310 LWS_EXT_CALLBACK_PAYLOAD_TX,
311 wsi->active_extensions_user[n], &eff_buf, 0);
316 buf = (unsigned char *)eff_buf.token;
317 len = eff_buf.token_len;
319 switch (wsi->ietf_spec_revision) {
320 /* chrome likes this as of 30 Oct 2010 */
321 /* Firefox 4.0b6 likes this as of 30 Oct 2010 */
323 if ((protocol & 0xf) == LWS_WRITE_BINARY) {
324 /* in binary mode we send 7-bit used length blocks */
326 while (len & (127 << shift)) {
335 ((len >> shift) & 127) | 0x80;
338 ((len >> shift) & 127);
345 /* frame type = text, length-free spam mode */
349 buf[len] = 0xff; /* EOT marker */
358 dropmask = &buf[0 - pre];
359 is_masked_bit = 0x80;
365 switch (protocol & 0xf) {
367 if (wsi->ietf_spec_revision < 7)
368 n = LWS_WS_OPCODE_04__TEXT_FRAME;
370 n = LWS_WS_OPCODE_07__TEXT_FRAME;
372 case LWS_WRITE_BINARY:
373 if (wsi->ietf_spec_revision < 7)
374 n = LWS_WS_OPCODE_04__BINARY_FRAME;
376 n = LWS_WS_OPCODE_07__BINARY_FRAME;
378 case LWS_WRITE_CONTINUATION:
379 if (wsi->ietf_spec_revision < 7)
380 n = LWS_WS_OPCODE_04__CONTINUATION;
382 n = LWS_WS_OPCODE_07__CONTINUATION;
385 case LWS_WRITE_CLOSE:
386 if (wsi->ietf_spec_revision < 7)
387 n = LWS_WS_OPCODE_04__CLOSE;
389 n = LWS_WS_OPCODE_07__CLOSE;
392 * v5 mandates the first byte of close packet
393 * in both client and server directions
396 switch (wsi->ietf_spec_revision) {
401 /* we can do this because we demand post-buf */
407 case LWS_CONNMODE_WS_SERVING:
409 lwsl_debug("LWS_WRITE_CLOSE S\n");
413 case LWS_CONNMODE_WS_CLIENT:
415 lwsl_debug("LWS_WRITE_CLOSE C\n");
425 * 06 has a 2-byte status code in network order
426 * we can do this because we demand post-buf
429 if (wsi->close_reason) {
430 /* reason codes count as data bytes */
432 buf[0] = wsi->close_reason >> 8;
433 buf[1] = wsi->close_reason;
440 if (wsi->ietf_spec_revision < 7)
441 n = LWS_WS_OPCODE_04__PING;
443 n = LWS_WS_OPCODE_07__PING;
445 wsi->pings_vs_pongs++;
448 if (wsi->ietf_spec_revision < 7)
449 n = LWS_WS_OPCODE_04__PONG;
451 n = LWS_WS_OPCODE_07__PONG;
454 lwsl_warn("libwebsocket_write: unknown write "
455 "opcode / protocol\n");
459 if (!(protocol & LWS_WRITE_NO_FIN))
465 buf[-pre + 1] = len | is_masked_bit;
470 buf[-pre + 1] = 126 | is_masked_bit;
471 buf[-pre + 2] = len >> 8;
476 buf[-pre + 1] = 127 | is_masked_bit;
478 buf[-pre + 2] = (len >> 56) & 0x7f;
479 buf[-pre + 3] = len >> 48;
480 buf[-pre + 4] = len >> 40;
481 buf[-pre + 5] = len >> 32;
488 buf[-pre + 6] = len >> 24;
489 buf[-pre + 7] = len >> 16;
490 buf[-pre + 8] = len >> 8;
498 * Deal with masking if we are in client -> server direction and
499 * the protocol demands it
502 if (wsi->mode == LWS_CONNMODE_WS_CLIENT &&
503 wsi->ietf_spec_revision >= 4) {
506 * this is only useful for security tests where it's required
507 * to control the raw packet payload content
510 if (!(protocol & LWS_WRITE_CLIENT_IGNORE_XOR_MASK) &&
511 wsi->xor_mask != xor_no_mask) {
513 if (libwebsocket_0405_frame_mask_generate(wsi)) {
514 lwsl_err("libwebsocket_write: "
515 "frame mask generation failed\n");
520 if (wsi->ietf_spec_revision < 7)
522 * use the XOR masking against everything we
523 * send past the frame key
525 for (n = -pre; n < ((int)len + post); n++)
526 buf[n] = wsi->xor_mask(wsi, buf[n]);
529 * in v7, just mask the payload
531 for (n = 0; n < (int)len; n++)
533 wsi->xor_mask(wsi, dropmask[n + 4]);
536 if (wsi->ietf_spec_revision < 7) {
537 /* make space for the frame nonce in clear */
540 dropmask = &buf[0 - pre];
544 /* copy the frame nonce into place */
546 wsi->frame_masking_nonce_04, 4);
549 if (wsi->ietf_spec_revision < 7) {
551 /* make space for the frame nonce in clear */
559 if (dropmask && wsi->xor_mask != xor_no_mask) {
573 lwsl_debug("send %ld: ", len + post);
574 for (n = -pre; n < ((int)len + post); n++)
575 lwsl_debug("%02X ", buf[n]);
580 if (protocol == LWS_WRITE_HTTP) {
581 if (lws_issue_raw(wsi, (unsigned char *)buf - pre,
589 * give any active extensions a chance to munge the buffer
590 * before send. We pass in a pointer to an lws_tokens struct
591 * prepared with the default buffer and content length that's in
592 * there. Rather than rewrite the default buffer, extensions
593 * that expect to grow the buffer can adapt .token to
594 * point to their own per-connection buffer in the extension
595 * user allocation. By default with no extensions or no
596 * extension callback handling, just the normal input buffer is
597 * used then so it is efficient.
599 * callback returns 1 in case it wants to spill more buffers
602 return lws_issue_raw_ext_access(wsi, buf - pre, len + pre + post);
607 * libwebsockets_serve_http_file() - Send a file back to the client using http
608 * @context: libwebsockets context
609 * @wsi: Websocket instance (available from user callback)
610 * @file: The file to issue over http
611 * @content_type: The http content type, eg, text/html
613 * This function is intended to be called from the callback in response
614 * to http requests from the client. It allows the callback to issue
615 * local files down the http link in a single step.
618 int libwebsockets_serve_http_file(struct libwebsocket_context *context,
619 struct libwebsocket *wsi, const char *file,
620 const char *content_type)
623 struct stat stat_buf;
628 strncpy(wsi->filepath, file, sizeof wsi->filepath);
629 wsi->filepath[sizeof(wsi->filepath) - 1] = '\0';
632 fd = open(wsi->filepath, O_RDONLY | _O_BINARY);
634 fd = open(wsi->filepath, O_RDONLY);
637 p += sprintf(p, "HTTP/1.0 400 Bad\x0d\x0a"
638 "Server: libwebsockets\x0d\x0a"
641 libwebsocket_write(wsi, (unsigned char *)buf, p - buf,
647 fstat(fd, &stat_buf);
648 wsi->filelen = stat_buf.st_size;
649 p += sprintf(p, "HTTP/1.0 200 OK\x0d\x0a"
650 "Server: libwebsockets\x0d\x0a"
651 "Content-Type: %s\x0d\x0a"
652 "Content-Length: %u\x0d\x0a"
653 "\x0d\x0a", content_type,
654 (unsigned int)stat_buf.st_size);
656 n = libwebsocket_write(wsi, (unsigned char *)buf, p - buf, LWS_WRITE_HTTP);
663 wsi->state = WSI_STATE_HTTP_ISSUING_FILE;
665 while (!lws_send_pipe_choked(wsi)) {
667 n = read(fd, buf, sizeof buf);
670 m = libwebsocket_write(wsi, (unsigned char *)buf, n, LWS_WRITE_HTTP);
682 if (n < sizeof(buf) || wsi->filepos == wsi->filelen) {
683 /* oh, we were able to finish here! */
684 wsi->state = WSI_STATE_HTTP;
687 if (wsi->protocol->callback(context, wsi, LWS_CALLBACK_HTTP_FILE_COMPLETION, wsi->user_space,
688 wsi->filepath, wsi->filepos))
689 libwebsocket_close_and_free_session(context, wsi, LWS_CLOSE_STATUS_NOSTATUS);
695 /* we choked, no worries schedule service for the rest of it */
697 libwebsocket_callback_on_writable(context, wsi);
704 int libwebsockets_serve_http_file_fragment(struct libwebsocket_context *context,
705 struct libwebsocket *wsi)
713 fd = open(wsi->filepath, O_RDONLY | _O_BINARY);
715 fd = open(wsi->filepath, O_RDONLY);
720 lseek(fd, wsi->filepos, SEEK_SET);
722 while (!lws_send_pipe_choked(wsi)) {
723 n = read(fd, buf, sizeof buf);
725 libwebsocket_write(wsi, (unsigned char *)buf, n, LWS_WRITE_HTTP);
734 if (n < sizeof(buf) || wsi->filepos == wsi->filelen) {
735 wsi->state = WSI_STATE_HTTP;
741 libwebsocket_callback_on_writable(context, wsi);