net: websocket: pass HTTP upgrade request context to user callback
Passing HTTP upgrade request context to the user callback allows the user to decide whether to accept or reject the websocket connection based on the HTTP headers in the request. The primary reason for this is to enable authentication of the websocket connection (e.g. via cookies or Authorization header). Signed-off-by: Matt Rodgers <mrodgers@witekio.com>
This commit is contained in:
parent
91c10f14f9
commit
549e5de277
7 changed files with 23 additions and 9 deletions
|
|
@ -254,6 +254,7 @@ BUILD_ASSERT(offsetof(struct http_resource_detail_dynamic, common) == 0);
|
|||
* reading and writing websocket data, and closing the connection.
|
||||
*
|
||||
* @param ws_socket A socket for the Websocket data.
|
||||
* @param request_ctx Request context structure associated with HTTP upgrade request
|
||||
* @param user_data User specified data.
|
||||
*
|
||||
* @return 0 Accepting the connection, HTTP server library will no longer
|
||||
|
|
@ -261,7 +262,7 @@ BUILD_ASSERT(offsetof(struct http_resource_detail_dynamic, common) == 0);
|
|||
* to send and receive data to/from the supplied socket.
|
||||
* <0 error, close the connection.
|
||||
*/
|
||||
typedef int (*http_resource_websocket_cb_t)(int ws_socket,
|
||||
typedef int (*http_resource_websocket_cb_t)(int ws_socket, struct http_request_ctx *request_ctx,
|
||||
void *user_data);
|
||||
|
||||
/** @brief Representation of a websocket server resource */
|
||||
|
|
|
|||
|
|
@ -62,8 +62,8 @@ struct shell_websocket {
|
|||
};
|
||||
|
||||
extern const struct shell_transport_api shell_websocket_transport_api;
|
||||
extern int shell_websocket_setup(int ws_socket, void *user_data);
|
||||
extern int shell_websocket_enable(const struct shell *sh);
|
||||
int shell_websocket_setup(int ws_socket, struct http_request_ctx *request_ctx, void *user_data);
|
||||
int shell_websocket_enable(const struct shell *sh);
|
||||
|
||||
#define GET_WS_NAME(_service) ws_ctx_##_service
|
||||
#define GET_WS_SHELL_NAME(_name) shell_websocket_##_name
|
||||
|
|
|
|||
|
|
@ -295,7 +295,7 @@ int ws_netstats_init(void)
|
|||
}
|
||||
SYS_INIT(ws_netstats_init, APPLICATION, 0);
|
||||
|
||||
int ws_echo_setup(int ws_socket, void *user_data)
|
||||
int ws_echo_setup(int ws_socket, struct http_request_ctx *request_ctx, void *user_data)
|
||||
{
|
||||
int slot;
|
||||
|
||||
|
|
@ -331,7 +331,7 @@ int ws_echo_setup(int ws_socket, void *user_data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ws_netstats_setup(int ws_socket, void *user_data)
|
||||
int ws_netstats_setup(int ws_socket, struct http_request_ctx *request_ctx, void *user_data)
|
||||
{
|
||||
int ret;
|
||||
int slot;
|
||||
|
|
|
|||
|
|
@ -4,22 +4,26 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/net/http/server.h>
|
||||
|
||||
/**
|
||||
* @brief Setup websocket for echoing data back to client
|
||||
*
|
||||
* @param ws_socket Socket file descriptor associated with websocket
|
||||
* @param request_ctx Request context associated with websocket HTTP upgrade request
|
||||
* @param user_data User data pointer
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int ws_echo_setup(int ws_socket, void *user_data);
|
||||
int ws_echo_setup(int ws_socket, struct http_request_ctx *request_ctx, void *user_data);
|
||||
|
||||
/**
|
||||
* @brief Setup websocket for sending net statistics to client
|
||||
*
|
||||
* @param ws_socket Socket file descriptor associated with websocket
|
||||
* @param request_ctx Request context associated with websocket HTTP upgrade request
|
||||
* @param user_data User data pointer
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int ws_netstats_setup(int ws_socket, void *user_data);
|
||||
int ws_netstats_setup(int ws_socket, struct http_request_ctx *request_ctx, void *user_data);
|
||||
|
|
|
|||
|
|
@ -865,6 +865,7 @@ int handle_http1_request(struct http_client_ctx *client)
|
|||
goto not_found;
|
||||
}
|
||||
|
||||
detail->path_len = path_len;
|
||||
client->current_detail = detail;
|
||||
return handle_http1_to_websocket_upgrade(client);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,7 +93,10 @@ int handle_http1_to_websocket_upgrade(struct http_client_ctx *client)
|
|||
*/
|
||||
if (client->parser_state == HTTP1_MESSAGE_COMPLETE_STATE) {
|
||||
struct http_resource_detail_websocket *ws_detail;
|
||||
struct http_request_ctx request_ctx;
|
||||
int ws_sock;
|
||||
char *params;
|
||||
size_t params_len;
|
||||
|
||||
ws_detail = (struct http_resource_detail_websocket *)client->current_detail;
|
||||
|
||||
|
|
@ -105,9 +108,14 @@ int handle_http1_to_websocket_upgrade(struct http_client_ctx *client)
|
|||
goto error;
|
||||
}
|
||||
|
||||
memset(&request_ctx, 0, sizeof(request_ctx));
|
||||
params = &client->url_buffer[client->current_detail->path_len];
|
||||
params_len = strlen(params);
|
||||
populate_request_ctx(&request_ctx, params, params_len, &client->header_capture_ctx);
|
||||
|
||||
ret = ws_detail->cb(ws_sock, &request_ctx, ws_detail->user_data);
|
||||
http_server_release_client(client);
|
||||
|
||||
ret = ws_detail->cb(ws_sock, ws_detail->user_data);
|
||||
if (ret < 0) {
|
||||
NET_DBG("WS connection failed (%d)", ret);
|
||||
websocket_unregister(ws_sock);
|
||||
|
|
|
|||
|
|
@ -377,7 +377,7 @@ const struct shell_transport_api shell_websocket_transport_api = {
|
|||
.read = sh_read
|
||||
};
|
||||
|
||||
int shell_websocket_setup(int ws_socket, void *user_data)
|
||||
int shell_websocket_setup(int ws_socket, struct http_request_ctx *request_ctx, void *user_data)
|
||||
{
|
||||
struct shell_websocket *ws = user_data;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue