mirror of https://github.com/aria2/aria2
Update wslay
parent
dda0b62fb9
commit
28562b3f6d
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}
|
||||
])
|
||||
|
|
|
@ -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)
|
|
@ -570,7 +570,7 @@ void reactor(int sfd)
|
|||
} else {
|
||||
perror("epoll_ctl");
|
||||
delete next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(eh->finish()) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue