Update wslay

pull/547/head
Tatsuhiro Tsujikawa 2016-01-22 23:41:43 +09:00
parent dda0b62fb9
commit 28562b3f6d
13 changed files with 183 additions and 93 deletions

2
deps/wslay/COPYING vendored
View File

@ -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

View File

@ -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

56
deps/wslay/NEWS vendored
View File

@ -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
This is the initial release of wslay WebSocket C library.
* build: allow one to build out-of-tree documentation
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.
Patch from Vincent Bernat
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.
* build: fix `./configure` when nettle is not present
Visit http://wslay.sourceforge.net/ for the API reference and
tutorial.
`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.
Patch from Ben Vanik
* Improve http_handshake in fork-echoserver.
Patch from Gurjeet Singh
* Don't send any pending control frame other than Close control frame
after Close is queued.

30
deps/wslay/README.rst vendored
View File

@ -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

View File

@ -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], [t-tujikawa@users.sourceforge.net])
AC_INIT([wslay], [1.0.1-DEV], [t-tujikawa@users.sourceforge.net])
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}
])

View File

@ -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)

View File

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

View File

@ -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,

View File

@ -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);
}

View File

@ -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,

View File

@ -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;

View File

@ -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));

View File

@ -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);