remove all support for pre v13 protocols
[profile/ivi/libwebsockets.git] / lib / output.c
1 /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2010-2013 Andy Green <andy@warmcat.com>
5  *
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.
10  *
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.
15  *
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,
19  *  MA  02110-1301  USA
20  */
21
22 #include "private-libwebsockets.h"
23
24 #ifdef WIN32
25 #include <io.h>
26 #endif
27
28 static int
29 libwebsocket_0405_frame_mask_generate(struct libwebsocket *wsi)
30 {
31         int n;
32
33         /* fetch the per-frame nonce */
34
35         n = libwebsockets_get_random(wsi->protocol->owning_server,
36                                                 wsi->frame_masking_nonce_04, 4);
37         if (n != 4) {
38                 lwsl_parser("Unable to read from random device %s %d\n",
39                                                      SYSTEM_RANDOM_FILEPATH, n);
40                 return 1;
41         }
42
43         /* start masking from first byte of masking key buffer */
44         wsi->frame_mask_index = 0;
45
46         return 0;
47 }
48
49 #ifdef _DEBUG
50
51 void lwsl_hexdump(void *vbuf, size_t len)
52 {
53         int n;
54         int m;
55         int start;
56         unsigned char *buf = (unsigned char *)vbuf;
57         char line[80];
58         char *p;
59
60         lwsl_parser("\n");
61
62         for (n = 0; n < len;) {
63                 start = n;
64                 p = line;
65
66                 p += sprintf(p, "%04X: ", start);
67
68                 for (m = 0; m < 16 && n < len; m++)
69                         p += sprintf(p, "%02X ", buf[n++]);
70                 while (m++ < 16)
71                         p += sprintf(p, "   ");
72
73                 p += sprintf(p, "   ");
74
75                 for (m = 0; m < 16 && (start + m) < len; m++) {
76                         if (buf[start + m] >= ' ' && buf[start + m] < 127)
77                                 *p++ = buf[start + m];
78                         else
79                                 *p++ = '.';
80                 }
81                 while (m++ < 16)
82                         *p++ = ' ';
83
84                 *p++ = '\n';
85                 *p = '\0';
86                 lwsl_debug("%s", line);
87         }
88         lwsl_debug("\n");
89 }
90
91 #endif
92
93 int lws_issue_raw(struct libwebsocket *wsi, unsigned char *buf, size_t len)
94 {
95         int n;
96 #ifndef LWS_NO_EXTENSIONS
97         int m;
98
99         /*
100          * one of the extensions is carrying our data itself?  Like mux?
101          */
102
103         for (n = 0; n < wsi->count_active_extensions; n++) {
104                 /*
105                  * there can only be active extensions after handshake completed
106                  * so we can rely on protocol being set already in here
107                  */
108                 m = wsi->active_extensions[n]->callback(
109                                 wsi->protocol->owning_server,
110                                 wsi->active_extensions[n], wsi,
111                                 LWS_EXT_CALLBACK_PACKET_TX_DO_SEND,
112                                      wsi->active_extensions_user[n], &buf, len);
113                 if (m < 0) {
114                         lwsl_ext("Extension reports fatal error\n");
115                         return -1;
116                 }
117                 if (m) /* handled */ {
118 /*                      lwsl_ext("ext sent it\n"); */
119                         return 0;
120                 }
121         }
122 #endif
123         if (!wsi->sock)
124                 lwsl_warn("** error 0 sock but expected to send\n");
125
126         /*
127          * nope, send it on the socket directly
128          */
129
130 #if 0
131         lwsl_debug("  TX: ");
132         lws_hexdump(buf, len);
133 #endif
134
135 #ifdef LWS_OPENSSL_SUPPORT
136         if (wsi->ssl) {
137                 n = SSL_write(wsi->ssl, buf, len);
138                 if (n < 0) {
139                         lwsl_debug("ERROR writing to socket\n");
140                         return -1;
141                 }
142         } else {
143 #endif
144                 n = send(wsi->sock, buf, len, MSG_NOSIGNAL);
145                 if (n != len) {
146                         lwsl_debug("ERROR writing len %d to socket %d\n", len, n);
147                         return -1;
148                 }
149 #ifdef LWS_OPENSSL_SUPPORT
150         }
151 #endif
152         return 0;
153 }
154
155 #ifdef LWS_NO_EXTENSIONS
156 int
157 lws_issue_raw_ext_access(struct libwebsocket *wsi,
158                                                  unsigned char *buf, size_t len)
159 {
160         return lws_issue_raw(wsi, buf, len);
161 }
162 #else
163 int
164 lws_issue_raw_ext_access(struct libwebsocket *wsi,
165                                                  unsigned char *buf, size_t len)
166 {
167         int ret;
168         struct lws_tokens eff_buf;
169         int m;
170         int n;
171
172         eff_buf.token = (char *)buf;
173         eff_buf.token_len = len;
174
175         /*
176          * while we have original buf to spill ourselves, or extensions report
177          * more in their pipeline
178          */
179
180         ret = 1;
181         while (ret == 1) {
182
183                 /* default to nobody has more to spill */
184
185                 ret = 0;
186
187                 /* show every extension the new incoming data */
188
189                 for (n = 0; n < wsi->count_active_extensions; n++) {
190                         m = wsi->active_extensions[n]->callback(
191                                         wsi->protocol->owning_server,
192                                         wsi->active_extensions[n], wsi,
193                                         LWS_EXT_CALLBACK_PACKET_TX_PRESEND,
194                                    wsi->active_extensions_user[n], &eff_buf, 0);
195                         if (m < 0) {
196                                 lwsl_ext("Extension: fatal error\n");
197                                 return -1;
198                         }
199                         if (m)
200                                 /*
201                                  * at least one extension told us he has more
202                                  * to spill, so we will go around again after
203                                  */
204                                 ret = 1;
205                 }
206
207                 /* assuming they left us something to send, send it */
208
209                 if (eff_buf.token_len)
210                         if (lws_issue_raw(wsi, (unsigned char *)eff_buf.token,
211                                                             eff_buf.token_len))
212                                 return -1;
213
214                 lwsl_parser("written %d bytes to client\n", eff_buf.token_len);
215
216                 /* no extension has more to spill */
217
218                 if (!ret)
219                         break;
220
221                 /* we used up what we had */
222
223                 eff_buf.token = NULL;
224                 eff_buf.token_len = 0;
225
226                 /*
227                  * Did that leave the pipe choked?
228                  */
229
230                 if (!lws_send_pipe_choked(wsi))
231                         /* no we could add more */
232                         continue;
233
234                 lwsl_debug("choked\n");
235
236                 /*
237                  * Yes, he's choked.  Don't spill the rest now get a callback
238                  * when he is ready to send and take care of it there
239                  */
240                 libwebsocket_callback_on_writable(
241                                              wsi->protocol->owning_server, wsi);
242                 wsi->extension_data_pending = 1;
243                 ret = 0;
244         }
245
246         return 0;
247 }
248 #endif
249
250 /**
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
264  *              are used.
265  *
266  *      This function provides the way to issue data back to the client
267  *      for both http and websocket protocols.
268  *
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.
273  */
274
275 int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf,
276                           size_t len, enum libwebsocket_write_protocol protocol)
277 {
278         int n;
279         int pre = 0;
280         int post = 0;
281         int masked7 = wsi->mode == LWS_CONNMODE_WS_CLIENT;
282         unsigned char *dropmask = NULL;
283         unsigned char is_masked_bit = 0;
284 #ifndef LWS_NO_EXTENSIONS
285         struct lws_tokens eff_buf;
286         int m;
287 #endif
288
289         if (lws_confirm_legit_wsi(wsi)) {
290                 lwsl_err("libwebsocket_write on illegitimate wsi\n");
291                 return -1;
292         }
293         if (len == 0 && protocol != LWS_WRITE_CLOSE) {
294                 lwsl_warn("zero length libwebsocket_write attempt\n");
295                 return 0;
296         }
297
298         if (protocol == LWS_WRITE_HTTP)
299                 goto send_raw;
300
301         /* websocket protocol, either binary or text */
302
303         if (wsi->state != WSI_STATE_ESTABLISHED)
304                 return -1;
305
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;
310
311         switch (protocol) {
312         case LWS_WRITE_PING:
313         case LWS_WRITE_PONG:
314         case LWS_WRITE_CLOSE:
315                 break;
316         default:
317
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);
324                         if (m < 0)
325                                 return -1;
326                 }
327         }
328
329         buf = (unsigned char *)eff_buf.token;
330         len = eff_buf.token_len;
331 #endif
332
333         switch (wsi->ietf_spec_revision) {
334         case 13:
335                 if (masked7) {
336                         pre += 4;
337                         dropmask = &buf[0 - pre];
338                         is_masked_bit = 0x80;
339                 }
340
341                 switch (protocol & 0xf) {
342                 case LWS_WRITE_TEXT:
343                         n = LWS_WS_OPCODE_07__TEXT_FRAME;
344                         break;
345                 case LWS_WRITE_BINARY:
346                         n = LWS_WS_OPCODE_07__BINARY_FRAME;
347                         break;
348                 case LWS_WRITE_CONTINUATION:
349                         n = LWS_WS_OPCODE_07__CONTINUATION;
350                         break;
351
352                 case LWS_WRITE_CLOSE:
353                         n = LWS_WS_OPCODE_07__CLOSE;
354
355                         /*
356                          * 06+ has a 2-byte status code in network order
357                          * we can do this because we demand post-buf
358                          */
359
360                         if (wsi->close_reason) {
361                                 /* reason codes count as data bytes */
362                                 buf -= 2;
363                                 buf[0] = wsi->close_reason >> 8;
364                                 buf[1] = wsi->close_reason;
365                                 len += 2;
366                         }
367                         break;
368                 case LWS_WRITE_PING:
369                         n = LWS_WS_OPCODE_07__PING;
370                         wsi->pings_vs_pongs++;
371                         break;
372                 case LWS_WRITE_PONG:
373                         n = LWS_WS_OPCODE_07__PONG;
374                         break;
375                 default:
376                         lwsl_warn("libwebsocket_write: unknown write "
377                                                          "opcode / protocol\n");
378                         return -1;
379                 }
380
381                 if (!(protocol & LWS_WRITE_NO_FIN))
382                         n |= 1 << 7;
383
384                 if (len < 126) {
385                         pre += 2;
386                         buf[-pre] = n;
387                         buf[-pre + 1] = len | is_masked_bit;
388                 } else {
389                         if (len < 65536) {
390                                 pre += 4;
391                                 buf[-pre] = n;
392                                 buf[-pre + 1] = 126 | is_masked_bit;
393                                 buf[-pre + 2] = len >> 8;
394                                 buf[-pre + 3] = len;
395                         } else {
396                                 pre += 10;
397                                 buf[-pre] = n;
398                                 buf[-pre + 1] = 127 | is_masked_bit;
399 #if defined __LP64__
400                                         buf[-pre + 2] = (len >> 56) & 0x7f;
401                                         buf[-pre + 3] = len >> 48;
402                                         buf[-pre + 4] = len >> 40;
403                                         buf[-pre + 5] = len >> 32;
404 #else
405                                         buf[-pre + 2] = 0;
406                                         buf[-pre + 3] = 0;
407                                         buf[-pre + 4] = 0;
408                                         buf[-pre + 5] = 0;
409 #endif
410                                 buf[-pre + 6] = len >> 24;
411                                 buf[-pre + 7] = len >> 16;
412                                 buf[-pre + 8] = len >> 8;
413                                 buf[-pre + 9] = len;
414                         }
415                 }
416                 break;
417         }
418
419         /*
420          * Deal with masking if we are in client -> server direction and
421          * the protocol demands it
422          */
423
424         if (wsi->mode == LWS_CONNMODE_WS_CLIENT) {
425
426                 if (libwebsocket_0405_frame_mask_generate(wsi)) {
427                         lwsl_err("libwebsocket_write: "
428                                       "frame mask generation failed\n");
429                         return 1;
430                 }
431
432                 /*
433                  * in v7, just mask the payload
434                  */
435                 for (n = 4; n < (int)len + 4; n++)
436                         dropmask[n] = dropmask[n] ^ wsi->frame_masking_nonce_04[(wsi->frame_mask_index++) & 3];
437
438                 if (dropmask)
439                         /* copy the frame nonce into place */
440                         memcpy(dropmask,
441                                        wsi->frame_masking_nonce_04, 4);
442         }
443
444 send_raw:
445
446 #if 0
447         lwsl_debug("send %ld: ", len + post);
448         lwsl_hexdump(&buf[-pre], len + post);
449 #endif
450
451         switch (protocol) {
452         case LWS_WRITE_CLOSE:
453 //              lwsl_hexdump(&buf[-pre], len + post);
454         case LWS_WRITE_HTTP:
455         case LWS_WRITE_PONG:
456         case LWS_WRITE_PING:
457                 if (lws_issue_raw(wsi, (unsigned char *)buf - pre,
458                                                               len + pre + post))
459                         return -1;
460
461                 return 0;
462         default:
463                 break;
464         }
465
466         /*
467          * give any active extensions a chance to munge the buffer
468          * before send.  We pass in a pointer to an lws_tokens struct
469          * prepared with the default buffer and content length that's in
470          * there.  Rather than rewrite the default buffer, extensions
471          * that expect to grow the buffer can adapt .token to
472          * point to their own per-connection buffer in the extension
473          * user allocation.  By default with no extensions or no
474          * extension callback handling, just the normal input buffer is
475          * used then so it is efficient.
476          *
477          * callback returns 1 in case it wants to spill more buffers
478          */
479
480         return lws_issue_raw_ext_access(wsi, buf - pre, len + pre + post);
481 }
482
483
484 /**
485  * libwebsockets_serve_http_file() - Send a file back to the client using http
486  * @context:            libwebsockets context
487  * @wsi:                Websocket instance (available from user callback)
488  * @file:               The file to issue over http
489  * @content_type:       The http content type, eg, text/html
490  *
491  *      This function is intended to be called from the callback in response
492  *      to http requests from the client.  It allows the callback to issue
493  *      local files down the http link in a single step.
494  */
495
496 int libwebsockets_serve_http_file(struct libwebsocket_context *context,
497                         struct libwebsocket *wsi, const char *file,
498                                                        const char *content_type)
499 {
500         int fd;
501         struct stat stat_buf;
502         char buf[1400];
503         char *p = buf;
504         int n, m;
505
506         strncpy(wsi->filepath, file, sizeof wsi->filepath);
507         wsi->filepath[sizeof(wsi->filepath) - 1] = '\0';
508
509 #ifdef WIN32
510         fd = open(wsi->filepath, O_RDONLY | _O_BINARY);
511 #else
512         fd = open(wsi->filepath, O_RDONLY);
513 #endif
514         if (fd < 1) {
515                 p += sprintf(p, "HTTP/1.0 400 Bad\x0d\x0a"
516                         "Server: libwebsockets\x0d\x0a"
517                         "\x0d\x0a"
518                 );
519                 libwebsocket_write(wsi, (unsigned char *)buf, p - buf,
520                                                                 LWS_WRITE_HTTP);
521
522                 return -1;
523         }
524
525         fstat(fd, &stat_buf);
526         wsi->filelen = stat_buf.st_size;
527         p += sprintf(p, "HTTP/1.0 200 OK\x0d\x0a"
528                         "Server: libwebsockets\x0d\x0a"
529                         "Content-Type: %s\x0d\x0a"
530                         "Content-Length: %u\x0d\x0a"
531                         "\x0d\x0a", content_type,
532                                         (unsigned int)stat_buf.st_size);
533
534         n = libwebsocket_write(wsi, (unsigned char *)buf, p - buf, LWS_WRITE_HTTP);
535         if (n) {
536                 close(fd);
537                 return n;
538         }
539
540         wsi->filepos = 0;
541         wsi->state = WSI_STATE_HTTP_ISSUING_FILE;
542
543         while (!lws_send_pipe_choked(wsi)) {
544
545                 n = read(fd, buf, sizeof buf);
546                 if (n > 0) {
547                         wsi->filepos += n;
548                         m = libwebsocket_write(wsi, (unsigned char *)buf, n, LWS_WRITE_HTTP);
549                         if (m) {
550                                 close(fd);
551                                 return m;
552                         }
553                 }
554
555                 if (n < 0) {
556                         close(fd);
557                         return -1;
558                 }
559
560                 if (n < sizeof(buf) || wsi->filepos == wsi->filelen) {
561                         /* oh, we were able to finish here! */
562                         wsi->state = WSI_STATE_HTTP;
563                         close(fd);
564
565                         if (wsi->protocol->callback(context, wsi, LWS_CALLBACK_HTTP_FILE_COMPLETION, wsi->user_space,
566                                                         wsi->filepath, wsi->filepos)) {
567                                 lwsl_info("closing connecton after file_completion returned nonzero\n");
568                                 libwebsocket_close_and_free_session(context, wsi, LWS_CLOSE_STATUS_NOSTATUS);
569                         }
570
571                         return 0;
572                 }
573         }
574
575         /* we choked, no worries schedule service for the rest of it */
576
577         libwebsocket_callback_on_writable(context, wsi);
578
579         close(fd);
580
581         return 0;
582 }
583
584 int libwebsockets_serve_http_file_fragment(struct libwebsocket_context *context,
585                                                         struct libwebsocket *wsi)
586 {
587         int fd;
588         int ret = 0;
589         char buf[1400];
590         int n;
591
592 #ifdef WIN32
593         fd = open(wsi->filepath, O_RDONLY | _O_BINARY);
594 #else
595         fd = open(wsi->filepath, O_RDONLY);
596 #endif
597         if (fd < 1)
598                 return -1;
599
600         lseek(fd, wsi->filepos, SEEK_SET);
601
602         while (!lws_send_pipe_choked(wsi)) {
603                 n = read(fd, buf, sizeof buf);
604                 if (n > 0) {
605                         libwebsocket_write(wsi, (unsigned char *)buf, n, LWS_WRITE_HTTP);
606                         wsi->filepos += n;
607                 }
608
609                 if (n < 0) {
610                         close(fd);
611                         return -1;
612                 }
613
614                 if (n < sizeof(buf) || wsi->filepos == wsi->filelen) {
615                         wsi->state = WSI_STATE_HTTP;
616                         close(fd);
617                         return 0;
618                 }
619         }
620
621         libwebsocket_callback_on_writable(context, wsi);
622
623         close(fd);
624
625         return ret;
626 }
627
628