Преглед изворни кода

websocket: option to compile the module without libunistring

- patch discussed on sr-dev
- dcm: aded define wrapper to have this as compile time option and
  included the MIT license from the code site
Timo Teräs пре 11 година
родитељ
комит
f2dc27ced2
3 измењених фајлова са 102 додато и 1 уклоњено
  1. 9 1
      modules/websocket/Makefile
  2. 82 0
      modules/websocket/utf8_decode.h
  3. 11 0
      modules/websocket/ws_frame.c

+ 9 - 1
modules/websocket/Makefile

@@ -7,6 +7,8 @@ include ../../Makefile.defs
 auto_gen=
 auto_gen=
 NAME=websocket.so
 NAME=websocket.so
 
 
+EMBEDDED_UTF8_DECODE ?= 0
+
 ifeq ($(CROSS_COMPILE),)
 ifeq ($(CROSS_COMPILE),)
 SSL_BUILDER=$(shell \
 SSL_BUILDER=$(shell \
 	if pkg-config --exists libssl; then \
 	if pkg-config --exists libssl; then \
@@ -27,7 +29,13 @@ else
 	#       E.g.: make TLS_HOOKS=1 TLS_EXTRA_LIBS="-lz -lkrb5"
 	#       E.g.: make TLS_HOOKS=1 TLS_EXTRA_LIBS="-lz -lkrb5"
 endif
 endif
 
 
-LIBS+= $(TLS_EXTRA_LIBS) -lunistring
+LIBS+= $(TLS_EXTRA_LIBS)
+
+ifeq ($(EMBEDDED_UTF8_DECODE),0)
+	LIBS+= -lunistring
+else
+	DEFS += -DEMBEDDED_UTF8_DECODE
+endif
 
 
 # Static linking, if you'd like to use TLS and WEBSOCKET at the same time
 # Static linking, if you'd like to use TLS and WEBSOCKET at the same time
 #
 #

+ 82 - 0
modules/websocket/utf8_decode.h

@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) 2008-2010 Bjoern Hoehrmann <[email protected]>
+ *
+ * MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *   The above copyright notice and this permission notice shall be included
+ *   in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ * 
+ * See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.
+ */
+
+#ifdef EMBEDDED_UTF8_DECODE
+
+#ifndef _UTF8_DECODE_H_
+#define _UTF8_DECODE_H_
+
+#include <stdint.h>
+#include <stddef.h>
+
+#define UTF8_ACCEPT 0
+#define UTF8_REJECT 12
+
+static const uint8_t utf8d[] = {
+	// The first part of the table maps bytes to character classes that
+	// to reduce the size of the transition table and create bitmasks.
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
+	7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+	8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+	10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8,
+
+	// The second part is a transition table that maps a combination
+	// of a state of the automaton and a character class to a state.
+	0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12,
+	12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12,
+	12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12,
+	12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12,
+	12,36,12,12,12,12,12,12,12,12,12,12,
+};
+
+static inline uint32_t decode(uint32_t* state, uint32_t* codep, uint32_t byte)
+{
+	uint32_t type = utf8d[byte];
+
+	*codep = (*state != UTF8_ACCEPT) ?
+		(byte & 0x3fu) | (*codep << 6) :
+		(0xff >> type) & (byte);
+
+	*state = utf8d[256 + *state + type];
+	return *state;
+}
+
+static inline int IsUTF8(uint8_t* s, size_t len)
+{
+	uint32_t codepoint, state = 0;
+
+	while (len--)
+		decode(&state, &codepoint, *s++);
+
+	return state == UTF8_ACCEPT;
+}
+
+#endif
+
+#endif

+ 11 - 0
modules/websocket/ws_frame.c

@@ -27,7 +27,13 @@
  */
  */
 
 
 #include <limits.h>
 #include <limits.h>
+
+#ifdef EMBEDDED_UTF8_DECODE
+#include "utf8_decode.h"
+#else
 #include <unistr.h>
 #include <unistr.h>
+#endif
+
 #include "../../events.h"
 #include "../../events.h"
 #include "../../receive.h"
 #include "../../receive.h"
 #include "../../stats.h"
 #include "../../stats.h"
@@ -726,8 +732,13 @@ int ws_frame_transmit(void *data)
 	frame.fin = 1;
 	frame.fin = 1;
 	/* Can't be sure whether this message is UTF-8 or not so check to see
 	/* Can't be sure whether this message is UTF-8 or not so check to see
 	   if it "might" be UTF-8 and send as binary if it definitely isn't */
 	   if it "might" be UTF-8 and send as binary if it definitely isn't */
+#ifdef EMBEDDED_UTF8_DECODE
+	frame.opcode = IsUTF8((uint8_t *) wsev->buf, wsev->len) ?
+				OPCODE_TEXT_FRAME : OPCODE_BINARY_FRAME;
+#else
 	frame.opcode = (u8_check((uint8_t *) wsev->buf, wsev->len) == NULL) ?
 	frame.opcode = (u8_check((uint8_t *) wsev->buf, wsev->len) == NULL) ?
 				OPCODE_TEXT_FRAME : OPCODE_BINARY_FRAME;
 				OPCODE_TEXT_FRAME : OPCODE_BINARY_FRAME;
+#endif
 	frame.payload_len = wsev->len;
 	frame.payload_len = wsev->len;
 	frame.payload_data = wsev->buf;
 	frame.payload_data = wsev->buf;
 	frame.wsc = wsconn_get(wsev->id);
 	frame.wsc = wsconn_get(wsev->id);