mirror of
https://github.com/lammertb/libhttp.git
synced 2025-07-29 21:01:13 +03:00
Handler for websocket connection (Step 6/7)
Add an interface to register handler for websocket connections. See enhancement #30 and question #101
This commit is contained in:
@ -39,7 +39,7 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v110_xp</PlatformToolset>
|
||||
<PlatformToolset>v100</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
|
@ -39,7 +39,7 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v110_xp</PlatformToolset>
|
||||
<PlatformToolset>v100</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
|
@ -46,7 +46,7 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v110_xp</PlatformToolset>
|
||||
<PlatformToolset>v100</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
|
@ -40,6 +40,7 @@
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v100</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
@ -116,7 +117,7 @@
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>USE_WEBSOCKET;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>USE_WEBSOCKET;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
|
@ -40,6 +40,7 @@
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v100</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
@ -116,7 +117,7 @@
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>USE_WEBSOCKET;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>USE_WEBSOCKET;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
|
@ -26,6 +26,7 @@
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v100</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
@ -46,7 +46,7 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v110_xp</PlatformToolset>
|
||||
<PlatformToolset>v100</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
|
@ -132,14 +132,13 @@ int WebSocketConnectHandler(const struct mg_connection * conn, void *cbdata)
|
||||
return reject;
|
||||
}
|
||||
|
||||
void WebSocketReadyHandler(const struct mg_connection * conn, void *cbdata)
|
||||
void WebSocketReadyHandler(struct mg_connection * conn, void *cbdata)
|
||||
{
|
||||
struct mg_context *ctx = mg_get_context((struct mg_connection *) /* TODO: check const_casts */ conn);
|
||||
struct mg_context *ctx = mg_get_context(conn);
|
||||
int i;
|
||||
|
||||
const char * text = "Hello from the websocket ready handler";
|
||||
/* TODO: check "const struct mg_connection *" vs "struct mg_connection *" everywhere */
|
||||
mg_websocket_write((struct mg_connection *)conn, WEBSOCKET_OPCODE_TEXT, text, strlen(text));
|
||||
mg_websocket_write(conn, WEBSOCKET_OPCODE_TEXT, text, strlen(text));
|
||||
fprintf(stdout, "Client added to the set of webserver connections\r\n\r\n");
|
||||
mg_lock_context(ctx);
|
||||
for (i=0; i<MAX_WS_CLIENTS; i++) {
|
||||
@ -151,7 +150,7 @@ void WebSocketReadyHandler(const struct mg_connection * conn, void *cbdata)
|
||||
mg_unlock_context(ctx);
|
||||
}
|
||||
|
||||
int WebsocketDataHandler(const struct mg_connection * conn, int bits, char * data, size_t len, void *cbdata)
|
||||
int WebsocketDataHandler(struct mg_connection * conn, int bits, char * data, size_t len, void *cbdata)
|
||||
{
|
||||
fprintf(stdout, "Websocket got data:\r\n");
|
||||
fwrite(data, len, 1, stdout);
|
||||
|
@ -105,9 +105,9 @@ struct tclient_data {
|
||||
int closed;
|
||||
};
|
||||
|
||||
static int websocket_client_data_handler(const struct mg_connection *conn, int flags, char *data, size_t data_len, void * user_data)
|
||||
static int websocket_client_data_handler(struct mg_connection *conn, int flags, char *data, size_t data_len, void * user_data)
|
||||
{
|
||||
struct mg_context *ctx = mg_get_context(conn); /* TODO: const qualifier */
|
||||
struct mg_context *ctx = mg_get_context(conn);
|
||||
struct tclient_data *pclient_data = (struct tclient_data *) mg_get_user_data(ctx);
|
||||
|
||||
printf("Client received data from server: ");
|
||||
@ -124,7 +124,7 @@ static int websocket_client_data_handler(const struct mg_connection *conn, int f
|
||||
|
||||
static void websocket_client_close_handler(const struct mg_connection *conn, void * user_data)
|
||||
{
|
||||
struct mg_context *ctx = mg_get_context(conn); /* TODO: const qualifier */
|
||||
struct mg_context *ctx = mg_get_context(conn);
|
||||
struct tclient_data *pclient_data = (struct tclient_data *) mg_get_user_data(ctx);
|
||||
|
||||
printf("Client: Close handler\n");
|
||||
|
@ -293,8 +293,8 @@ CIVETWEB_API void mg_set_request_handler(struct mg_context *ctx, const char *uri
|
||||
mg_connection_close_handler
|
||||
Is called, when the connection is closed.*/
|
||||
typedef int (*mg_websocket_connect_handler)(const struct mg_connection *, void *);
|
||||
typedef void (*mg_websocket_ready_handler)(const struct mg_connection *, void *);
|
||||
typedef int (*mg_websocket_data_handler)(const struct mg_connection *, int, char *, size_t, void *);
|
||||
typedef void (*mg_websocket_ready_handler)(struct mg_connection *, void *);
|
||||
typedef int (*mg_websocket_data_handler)(struct mg_connection *, int, char *, size_t, void *);
|
||||
typedef void (*mg_websocket_close_handler)(const struct mg_connection *, void *);
|
||||
|
||||
/* mg_set_websocket_handler
|
||||
@ -320,7 +320,7 @@ CIVETWEB_API const char *mg_get_option(const struct mg_context *ctx, const char
|
||||
|
||||
|
||||
/* Get context from connection. */
|
||||
CIVETWEB_API struct mg_context *mg_get_context(struct mg_connection *conn);
|
||||
CIVETWEB_API struct mg_context *mg_get_context(const struct mg_connection *conn);
|
||||
|
||||
|
||||
/* Get user data passed to mg_start from context. */
|
||||
|
@ -1220,7 +1220,7 @@ const char *mg_get_option(const struct mg_context *ctx, const char *name)
|
||||
}
|
||||
}
|
||||
|
||||
struct mg_context *mg_get_context(struct mg_connection * conn)
|
||||
struct mg_context *mg_get_context(const struct mg_connection * conn)
|
||||
{
|
||||
return (conn == NULL) ? (struct mg_context *)NULL : (conn->ctx);
|
||||
}
|
||||
@ -5755,7 +5755,7 @@ static void read_websocket(struct mg_connection *conn, mg_websocket_data_handler
|
||||
The original websocket upgrade request is never removed, so the queue
|
||||
begins after it. */
|
||||
unsigned char *buf = (unsigned char *) conn->buf + conn->request_len;
|
||||
int n, error;
|
||||
int n, error, exit_by_callback;
|
||||
|
||||
/* body_len is the length of the entire queue in bytes
|
||||
len is the length of the current message
|
||||
@ -5867,6 +5867,7 @@ static void read_websocket(struct mg_connection *conn, mg_websocket_data_handler
|
||||
|
||||
/* Exit the loop if callback signalled to exit,
|
||||
or "connection close" opcode received. */
|
||||
exit_by_callback = 0;
|
||||
if ((ws_data_handler != NULL &&
|
||||
#ifdef USE_LUA
|
||||
(conn->lua_websocket_state == NULL) &&
|
||||
@ -5876,13 +5877,19 @@ static void read_websocket(struct mg_connection *conn, mg_websocket_data_handler
|
||||
(conn->lua_websocket_state &&
|
||||
!lua_websocket_data(conn, conn->lua_websocket_state, mop, data, data_len)) ||
|
||||
#endif
|
||||
(mop & 0xf) == WEBSOCKET_OPCODE_CONNECTION_CLOSE) { /* Opcode == 8, connection close */
|
||||
break;
|
||||
0) {
|
||||
exit_by_callback = 1;
|
||||
}
|
||||
|
||||
if (data != mem) {
|
||||
mg_free(data);
|
||||
}
|
||||
|
||||
if (exit_by_callback || ((mop & 0xf) == WEBSOCKET_OPCODE_CONNECTION_CLOSE)) {
|
||||
/* Opcode == 8, connection close */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Not breaking the loop, process next websocket frame. */
|
||||
} else {
|
||||
/* Read from the socket into the next available location in the
|
||||
@ -5952,9 +5959,8 @@ static void handle_websocket_request(struct mg_connection *conn,
|
||||
const char *version = mg_get_header(conn, "Sec-WebSocket-Version");
|
||||
int lua_websock = 0;
|
||||
|
||||
#ifndef USE_LUA
|
||||
#if !defined(USE_LUA)
|
||||
(void)path;
|
||||
(void)is_callback_resource;
|
||||
#endif
|
||||
|
||||
/* Step 1: Check websocket protocol version. */
|
||||
@ -5974,7 +5980,7 @@ static void handle_websocket_request(struct mg_connection *conn,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_LUA
|
||||
#if defined(USE_LUA)
|
||||
/* Step 3: No callback. Check if Lua is responsible. */
|
||||
else {
|
||||
/* Step 3.1: Check if Lua is responsible. */
|
||||
@ -6011,11 +6017,13 @@ static void handle_websocket_request(struct mg_connection *conn,
|
||||
if (ws_ready_handler != NULL) {
|
||||
ws_ready_handler(conn, cbData);
|
||||
}
|
||||
#if defined(USE_LUA)
|
||||
} else if (lua_websock) {
|
||||
if (!lua_websocket_ready(conn, conn->lua_websocket_state)) {
|
||||
/* the ready handler returned false */
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Step 7: Enter the read loop */
|
||||
|
@ -26,6 +26,7 @@
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v100</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
@ -26,6 +26,7 @@
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v100</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
Reference in New Issue
Block a user