Browse Source

Update wslay

Tatsuhiro Tsujikawa 9 years ago
parent
commit
28562b3f6d

+ 1 - 1
deps/wslay/COPYING

@@ -1,6 +1,6 @@
 The MIT License
 
-Copyright (c) 2011, 2012 Tatsuhiro Tsujikawa
+Copyright (c) 2011, 2012, 2015 Tatsuhiro Tsujikawa
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the

+ 0 - 5
deps/wslay/Makefile.am

@@ -23,8 +23,3 @@
 SUBDIRS = lib tests
 
 ACLOCAL_AMFLAGS = -I m4
-
-EXTRA_DIST = examples/Makefile \
-	examples/fork-echoserv.c \
-	examples/echoserv.cc \
-	examples/testclient.cc

+ 31 - 25
deps/wslay/NEWS

@@ -1,41 +1,47 @@
-wslay 0.1.1
+wslay 1.0.0
 ===========
 
 Release Note
 ------------
 
-This release fixes the example programs and tutorial.  It does not
-change library code at all, so the library version has not been
-changed.
+This release fixes several build issues.  Most changes were introduced
+by contributors.  Thank you for all the contributions in this project.
+Because wslay is very stable since the previous release (more than 2
+years ago), we mark this release 1.0.0.
 
 Changes
 -------
 
-* Fixed example source code and tutorial.
+* Fix NULL check in wslay_frame_context_init.
 
-
+  Patch from Witchakorn Kamolpornwijit
 
-wslay 0.1.0
-===========
+* the examples uses epoll and thus only be built on linux
 
-Release Note
-------------
+  Patch from Kazuho Oku
+
+* build: allow one to build out-of-tree documentation
+
+  Patch from Vincent Bernat
+
+* build: fix `./configure` when nettle is not present
+
+  `PKG_CHECK_MODULES` will fail unless we give it an action to execute
+  on failure. When nettle is not available, we set `have_nettle` to
+  `no`.
+
+  Patch from Vincent Bernat
+
+* Adds the ability to override the version header include with a
+  define.  This enables projects to set the build version from the
+  compile environment and avoid the need to generate the version
+  header.
 
-This is the initial release of wslay WebSocket C library.
+  Patch from Ben Vanik
 
-Wslay is a WebSocket library written in C. It implements the protocol
-version 13 described in RFC 6455. This library offers 2 levels of API:
-event-based API and frame-based low-level API. For event-based API, it
-is suitable for non-blocking reactor pattern style. You can set
-callbacks in various events. For frame-based API, you can send
-WebSocket frame directly. Wslay only supports data transfer part of
-WebSocket protocol and does not perform opening handshake in HTTP.
+* Improve http_handshake in fork-echoserver.
 
-Wslay does not perform any I/O operations for its own. Instead, it
-offers callbacks for them. This makes Wslay independent on any I/O
-frameworks, SSL, sockets, etc. This makes Wslay protable across
-various platforms and the application authors can choose freely IO
-frameworks.
+  Patch from Gurjeet Singh
 
-Visit http://wslay.sourceforge.net/ for the API reference and
-tutorial.
+* Don't send any pending control frame other than Close control frame
+  after Close is queued.

+ 29 - 1
deps/wslay/README.rst

@@ -22,7 +22,7 @@ Wslay supports:
 
 Wslay does not perform any I/O operations for its own. Instead, it
 offers callbacks for them. This makes Wslay independent on any I/O
-frameworks, SSL, sockets, etc.  This makes Wslay protable across
+frameworks, SSL, sockets, etc.  This makes Wslay portable across
 various platforms and the application authors can choose freely I/O
 frameworks.
 
@@ -30,3 +30,31 @@ See Autobahn test reports:
 `server <http://wslay.sourceforge.net/autobahn/reports/servers/index.html>`_
 and
 `client <http://wslay.sourceforge.net/autobahn/reports/clients/index.html>`_.
