1
0
mirror of https://github.com/lammertb/libhttp.git synced 2026-01-27 08:02:47 +03:00

Moved websocket_write_exec to own file

This commit is contained in:
Lammert Bies
2016-12-10 17:28:57 +01:00
parent 2fd77a9e3d
commit 60339f151b
3 changed files with 131 additions and 86 deletions

View File

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

View File

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

View File

@@ -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, "<!--#", 5) != 0) {
/* Not an SSI tag, pass it */
(void)mg_write(conn, buf, (size_t)len);
mg_write( conn, buf, (size_t)len );
} else {
if (!memcmp(buf + 5, "include", 7)) {
do_ssi_include(conn, path, buf + 12, include_level);
@@ -6485,25 +6482,29 @@ void XX_httplib_handle_propfind( struct mg_connection *conn, const char *path, s
} /* XX_httplib_handle_propfind */
#endif
void mg_lock_connection(struct mg_connection *conn) {
void mg_lock_connection( struct mg_connection *conn ) {
if (conn) pthread_mutex_lock(&conn->mutex);
}
if ( conn != NULL ) pthread_mutex_lock( & conn->mutex );
void mg_unlock_connection(struct mg_connection *conn) {
} /* mg_lock_connection */
if (conn) pthread_mutex_unlock(&conn->mutex);
}
void mg_unlock_connection( struct mg_connection *conn ) {
void mg_lock_context(struct mg_context *ctx) {
if ( conn != NULL ) pthread_mutex_unlock( & conn->mutex );
if (ctx) pthread_mutex_lock(&ctx->nonce_mutex);
}
} /* mg_unlock_connection */
void mg_unlock_context(struct mg_context *ctx) {
void mg_lock_context( struct mg_context *ctx ) {
if (ctx) (void)pthread_mutex_unlock(&ctx->nonce_mutex);
}
if ( ctx != NULL ) pthread_mutex_lock( & ctx->nonce_mutex );
} /* mg_lock_context */
void mg_unlock_context( struct mg_context *ctx ) {
if ( ctx != NULL ) pthread_mutex_unlock( & ctx->nonce_mutex );
} /* mg_unlock_context */
#if defined(USE_TIMERS)
#include "timer.inl"
@@ -6676,7 +6677,11 @@ static void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]) {
state[2] += c;
state[3] += d;
state[4] += e;
a = b = c = d = e = 0;
a = 0;
b = 0;
c = 0;
d = 0;
e = 0;
memset(block, '\0', sizeof(block));
}
@@ -6953,57 +6958,4 @@ void XX_httplib_read_websocket( struct mg_connection *conn, mg_websocket_data_ha
} /* XX_httplib_read_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 */