summaryrefslogtreecommitdiff
path: root/res/res_http_websocket.c
diff options
context:
space:
mode:
authorDavid M. Lee <dlee@digium.com>2015-02-25 20:44:51 +0000
committerDavid M. Lee <dlee@digium.com>2015-02-25 20:44:51 +0000
commit43a3e80be155dc7569a94082a1d1c1484cf40dbe (patch)
treedd96fe7a09f8a0f4899c5398f9e5c8a6b261b6cd /res/res_http_websocket.c
parent978649a56838c7502a5869b93c697a7c66e5921e (diff)
Increase WebSocket frame size and improve large read handling
Some WebSocket applications, like [chan_respoke][], require a larger frame size than the default 8k; this patch bumps the default to 16k. This patch also fixes some problems exacerbated by large frames. The sanity counter was decremented on every fread attempt in ws_safe_read(), regardless of whether data was read from the socket or not. For large frames, this could result in loss of sanity prior to reading the entire frame. (16k frame / 1448 bytes per segment = 12 segments). This patch changes the sanity counter so that it only decrements when fread() doesn't read any bytes. This more closely matches the original intention of ws_safe_read(), given that the error message is "Websocket seems unresponsive". This patch also properly logs EOF conditions, so disconnects are no longer confused with unresponsive connections. [chan_respoke]: https://github.com/respoke/chan_respoke Review: https://reviewboard.asterisk.org/r/4431/ ........ Merged revisions 432236 from http://svn.asterisk.org/svn/asterisk/branches/11 git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/13@432237 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'res/res_http_websocket.c')
-rw-r--r--res/res_http_websocket.c39
1 files changed, 25 insertions, 14 deletions
diff --git a/res/res_http_websocket.c b/res/res_http_websocket.c
index d1beae6c2..7e71f8bf1 100644
--- a/res/res_http_websocket.c
+++ b/res/res_http_websocket.c
@@ -52,7 +52,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#define MAX_PROTOCOL_BUCKETS 7
/*! \brief Size of the pre-determined buffer for WebSocket frames */
-#define MAXIMUM_FRAME_SIZE 8192
+#define MAXIMUM_FRAME_SIZE 16384
/*! \brief Default reconstruction size for multi-frame payload reconstruction. If exceeded the next frame will start a
* payload.
@@ -413,18 +413,35 @@ int AST_OPTIONAL_API_NAME(ast_websocket_set_timeout)(struct ast_websocket *sessi
*/
static inline int ws_safe_read(struct ast_websocket *session, char *buf, int len, enum ast_websocket_opcode *opcode)
{
- int sanity;
size_t rlen;
int xlen = len;
char *rbuf = buf;
- for (sanity = 10; sanity; sanity--) {
+ int sanity = 10;
+
+ for (;;) {
clearerr(session->f);
rlen = fread(rbuf, 1, xlen, session->f);
- if (!rlen && ferror(session->f) && errno != EAGAIN) {
- ast_log(LOG_ERROR, "Error reading from web socket: %s\n", strerror(errno));
- *opcode = AST_WEBSOCKET_OPCODE_CLOSE;
- session->closing = 1;
- return -1;
+ if (!rlen) {
+ if (feof(session->f)) {
+ ast_log(LOG_WARNING, "Web socket closed abruptly\n");
+ *opcode = AST_WEBSOCKET_OPCODE_CLOSE;
+ session->closing = 1;
+ return -1;
+ }
+
+ if (ferror(session->f) && errno != EAGAIN) {
+ ast_log(LOG_ERROR, "Error reading from web socket: %s\n", strerror(errno));
+ *opcode = AST_WEBSOCKET_OPCODE_CLOSE;
+ session->closing = 1;
+ return -1;
+ }
+
+ if (!--sanity) {
+ ast_log(LOG_WARNING, "Websocket seems unresponsive, disconnecting ...\n");
+ *opcode = AST_WEBSOCKET_OPCODE_CLOSE;
+ session->closing = 1;
+ return -1;
+ }
}
xlen = xlen - rlen;
rbuf = rbuf + rlen;
@@ -438,12 +455,6 @@ static inline int ws_safe_read(struct ast_websocket *session, char *buf, int len
return -1;
}
}
- if (!sanity) {
- ast_log(LOG_WARNING, "Websocket seems unresponsive, disconnecting ...\n");
- *opcode = AST_WEBSOCKET_OPCODE_CLOSE;
- session->closing = 1;
- return -1;
- }
return 0;
}