+
+Requirements
+------------
+
+`Sphinx <http://sphinx.pocoo.org/>`_ is used to generate man pages.
+
+To build and run the unit test programs, the following packages are
+needed:
+
+* cunit >= 2.1
+
+To build and run the example programs, the following packages are
+needed:
+
+* nettle >= 2.4
+
+
+Build from git
+--------------
+
+Building from git is easy, but please be sure that at least autoconf 2.68 is
+used.::
+
+    $ autoreconf -i
+    $ automake
+    $ autoconf
+    $ ./configure
+    $ make

+ 24 - 5
deps/wslay/configure.ac

@@ -21,14 +21,14 @@ dnl LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 dnl OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 dnl WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 AC_PREREQ(2.61)
-AC_INIT([wslay], [0.1.1], [[email protected]])
+AC_INIT([wslay], [1.0.1-DEV], [[email protected]])
 LT_PREREQ([2.2.6])
 LT_INIT()
 AC_CONFIG_AUX_DIR([.])
 dnl See versioning rule:
 dnl  http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
 AC_SUBST(LT_CURRENT, 0)
-AC_SUBST(LT_REVISION, 0)
+AC_SUBST(LT_REVISION, 1)
 AC_SUBST(LT_AGE, 0)
 
 AC_CANONICAL_BUILD
@@ -42,15 +42,21 @@ AC_CONFIG_HEADERS([config.h])
 
 dnl Checks for programs
 AC_PROG_CC
+AC_PROG_CXX
 AC_PROG_INSTALL
 AC_PROG_LN_S
 AC_PROG_MAKE_SET
+PKG_PROG_PKG_CONFIG([0.20])
 
 AC_PATH_PROG([SPHINX_BUILD], [sphinx-build])
 AC_SUBST([SPHINX_BUILD])
 AM_CONDITIONAL([HAVE_SPHINX_BUILD], [ test "x$SPHINX_BUILD" != "x" ])
 
 # Checks for libraries.
+
+# Nettle used in examples
+PKG_CHECK_MODULES([NETTLE], [nettle >= 2.4], [have_nettle=yes], [have_nettle=no])
+
 AC_CHECK_LIB([cunit], [CU_initialize_registry],
              [have_cunit=yes], [have_cunit=no])
 AM_CONDITIONAL([HAVE_CUNIT], [ test "x${have_cunit}" = "xyes" ])
@@ -91,9 +97,6 @@ AC_CHECK_TYPES([ptrdiff_t])
 AC_C_BIGENDIAN
 
 # Checks for library functions.
