From 8456c050ea339be1daae82d8677d0a9a767aa80c Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 23 Sep 2018 22:39:31 -0700 Subject: [PATCH] GUACAMOLE-629: Add support for updating connection parameters of in-progress connections. --- src/libguac/guacamole/user-fntypes.h | 30 ++++++++++++++++++++++++++++ src/libguac/guacamole/user.h | 21 +++++++++++++++++++ src/libguac/user-handlers.c | 25 +++++++++++++++++++++++ src/libguac/user-handlers.h | 7 +++++++ 4 files changed, 83 insertions(+) diff --git a/src/libguac/guacamole/user-fntypes.h b/src/libguac/guacamole/user-fntypes.h index 13256c56..d8689322 100644 --- a/src/libguac/guacamole/user-fntypes.h +++ b/src/libguac/guacamole/user-fntypes.h @@ -237,6 +237,36 @@ typedef int guac_user_file_handler(guac_user* user, guac_stream* stream, typedef int guac_user_pipe_handler(guac_user* user, guac_stream* stream, char* mimetype, char* name); +/** + * Handler for Guacamole argument value (argv) streams received from a user. + * Argument value streams are real-time revisions to the connection parameters + * of an in-progress connection. Each such argument value stream begins when + * the user sends a "argv" instruction. To handle received data along this + * stream, implementations of this handler must assign blob and end handlers to + * the given stream object. + * + * @param user + * The user that opened the argument value stream. + * + * @param stream + * The stream object allocated by libguac to represent the argument value + * stream opened by the user. + * + * @param mimetype + * The mimetype of the data that will be sent along the stream. + * + * @param name + * The name of the connection parameter being updated. It is up to the + * implementation of this handler to decide whether and how to update a + * connection parameter. + * + * @return + * Zero if the opening of the argument value stream has been handled + * successfully, or non-zero if an error occurs. + */ +typedef int guac_user_argv_handler(guac_user* user, guac_stream* stream, + char* mimetype, char* name); + /** * Handler for Guacamole stream blobs. Each blob originates from a "blob" * instruction which was associated with a previously-created stream. diff --git a/src/libguac/guacamole/user.h b/src/libguac/guacamole/user.h index f89f8077..792c7421 100644 --- a/src/libguac/guacamole/user.h +++ b/src/libguac/guacamole/user.h @@ -475,6 +475,27 @@ struct guac_user { */ guac_user_audio_handler* audio_handler; + /** + * Handler for argv events (updates to the connection parameters of an + * in-progress connection) sent by the Guacamole web-client. + * + * The handler takes a guac_stream which contains the stream index and + * will persist through the duration of the transfer, the mimetype of + * the data being transferred, and the argument (connection parameter) + * name. + * + * Example: + * @code + * int argv_handler(guac_user* user, guac_stream* stream, + * char* mimetype, char* name); + * + * int guac_user_init(guac_user* user, int argc, char** argv) { + * user->argv_handler = argv_handler; + * } + * @endcode + */ + guac_user_argv_handler* argv_handler; + }; /** diff --git a/src/libguac/user-handlers.c b/src/libguac/user-handlers.c index 0e8ed38b..b84dc721 100644 --- a/src/libguac/user-handlers.c +++ b/src/libguac/user-handlers.c @@ -49,6 +49,7 @@ __guac_instruction_handler_mapping __guac_instruction_handler_map[] = { {"get", __guac_handle_get}, {"put", __guac_handle_put}, {"audio", __guac_handle_audio}, + {"argv", __guac_handle_argv}, {NULL, NULL} }; @@ -382,6 +383,30 @@ int __guac_handle_pipe(guac_user* user, int argc, char** argv) { return 0; } +int __guac_handle_argv(guac_user* user, int argc, char** argv) { + + /* Pull corresponding stream */ + int stream_index = atoi(argv[0]); + guac_stream* stream = __init_input_stream(user, stream_index); + if (stream == NULL) + return 0; + + /* If supported, call handler */ + if (user->argv_handler) + return user->argv_handler( + user, + stream, + argv[1], /* mimetype */ + argv[2] /* name */ + ); + + /* Otherwise, abort */ + guac_protocol_send_ack(user->socket, stream, + "Reconfiguring in-progress connections unsupported", + GUAC_PROTOCOL_STATUS_UNSUPPORTED); + return 0; +} + int __guac_handle_ack(guac_user* user, int argc, char** argv) { guac_stream* stream; diff --git a/src/libguac/user-handlers.h b/src/libguac/user-handlers.h index 7a1b623a..eedeba15 100644 --- a/src/libguac/user-handlers.h +++ b/src/libguac/user-handlers.h @@ -120,6 +120,13 @@ __guac_instruction_handler __guac_handle_file; */ __guac_instruction_handler __guac_handle_pipe; +/** + * Internal initial handler for the argv instruction. When a argv instruction + * is received, this handler will be called. The client's argv handler will + * be invoked if defined. + */ +__guac_instruction_handler __guac_handle_argv; + /** * Internal initial handler for the ack instruction. When a ack instruction * is received, this handler will be called. The client's ack handler will