summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2018-07-18 13:02:04 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2018-07-18 13:02:17 +0000
commit55374ef8d020b73286cf50588ea77c06ed79b162 (patch)
treef0d6a80b0aa016aef274544d9c433b2e3f476959
parentReleasing progress-linux version 2.3.4-3~dschinn1. (diff)
downloadulfius-55374ef8d020b73286cf50588ea77c06ed79b162.zip
ulfius-55374ef8d020b73286cf50588ea77c06ed79b162.tar.xz
Merging upstream version 2.3.5.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
-rw-r--r--CHANGELOG.md4
-rw-r--r--CMakeLists.txt2
-rw-r--r--include/ulfius.h13
-rw-r--r--src/Makefile4
-rw-r--r--src/u_websocket.c71
5 files changed, 59 insertions, 35 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5264dd0..ea91fa2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
# Ulfius Changelog
+## 2.3.5
+
+- Fix websocket bug that kept some connections open after being unproperly closed by the client
+
## 2.3.4
- Fix Makefile soname
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1386617..77231fb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -28,7 +28,7 @@ set(PROJECT_BUGREPORT_PATH "https://github.com/babelouest/ulfius/issues")
set(LIBRARY_VERSION_MAJOR "2")
set(LIBRARY_VERSION_MINOR "3")
-set(LIBRARY_VERSION_PATCH "4")
+set(LIBRARY_VERSION_PATCH "5")
set(LIBRARY_VERSION "${LIBRARY_VERSION_MAJOR}.${LIBRARY_VERSION_MINOR}.${LIBRARY_VERSION_PATCH}")
set(LIBRARY_SOVERSION "${LIBRARY_VERSION_MAJOR}.${LIBRARY_VERSION_MINOR}")
set(YDER_VERSION_DOWNLOAD "1.3.3")
diff --git a/include/ulfius.h b/include/ulfius.h
index 07b2519..2babd3f 100644
--- a/include/ulfius.h
+++ b/include/ulfius.h
@@ -26,9 +26,16 @@
#ifndef __ULFIUS_H__
#define __ULFIUS_H__
-#define ULFIUS_VERSION 2.3.4
+#define ULFIUS_VERSION 2.3.5
/** External dependencies **/
+
+#ifndef U_DISABLE_WEBSOCKET
+ #ifndef _GNU_SOURCE
+ #define _GNU_SOURCE
+ #endif
+ #include <poll.h>
+#endif
#include <pthread.h>
#include <microhttpd.h>
@@ -40,10 +47,6 @@
#define U_DISABLE_WEBSOCKET
#endif
-#ifndef U_DISABLE_WEBSOCKET
- #include <poll.h>
-#endif
-
/** Angharad libraries **/
#include <yder.h>
#include <orcania.h>
diff --git a/src/Makefile b/src/Makefile
index 33a7a0a..af57c95 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -27,7 +27,7 @@ CC=gcc
CFLAGS+=-c -pedantic -std=gnu99 -fPIC -Wall -D_REENTRANT -I$(DESTDIR)/include -I$(ULFIUS_INCLUDE) -I$(LIBORCANIA_LOCATION) -I$(LIBYDER_LOCATION) $(ADDITIONALFLAGS) $(JANSSONFLAG) $(CURLFLAG) $(WEBSOCKETFLAG) $(CPPFLAGS)
LIBS=-L$(DESTDIR)/lib -L$(LIBORCANIA_LOCATION) -L$(LIBYDER_LOCATION) -lc -lmicrohttpd -lyder -lorcania -lpthread $(LDFLAGS)
OUTPUT=libulfius.so
-VERSION=2.3.4
+VERSION=2.3.5
ifndef JANSSONFLAG
LJANSSON=-ljansson
@@ -81,7 +81,7 @@ static-install: static
cp $(ULFIUS_INCLUDE)/ulfius.h $(DESTDIR)/include
uninstall:
- rm -f $(DESTDIR)/lib/$(OUTPUT) libulfius.a
+ rm -f $(DESTDIR)/lib/$(OUTPUT) $(DESTDIR)/lib/libulfius.a
rm -f $(DESTDIR)/lib/$(OUTPUT).*
rm -f $(DESTDIR)/include/ulfius.h
diff --git a/src/u_websocket.c b/src/u_websocket.c
index eba4fa7..9957c85 100644
--- a/src/u_websocket.c
+++ b/src/u_websocket.c
@@ -108,6 +108,8 @@ void * ulfius_thread_websocket(void * data) {
pthread_t thread_websocket_manager;
pthread_mutexattr_t mutexattr;
int thread_ret_websocket_manager = 0, poll_ret;
+ int error = 0;
+ socklen_t len = sizeof (error);
if (websocket != NULL && websocket->websocket_manager != NULL) {
pthread_mutexattr_init ( &mutexattr );
@@ -132,31 +134,46 @@ void * ulfius_thread_websocket(void * data) {
if (pthread_mutex_lock(&websocket->websocket_manager->read_lock)) {
websocket->websocket_manager->connected = 0;
}
- poll_ret = poll(&websocket->websocket_manager->fds, 1, U_WEBSOCKET_USEC_WAIT);
- if (poll_ret == -1) {
- y_log_message(Y_LOG_LEVEL_ERROR, "Error poll websocket read");
- } else if (poll_ret > 0) {
- opcode = ulfius_read_incoming_message(websocket->websocket_manager, &message);
- if (opcode == U_WEBSOCKET_OPCODE_CLOSE) {
- // Send close command back, then close the socket
- if (ulfius_websocket_send_message(websocket->websocket_manager, U_WEBSOCKET_OPCODE_CLOSE, 0, NULL) != U_OK) {
- y_log_message(Y_LOG_LEVEL_ERROR, "Error sending close command");
- }
- websocket->websocket_manager->closing = 1;
- } else if (opcode == U_WEBSOCKET_OPCODE_PING) {
- // Send pong command
- if (ulfius_websocket_send_message(websocket->websocket_manager, U_WEBSOCKET_OPCODE_PONG, 0, NULL) != U_OK) {
- y_log_message(Y_LOG_LEVEL_ERROR, "Error sending pong command");
- }
- } else if (opcode != U_WEBSOCKET_OPCODE_NONE && message != NULL) {
- if (websocket->websocket_incoming_message_callback != NULL) {
- // TODO: run in thread
- websocket->websocket_incoming_message_callback(websocket->request, websocket->websocket_manager, message, websocket->websocket_incoming_user_data);
- }
- }
- if (message != NULL) {
- if (ulfius_push_websocket_message(websocket->websocket_manager->message_list_incoming, message) != U_OK) {
- y_log_message(Y_LOG_LEVEL_ERROR, "Error pushing new websocket message in list");
+ error = 0;
+ poll_ret = getsockopt(websocket->websocket_manager->sock, SOL_SOCKET, SO_ERROR, &error, &len);
+ if (poll_ret != 0) {
+ y_log_message(Y_LOG_LEVEL_ERROR, "Error getsockopt");
+ websocket->websocket_manager->connected = 0;
+ } else {
+ if (error != 0) {
+ y_log_message(Y_LOG_LEVEL_ERROR, "Socket not good enough");
+ websocket->websocket_manager->connected = 0;
+ } else {
+ poll_ret = poll(&websocket->websocket_manager->fds, 1, U_WEBSOCKET_USEC_WAIT);
+ if (poll_ret == -1) {
+ y_log_message(Y_LOG_LEVEL_ERROR, "Error poll websocket read");
+ websocket->websocket_manager->connected = 0;
+ } else if (websocket->websocket_manager->fds.revents & (POLLRDHUP|POLLERR|POLLHUP|POLLNVAL)) {
+ websocket->websocket_manager->connected = 0;
+ } else if (poll_ret > 0) {
+ opcode = ulfius_read_incoming_message(websocket->websocket_manager, &message);
+ if (opcode == U_WEBSOCKET_OPCODE_CLOSE) {
+ // Send close command back, then close the socket
+ if (ulfius_websocket_send_message(websocket->websocket_manager, U_WEBSOCKET_OPCODE_CLOSE, 0, NULL) != U_OK) {
+ y_log_message(Y_LOG_LEVEL_ERROR, "Error sending close command");
+ }
+ websocket->websocket_manager->closing = 1;
+ } else if (opcode == U_WEBSOCKET_OPCODE_PING) {
+ // Send pong command
+ if (ulfius_websocket_send_message(websocket->websocket_manager, U_WEBSOCKET_OPCODE_PONG, 0, NULL) != U_OK) {
+ y_log_message(Y_LOG_LEVEL_ERROR, "Error sending pong command");
+ }
+ } else if (opcode != U_WEBSOCKET_OPCODE_NONE && message != NULL) {
+ if (websocket->websocket_incoming_message_callback != NULL) {
+ // TODO: run in thread
+ websocket->websocket_incoming_message_callback(websocket->request, websocket->websocket_manager, message, websocket->websocket_incoming_user_data);
+ }
+ }
+ if (message != NULL) {
+ if (ulfius_push_websocket_message(websocket->websocket_manager->message_list_incoming, message) != U_OK) {
+ y_log_message(Y_LOG_LEVEL_ERROR, "Error pushing new websocket message in list");
+ }
+ }
}
}
}
@@ -204,7 +221,7 @@ void ulfius_start_websocket_cb (void * cls,
ulfius_init_websocket_message_list(websocket->websocket_manager->message_list_outcoming);
websocket->websocket_manager->sock = sock;
websocket->websocket_manager->fds.fd = sock;
- websocket->websocket_manager->fds.events = POLLIN;
+ websocket->websocket_manager->fds.events = POLLIN | POLLRDHUP;
websocket->websocket_manager->connected = 1;
websocket->websocket_manager->closing = 0;
thread_ret_websocket = pthread_create(&thread_websocket, NULL, ulfius_thread_websocket, (void *)websocket);
@@ -496,7 +513,7 @@ int ulfius_websocket_send_message(struct _websocket_manager * websocket_manager,
poll_ret = poll(&websocket_manager->fds, 1, U_WEBSOCKET_USEC_WAIT);
if (poll_ret == -1) {
y_log_message(Y_LOG_LEVEL_ERROR, "Error poll websocket read for close signal");
- } else if (poll_ret > 0) {
+ } else if (!(websocket_manager->fds.revents & (POLLRDHUP|POLLERR|POLLHUP|POLLNVAL)) && poll_ret > 0) {
do {
ret_message = ulfius_read_incoming_message(websocket_manager, &message);
if (message != NULL) {