-if test "x$cross_compiling" != "xyes"; then
-  AC_FUNC_MALLOC
-fi
 AC_CHECK_FUNCS([ \
   memmove \
   memset \
@@ -102,6 +105,17 @@ AC_CHECK_FUNCS([ \
   htons
 ])
 
+build_examples=no
+if test "x${have_nettle}" = "xyes"; then
+  case $host_os in
+    linux*)
+      # the examples uses epoll
+      build_examples=yes
+      ;;
+  esac
+fi
+AM_CONDITIONAL([ENABLE_EXAMPLES], [ test "x${build_examples}" = "xyes" ])
+
 AC_CONFIG_FILES([
   Makefile
   lib/Makefile
@@ -109,6 +123,9 @@ AC_CONFIG_FILES([
   lib/includes/Makefile
   lib/includes/wslay/wslayver.h
   tests/Makefile
+  examples/Makefile
+  doc/Makefile
+  doc/sphinx/conf.py
 ])
 AC_OUTPUT
 
@@ -121,4 +138,6 @@ AC_MSG_NOTICE([summary of build options:
     CFlags:         ${CFLAGS}
     Library types:  Shared=${enable_shared}, Static=${enable_static}
     CUnit:          ${have_cunit}
+    Nettle:         ${have_nettle}
+    Build examples: ${build_examples}
 ])

+ 0 - 46
deps/wslay/examples/Makefile

@@ -1,46 +0,0 @@
-# Wslay - The WebSocket Library
-
-# Copyright (c) 2011, 2012 Tatsuhiro Tsujikawa
-
-# 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.
-CC = gcc
-CXX = g++
-CFLAGS = -g -O2 -I../lib/includes
-CXXFLAGS = $(CFLAGS)
-LDFLAGS = -L../lib/.libs
-LIBS = -lwslay -lnettle
-
-PROGRAMS = fork-echoserv echoserv testclient
-
-.PHONY: all
-all: $(PROGRAMS)
-
-fork-echoserv: fork-echoserv.c
-	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ fork-echoserv.c $(LIBS)
-
-echoserv: echoserv.cc
-	$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ echoserv.cc $(LIBS)
-
-testclient: testclient.cc
-	$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ testclient.cc $(LIBS)
-
-.PHONY: clean
-clean:
-	rm -f *.o $(PROGRAMS)

+ 1 - 1
deps/wslay/examples/echoserv.cc

@@ -570,7 +570,7 @@ void reactor(int sfd)
             } else {
               perror("epoll_ctl");
               delete next;
-            }              
+            }
           }
         }
         if(eh->finish()) {

+ 80 - 5
deps/wslay/examples/fork-echoserv.c

@@ -50,6 +50,7 @@
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
+#include <ctype.h>
 
 #include <nettle/base64.h>
 #include <nettle/sha.h>
@@ -159,6 +160,80 @@ void create_accept_key(char *dst, const char *client_key)
   dst[BASE64_ENCODE_RAW_LENGTH(20)] = '\0';
 }
 
+/* We parse HTTP header lines of the format
+ *   \r\nfield_name: value1, value2, ... \r\n
+ *
+ * If the caller is looking for a specific value, we return a pointer to the
+ * start of that value, else we simply return the start of values list.
+ */
+static char*
+http_header_find_field_value(char *header, char *field_name, char *value)
+{
+  char *header_end,
+       *field_start,
+       *field_end,
+       *next_crlf,
+       *value_start;
+  int field_name_len;
+
+  /* Pointer to the last character in the header */
+  header_end = header + strlen(header) - 1;
+
+  field_name_len = strlen(field_name);
+
+  field_start = header;
+
+  do{
+    field_start = strstr(field_start+1, field_name);
+
+    field_end = field_start + field_name_len - 1;
+
+    if(field_start != NULL
+       && field_start - header >= 2
+       && field_start[-2] == '\r'
+       && field_start[-1] == '\n'
+       && header_end - field_end >= 1
+       && field_end[1] == ':')
+    {
+      break; /* Found the field */
+    }
+    else
+    {
+      continue; /* This is not the one; keep looking. */
+    }
+  } while(field_start != NULL);
+
+  if(field_start == NULL)
+    return NULL;
+
+  /* Find the field terminator */
+  next_crlf = strstr(field_start, "\r\n");
+
+  /* A field is expected to end with \r\n */
+  if(next_crlf == NULL)
+    return NULL; /* Malformed HTTP header! */
+
+  /* If not looking for a value, then return a pointer to the start of values string */
+  if(value == NULL)
+    return field_end+2;
+
+  value_start = strstr(field_start, value);
+
+  /* Value not found */
+  if(value_start == NULL)
+    return NULL;
+
+  /* Found the value we're looking for */
+  if(value_start > next_crlf)
+    return NULL; /* ... but after the CRLF terminator of the field. */
+
+  /* The value we found should be properly delineated from the other tokens */
+  if(isalnum(value_start[-1]) || isalnum(value_start[strlen(value)]))
+    return NULL;
+
+  return value_start;
+}
+
 /*
  * Performs HTTP handshake. *fd* is the file descriptor of the
  * connection to the client. This function returns 0 if it succeeds,
@@ -195,13 +270,13 @@ int http_handshake(int fd)
       }
     }
   }
-  if(strstr(header, "\r\nUpgrade: websocket\r\n") == NULL ||
-     strstr(header, "\r\nConnection: Upgrade\r\n") == NULL ||
-     (keyhdstart = strstr(header, "\r\nSec-WebSocket-Key:")) == NULL) {
+
+  if(http_header_find_field_value(header, "Upgrade", "websocket") == NULL ||
+     http_header_find_field_value(header, "Connection", "Upgrade") == NULL ||
+     (keyhdstart = http_header_find_field_value(header, "Sec-WebSocket-Key", NULL)) == NULL) {
     fprintf(stderr, "HTTP Handshake: Missing required header fields");
     return -1;
   }
-  keyhdstart += 20;
   for(; *keyhdstart == ' '; ++keyhdstart);
   keyhdend = keyhdstart;
   for(; *keyhdend != '\r' && *keyhdend != ' '; ++keyhdend);
@@ -281,7 +356,7 @@ ssize_t recv_callback(wslay_event_context_ptr ctx, uint8_t *buf, size_t len,
     r = -1;
   }
   return r;
-}    
+}
 
 void on_msg_recv_callback(wslay_event_context_ptr ctx,
                           const struct wslay_event_on_msg_recv_arg *arg,

+ 1 - 1
deps/wslay/examples/testclient.cc

@@ -496,7 +496,7 @@ int update_reports(const char *host, const char *service)
 
 int main(int argc, char **argv)
 {
-  if(argc < 2) {
+  if(argc < 3) {
     std::cerr << "Usage: " << argv[0] << " HOST SERV" << std::endl;
     exit(EXIT_FAILURE);
   }

+ 9 - 1
deps/wslay/lib/includes/wslay/wslay.h

@@ -33,7 +33,15 @@ extern "C" {
 #include <stdlib.h>
 #include <sys/types.h>
 
-#include <wslay/wslayver.h>
+
+/*
+ * wslay/wslayver.h is generated from wslay/wslayver.h.in by
+ * configure. The projects which do not use autotools can set
+ * WSLAY_VERSION macro from outside to avoid to generating wslayver.h
+ */
+#ifndef WSLAY_VERSION
+#  include <wslay/wslayver.h>
+#endif /* WSLAY_VERSION */
 
 enum wslay_error {
   WSLAY_ERR_WANT_READ = -100,

+ 4 - 0
deps/wslay/lib/wslay_event.c

@@ -135,6 +135,10 @@ static int wslay_event_byte_chunk_init
   memset(*chunk, 0, sizeof(struct wslay_event_byte_chunk));
   if(len) {
     (*chunk)->data = (uint8_t*)malloc(len);
+    if((*chunk)->data == NULL) {
+      free(*chunk);
+      return WSLAY_ERR_NOMEM;
+    }
     (*chunk)->data_length = len;
   }
   return 0;

+ 1 - 1
deps/wslay/lib/wslay_frame.c

@@ -37,7 +37,7 @@ int wslay_frame_context_init(wslay_frame_context_ptr *ctx,
                              void *user_data)
 {
   *ctx = (wslay_frame_context_ptr)malloc(sizeof(struct wslay_frame_context));
-  if(ctx == NULL) {
+  if(*ctx == NULL) {
     return -1;
   }
   memset(*ctx, 0, sizeof(struct wslay_frame_context));

+ 2 - 1
deps/wslay/lib/wslay_stack.c

@@ -40,10 +40,11 @@ struct wslay_stack* wslay_stack_new()
 
 void wslay_stack_free(struct wslay_stack *stack)
 {
+  struct wslay_stack_cell *p;
   if(!stack) {
     return;
   }
-  struct wslay_stack_cell *p = stack->top;
+  p = stack->top;
   while(p) {
     struct wslay_stack_cell *next = p->next;
     free(p);