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);
94 * notice this returns number of bytes sent, or -1
97 int lws_issue_raw(struct libwebsocket *wsi, unsigned char *buf, size_t len)
99 struct libwebsocket_context *context = wsi->protocol->owning_server;
101 #ifndef LWS_NO_EXTENSIONS
105 * one of the extensions is carrying our data itself? Like mux?
108 for (n = 0; n < wsi->count_active_extensions; n++) {
110 * there can only be active extensions after handshake completed
111 * so we can rely on protocol being set already in here
113 m = wsi->active_extensions[n]->callback(
114 wsi->protocol->owning_server,
115 wsi->active_extensions[n], wsi,
116 LWS_EXT_CALLBACK_PACKET_TX_DO_SEND,
117 wsi->active_extensions_user[n], &buf, len);
119 lwsl_ext("Extension reports fatal error\n");
122 if (m) /* handled */ {
123 /* lwsl_ext("ext sent it\n"); */
129 lwsl_warn("** error 0 sock but expected to send\n");
132 * nope, send it on the socket directly
137 lws_hexdump(buf, len);
140 lws_latency_pre(context, wsi);
141 #ifdef LWS_OPENSSL_SUPPORT
143 n = SSL_write(wsi->ssl, buf, len);
144 lws_latency(context, wsi, "SSL_write lws_issue_raw", n, n >= 0);
146 lwsl_debug("ERROR writing to socket\n");
151 n = send(wsi->sock, buf, len, MSG_NOSIGNAL);
152 lws_latency(context, wsi, "send lws_issue_raw", n, n == len);
154 lwsl_debug("ERROR writing len %d to skt %d\n", len, n);
157 #ifdef LWS_OPENSSL_SUPPORT
163 #ifdef LWS_NO_EXTENSIONS
165 lws_issue_raw_ext_access(struct libwebsocket *wsi,
166 unsigned char *buf, size_t len)
168 return lws_issue_raw(wsi, buf, len);
172 lws_issue_raw_ext_access(struct libwebsocket *wsi,
173 unsigned char *buf, size_t len)
176 struct lws_tokens eff_buf;
180 eff_buf.token = (char *)buf;
181 eff_buf.token_len = len;
184 * while we have original buf to spill ourselves, or extensions report
185 * more in their pipeline
191 /* default to nobody has more to spill */
195 /* show every extension the new incoming data */
197 for (n = 0; n < wsi->count_active_extensions; n++) {
198 m = wsi->active_extensions[n]->callback(
199 wsi->protocol->owning_server,
200 wsi->active_extensions[n], wsi,
201 LWS_EXT_CALLBACK_PACKET_TX_PRESEND,
202 wsi->active_extensions_user[n], &eff_buf, 0);
204 lwsl_ext("Extension: fatal error\n");
209 * at least one extension told us he has more
210 * to spill, so we will go around again after
215 /* assuming they left us something to send, send it */
217 if (eff_buf.token_len) {
218 n = lws_issue_raw(wsi, (unsigned char *)eff_buf.token,
223 * Keep amount spilled small to minimize chance of this
225 if (n != eff_buf.token_len) {
226 lwsl_err("Unable to spill ext %d vs %s\n",
227 eff_buf.token_len, n);
233 lwsl_parser("written %d bytes to client\n", eff_buf.token_len);
235 /* no extension has more to spill */
240 /* we used up what we had */
242 eff_buf.token = NULL;
243 eff_buf.token_len = 0;
246 * Did that leave the pipe choked?
249 if (!lws_send_pipe_choked(wsi))
250 /* no we could add more */
253 lwsl_debug("choked\n");
256 * Yes, he's choked. Don't spill the rest now get a callback
257 * when he is ready to send and take care of it there
259 libwebsocket_callback_on_writable(
260 wsi->protocol->owning_server, wsi);
261 wsi->extension_data_pending = 1;
270 * libwebsocket_write() - Apply protocol then write data to client
271 * @wsi: Websocket instance (available from user callback)
272 * @buf: The data to send. For data being sent on a websocket
273 * connection (ie, not default http), this buffer MUST have
274 * LWS_SEND_BUFFER_PRE_PADDING bytes valid BEFORE the pointer
275 * and an additional LWS_SEND_BUFFER_POST_PADDING bytes valid
276 * in the buffer after (buf + len). This is so the protocol
277 * header and trailer data can be added in-situ.
278 * @len: Count of the data bytes in the payload starting from buf
279 * @protocol: Use LWS_WRITE_HTTP to reply to an http connection, and one
280 * of LWS_WRITE_BINARY or LWS_WRITE_TEXT to send appropriate
281 * data on a websockets connection. Remember to allow the extra
282 * bytes before and after buf if LWS_WRITE_BINARY or LWS_WRITE_TEXT
285 * This function provides the way to issue data back to the client
286 * for both http and websocket protocols.
288 * In the case of sending using websocket protocol, be sure to allocate
289 * valid storage before and after buf as explained above. This scheme
290 * allows maximum efficiency of sending data and protocol in a single
291 * packet while not burdening the user code with any protocol knowledge.
293 * Return may be -1 for a fatal error needing connection close, or a
294 * positive number reflecting the amount of bytes actually sent. This
295 * can be less than the requested number of bytes due to OS memory
296 * pressure at any given time.
299 int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf,
300 size_t len, enum libwebsocket_write_protocol protocol)
305 int masked7 = wsi->mode == LWS_CONNMODE_WS_CLIENT;
306 unsigned char *dropmask = NULL;
307 unsigned char is_masked_bit = 0;
308 size_t orig_len = len;
309 #ifndef LWS_NO_EXTENSIONS
310 struct lws_tokens eff_buf;
314 if (len == 0 && protocol != LWS_WRITE_CLOSE) {
315 lwsl_warn("zero length libwebsocket_write attempt\n");
319 if (protocol == LWS_WRITE_HTTP)
322 /* websocket protocol, either binary or text */
324 if (wsi->state != WSI_STATE_ESTABLISHED)
327 #ifndef LWS_NO_EXTENSIONS
328 /* give a change to the extensions to modify payload */
329 eff_buf.token = (char *)buf;
330 eff_buf.token_len = len;
335 case LWS_WRITE_CLOSE:
339 for (n = 0; n < wsi->count_active_extensions; n++) {
340 m = wsi->active_extensions[n]->callback(
341 wsi->protocol->owning_server,
342 wsi->active_extensions[n], wsi,
343 LWS_EXT_CALLBACK_PAYLOAD_TX,
344 wsi->active_extensions_user[n], &eff_buf, 0);
350 buf = (unsigned char *)eff_buf.token;
351 len = eff_buf.token_len;
354 switch (wsi->ietf_spec_revision) {
358 dropmask = &buf[0 - pre];
359 is_masked_bit = 0x80;
362 switch (protocol & 0xf) {
364 n = LWS_WS_OPCODE_07__TEXT_FRAME;
366 case LWS_WRITE_BINARY:
367 n = LWS_WS_OPCODE_07__BINARY_FRAME;
369 case LWS_WRITE_CONTINUATION:
370 n = LWS_WS_OPCODE_07__CONTINUATION;
373 case LWS_WRITE_CLOSE:
374 n = LWS_WS_OPCODE_07__CLOSE;
377 * 06+ has a 2-byte status code in network order
378 * we can do this because we demand post-buf
381 if (wsi->u.ws.close_reason) {
382 /* reason codes count as data bytes */
384 buf[0] = wsi->u.ws.close_reason >> 8;
385 buf[1] = wsi->u.ws.close_reason;
390 n = LWS_WS_OPCODE_07__PING;
393 n = LWS_WS_OPCODE_07__PONG;
396 lwsl_warn("lws_write: unknown write opc / protocol\n");
400 if (!(protocol & LWS_WRITE_NO_FIN))
406 buf[-pre + 1] = len | is_masked_bit;
411 buf[-pre + 1] = 126 | is_masked_bit;
412 buf[-pre + 2] = len >> 8;
417 buf[-pre + 1] = 127 | is_masked_bit;
419 buf[-pre + 2] = (len >> 56) & 0x7f;
420 buf[-pre + 3] = len >> 48;
421 buf[-pre + 4] = len >> 40;
422 buf[-pre + 5] = len >> 32;
429 buf[-pre + 6] = len >> 24;
430 buf[-pre + 7] = len >> 16;
431 buf[-pre + 8] = len >> 8;
439 * Deal with masking if we are in client -> server direction and
440 * the protocol demands it
443 if (wsi->mode == LWS_CONNMODE_WS_CLIENT) {
445 if (libwebsocket_0405_frame_mask_generate(wsi)) {
446 lwsl_err("lws_write: frame mask generation failed\n");
451 * in v7, just mask the payload
453 for (n = 4; n < (int)len + 4; n++)
454 dropmask[n] = dropmask[n] ^
455 wsi->u.ws.frame_masking_nonce_04[
456 (wsi->u.ws.frame_mask_index++) & 3];
459 /* copy the frame nonce into place */
461 wsi->u.ws.frame_masking_nonce_04, 4);
467 lwsl_debug("send %ld: ", len + post);
468 lwsl_hexdump(&buf[-pre], len + post);
472 case LWS_WRITE_CLOSE:
473 /* lwsl_hexdump(&buf[-pre], len + post); */
477 return lws_issue_raw(wsi, (unsigned char *)buf - pre,
484 * give any active extensions a chance to munge the buffer
485 * before send. We pass in a pointer to an lws_tokens struct
486 * prepared with the default buffer and content length that's in
487 * there. Rather than rewrite the default buffer, extensions
488 * that expect to grow the buffer can adapt .token to
489 * point to their own per-connection buffer in the extension
490 * user allocation. By default with no extensions or no
491 * extension callback handling, just the normal input buffer is
492 * used then so it is efficient.
494 * callback returns 1 in case it wants to spill more buffers
497 n = lws_issue_raw_ext_access(wsi, buf - pre, len + pre + post);
501 return orig_len - ((len - pre + post) -n );
504 int libwebsockets_serve_http_file_fragment(
505 struct libwebsocket_context *context, struct libwebsocket *wsi)
510 while (!lws_send_pipe_choked(wsi)) {
511 n = read(wsi->u.http.fd, context->service_buffer,
512 sizeof(context->service_buffer));
514 m = libwebsocket_write(wsi, context->service_buffer, n,
519 wsi->u.http.filepos += n;
521 /* adjust for what was not sent */
522 lseek(wsi->u.http.fd, m - n, SEEK_CUR);
526 return -1; /* caller will close */
528 if (n < sizeof(context->service_buffer) ||
529 wsi->u.http.filepos == wsi->u.http.filelen) {
530 wsi->state = WSI_STATE_HTTP;
532 if (wsi->protocol->callback)
533 ret = user_callback_handle_rxflow(
534 wsi->protocol->callback, context, wsi,
535 LWS_CALLBACK_HTTP_FILE_COMPLETION,
536 wsi->user_space, NULL, 0);
541 lwsl_notice("choked before able to send whole file (post)\n");
542 libwebsocket_callback_on_writable(context, wsi);
548 * libwebsockets_serve_http_file() - Send a file back to the client using http
549 * @context: libwebsockets context
550 * @wsi: Websocket instance (available from user callback)
551 * @file: The file to issue over http
552 * @content_type: The http content type, eg, text/html
554 * This function is intended to be called from the callback in response
555 * to http requests from the client. It allows the callback to issue
556 * local files down the http link in a single step.
558 * Returning <0 indicates error and the wsi should be closed. Returning
559 * >0 indicates the file was completely sent and the wsi should be closed.
560 * ==0 indicates the file transfer is started and needs more service later,
561 * the wsi should be left alone.
564 int libwebsockets_serve_http_file(struct libwebsocket_context *context,
565 struct libwebsocket *wsi, const char *file,
566 const char *content_type)
568 struct stat stat_buf;
569 unsigned char *p = context->service_buffer;
572 wsi->u.http.fd = open(file, O_RDONLY
578 if (wsi->u.http.fd < 1) {
579 p += sprintf((char *)p,
580 "HTTP/1.0 400 Bad\x0d\x0aServer: libwebsockets\x0d\x0a\x0d\x0a"
583 /* too small to care about partial, closing anyway */
584 libwebsocket_write(wsi, context->service_buffer,
585 p - context->service_buffer, LWS_WRITE_HTTP);
590 fstat(wsi->u.http.fd, &stat_buf);
591 wsi->u.http.filelen = stat_buf.st_size;
592 p += sprintf((char *)p,
593 "HTTP/1.0 200 OK\x0d\x0aServer: libwebsockets\x0d\x0a""Content-Type: %s\x0d\x0a",
595 p += sprintf((char *)p,
596 "Content-Length: %u\x0d\x0a\x0d\x0a",
597 (unsigned int)stat_buf.st_size);
599 ret = libwebsocket_write(wsi, context->service_buffer,
600 p - context->service_buffer, LWS_WRITE_HTTP);
601 if (ret != (p - context->service_buffer)) {
602 lwsl_err("_write returned %d from %d\n", ret, (p - context->service_buffer));
606 wsi->u.http.filepos = 0;
607 wsi->state = WSI_STATE_HTTP_ISSUING_FILE;
609 return libwebsockets_serve_http_file_fragment(context, wsi);