From 60339f151b6dab603bb66508a991481e89add30c Mon Sep 17 00:00:00 2001 From: Lammert Bies Date: Sat, 10 Dec 2016 17:28:57 +0100 Subject: [PATCH] Moved websocket_write_exec to own file --- Makefile | 1 + src/httplib_websocket_write_exec.c | 92 +++++++++++++++++++++ src/libhttp.c | 124 +++++++++-------------------- 3 files changed, 131 insertions(+), 86 deletions(-) create mode 100644 src/httplib_websocket_write_exec.c diff --git a/Makefile b/Makefile index b8972dc3..a7f16d87 100644 --- a/Makefile +++ b/Makefile @@ -104,6 +104,7 @@ LIB_SOURCES = src/libhttp.c \ src/httplib_websocket_client_thread.c \ src/httplib_websocket_client_write.c \ src/httplib_websocket_write.c \ + src/httplib_websocket_write_exec.c \ src/httplib_worker_thread.c \ src/md5.c LIB_INLINE = src/mod_lua.inl src/md5.inl diff --git a/src/httplib_websocket_write_exec.c b/src/httplib_websocket_write_exec.c new file mode 100644 index 00000000..bb7b8360 --- /dev/null +++ b/src/httplib_websocket_write_exec.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2016 Lammert Bies + * Copyright (c) 2013-2016 the Civetweb developers + * Copyright (c) 2004-2013 Sergey Lyubka + * + * 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. + */ + + + +#include "libhttp-private.h" + + + +/* + * int XX_httplib_websocket_write_exec( struct mg_connection *conn, int opcode, const char *data, size_t dataLen, uint32_t masking_key ); + * + * The function XX_httplib_websocket_write_exec() does the heavy lifting in + * writing data over a websocket connectin to a remote peer. + */ + +#if defined(USE_WEBSOCKET) + +int XX_httplib_websocket_write_exec( struct mg_connection *conn, int opcode, const char *data, size_t dataLen, uint32_t masking_key ) { + + unsigned char header[14]; + size_t headerLen = 1; + + int retval = -1; + + header[0] = 0x80 + (opcode & 0xF); + + /* Frame format: http://tools.ietf.org/html/rfc6455#section-5.2 */ + if (dataLen < 126) { + /* inline 7-bit length field */ + header[1] = (unsigned char)dataLen; + headerLen = 2; + } else if (dataLen <= 0xFFFF) { + /* 16-bit length field */ + uint16_t len = htons((uint16_t)dataLen); + header[1] = 126; + memcpy(header + 2, &len, 2); + headerLen = 4; + } else { + /* 64-bit length field */ + uint32_t len1 = htonl((uint64_t)dataLen >> 32); + uint32_t len2 = htonl(dataLen & 0xFFFFFFFF); + header[1] = 127; + memcpy(header + 2, &len1, 4); + memcpy(header + 6, &len2, 4); + headerLen = 10; + } + + if (masking_key) { + /* add mask */ + header[1] |= 0x80; + memcpy(header + headerLen, &masking_key, 4); + headerLen += 4; + } + + + /* Note that POSIX/Winsock's send() is threadsafe + * http://stackoverflow.com/questions/1981372/are-parallel-calls-to-send-recv-on-the-same-socket-valid + * but mongoose's mg_printf/mg_write is not (because of the loop in + * push(), although that is only a problem if the packet is large or + * outgoing buffer is full). */ + (void)mg_lock_connection(conn); + retval = mg_write(conn, header, headerLen); + if (dataLen > 0) retval = mg_write(conn, data, dataLen); + mg_unlock_connection(conn); + + return retval; + +} /* XX_httplib_websocket_write_exec */ + +#endif /* !USE_WEBSOCKET */ diff --git a/src/libhttp.c b/src/libhttp.c index b6eed5be..bb215922 100644 --- a/src/libhttp.c +++ b/src/libhttp.c @@ -5425,11 +5425,11 @@ int XX_httplib_substitute_index_file( struct mg_connection *conn, char *path, si int XX_httplib_is_not_modified( const struct mg_connection *conn, const struct file *filep ) { char etag[64]; - const char *ims = mg_get_header(conn, "If-Modified-Since"); - const char *inm = mg_get_header(conn, "If-None-Match"); + const char *ims = mg_get_header( conn, "If-Modified-Since" ); + const char *inm = mg_get_header( conn, "If-None-Match" ); construct_etag(etag, sizeof(etag), filep); - if (!filep) return 0; + if ( filep == NULL ) return 0; return (inm != NULL && !mg_strcasecmp(etag, inm)) || (ims != NULL && (filep->last_modified <= parse_date_string(ims))); } /* XX_httplib_is_not_modified */ @@ -5837,9 +5837,9 @@ void XX_httplib_handle_cgi_request( struct mg_connection *conn, const char *prog goto done; } - setbuf(in, NULL); - setbuf(out, NULL); - setbuf(err, NULL); + setbuf( in, NULL ); + setbuf( out, NULL ); + setbuf( err, NULL ); fout.fp = out; if ((conn->request_info.content_length > 0) || conn->is_chunked) { @@ -6251,19 +6251,18 @@ static void do_ssi_exec(struct mg_connection *conn, char *tag) { #endif /* !NO_POPEN */ -static int mg_fgetc(struct file *filep, int offset) { +static int mg_fgetc( struct file *filep, int offset ) { - if (filep == NULL) return EOF; - if (filep->membuf != NULL && offset >= 0 - && ((unsigned int)(offset)) < filep->size) { - return ((const unsigned char *)filep->membuf)[offset]; - } else if (filep->fp != NULL) { - return fgetc(filep->fp); - } else return EOF; -} + if ( filep == NULL ) return EOF; + if ( filep->membuf != NULL && offset >= 0 && ((unsigned int)(offset)) < filep->size ) return ((const unsigned char *)filep->membuf)[offset]; + if ( filep->fp != NULL ) return fgetc( filep->fp ); + + return EOF; + +} /* mg_fgetc */ -static void send_ssi_file(struct mg_connection *conn, const char *path, struct file *filep, int include_level) { +static void send_ssi_file( struct mg_connection *conn, const char *path, struct file *filep, int include_level ) { char buf[MG_BUF_LEN]; int ch; @@ -6283,12 +6282,10 @@ static void send_ssi_file(struct mg_connection *conn, const char *path, struct f buf[len++] = (char)ch; buf[len] = '\0'; /* assert(len <= (int) sizeof(buf)); */ - if (len > (int)sizeof(buf)) { - break; - } + if (len > (int)sizeof(buf)) break; if (len < 6 || memcmp(buf, "