GUACAMOLE-629: Merge allow "argv" instructions to be sent from server to client.
This commit is contained in:
commit
95039ea3b3
@ -54,6 +54,7 @@ libguacinc_HEADERS = \
|
||||
guacamole/pool.h \
|
||||
guacamole/pool-types.h \
|
||||
guacamole/protocol.h \
|
||||
guacamole/protocol-constants.h \
|
||||
guacamole/protocol-types.h \
|
||||
guacamole/socket-constants.h \
|
||||
guacamole/socket.h \
|
||||
|
@ -516,6 +516,26 @@ int guac_client_get_processing_lag(guac_client* client) {
|
||||
|
||||
}
|
||||
|
||||
void guac_client_stream_argv(guac_client* client, guac_socket* socket,
|
||||
const char* mimetype, const char* name, const char* value) {
|
||||
|
||||
/* Allocate new stream for argument value */
|
||||
guac_stream* stream = guac_client_alloc_stream(client);
|
||||
|
||||
/* Declare stream as containing connection parameter data */
|
||||
guac_protocol_send_argv(socket, stream, mimetype, name);
|
||||
|
||||
/* Write parameter data */
|
||||
guac_protocol_send_blobs(socket, stream, value, strlen(value));
|
||||
|
||||
/* Terminate stream */
|
||||
guac_protocol_send_end(socket, stream);
|
||||
|
||||
/* Free allocated stream */
|
||||
guac_client_free_stream(client, stream);
|
||||
|
||||
}
|
||||
|
||||
void guac_client_stream_png(guac_client* client, guac_socket* socket,
|
||||
guac_composite_mode mode, const guac_layer* layer, int x, int y,
|
||||
cairo_surface_t* surface) {
|
||||
|
@ -59,7 +59,7 @@ typedef struct guac_jpeg_destination_mgr {
|
||||
/**
|
||||
* The output buffer.
|
||||
*/
|
||||
unsigned char buffer[6048];
|
||||
unsigned char buffer[GUAC_PROTOCOL_BLOB_MAX_LENGTH];
|
||||
|
||||
} guac_jpeg_destination_mgr;
|
||||
|
||||
|
@ -56,7 +56,7 @@ typedef struct guac_png_write_state {
|
||||
/**
|
||||
* Buffer of pending PNG data.
|
||||
*/
|
||||
char buffer[6048];
|
||||
char buffer[GUAC_PROTOCOL_BLOB_MAX_LENGTH];
|
||||
|
||||
/**
|
||||
* The number of bytes currently stored in the buffer.
|
||||
|
@ -52,7 +52,7 @@ typedef struct guac_webp_stream_writer {
|
||||
/**
|
||||
* Buffer of pending WebP data.
|
||||
*/
|
||||
char buffer[6048];
|
||||
char buffer[GUAC_PROTOCOL_BLOB_MAX_LENGTH];
|
||||
|
||||
/**
|
||||
* The number of bytes currently stored in the buffer.
|
||||
|
@ -548,6 +548,33 @@ int guac_client_load_plugin(guac_client* client, const char* protocol);
|
||||
*/
|
||||
int guac_client_get_processing_lag(guac_client* client);
|
||||
|
||||
/**
|
||||
* Streams the given connection parameter value over an argument value stream
|
||||
* ("argv" instruction), exposing the current value of the named connection
|
||||
* parameter to all users of the given client. The argument value stream will
|
||||
* be automatically allocated and freed.
|
||||
*
|
||||
* @param client
|
||||
* The Guacamole client for which the argument value stream should be
|
||||
* allocated.
|
||||
*
|
||||
* @param socket
|
||||
* The socket over which instructions associated with the argument value
|
||||
* stream should be sent.
|
||||
*
|
||||
* @param mimetype
|
||||
* The mimetype of the data within the connection parameter value being
|
||||
* sent.
|
||||
*
|
||||
* @param name
|
||||
* The name of the connection parameter being sent.
|
||||
*
|
||||
* @param value
|
||||
* The current value of the connection parameter being sent.
|
||||
*/
|
||||
void guac_client_stream_argv(guac_client* client, guac_socket* socket,
|
||||
const char* mimetype, const char* name, const char* value);
|
||||
|
||||
/**
|
||||
* Streams the image data of the given surface over an image stream ("img"
|
||||
* instruction) as PNG-encoded data. The image stream will be automatically
|
||||
|
53
src/libguac/guacamole/protocol-constants.h
Normal file
53
src/libguac/guacamole/protocol-constants.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#ifndef GUAC_PROTOCOL_CONSTANTS_H
|
||||
#define GUAC_PROTOCOL_CONSTANTS_H
|
||||
|
||||
/**
|
||||
* Constants related to the Guacamole protocol.
|
||||
*
|
||||
* @file protocol-constants.h
|
||||
*/
|
||||
|
||||
/**
|
||||
* This defines the overall protocol version that this build of libguac
|
||||
* supports. The protocol version is used to provide compatibility between
|
||||
* potentially different versions of Guacamole server and clients. The
|
||||
* version number is a MAJOR_MINOR_PATCH version that matches the versioning
|
||||
* used throughout the components of the Guacamole project. This version
|
||||
* will not necessarily increment with the other components, unless additional
|
||||
* functionality is introduced that affects compatibility.
|
||||
*
|
||||
* This version is passed by the __guac_protocol_send_args() function from the
|
||||
* server to the client during the client/server handshake.
|
||||
*/
|
||||
#define GUACAMOLE_PROTOCOL_VERSION "VERSION_1_1_0"
|
||||
|
||||
/**
|
||||
* The maximum number of bytes that should be sent in any one blob instruction
|
||||
* to ensure the instruction does not exceed the maximum allowed instruction
|
||||
* size.
|
||||
*
|
||||
* @see GUAC_INSTRUCTION_MAX_LENGTH
|
||||
*/
|
||||
#define GUAC_PROTOCOL_BLOB_MAX_LENGTH 6048
|
||||
|
||||
#endif
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
#include "layer-types.h"
|
||||
#include "object-types.h"
|
||||
#include "protocol-constants.h"
|
||||
#include "protocol-types.h"
|
||||
#include "socket-types.h"
|
||||
#include "stream-types.h"
|
||||
@ -38,20 +39,6 @@
|
||||
#include <cairo/cairo.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/**
|
||||
* This defines the overall protocol version that this build of libguac
|
||||
* supports. The protocol version is used to provide compatibility between
|
||||
* potentially different versions of Guacamole server and clients. The
|
||||
* version number is a MAJOR_MINOR_PATCH version that matches the versioning
|
||||
* used throughout the components of the Guacamole project. This version
|
||||
* will not necessarily increment with the other components, unless additional
|
||||
* functionality is introduced that affects compatibility.
|
||||
*
|
||||
* This version is passed by the __guac_protocol_send_args() function from the
|
||||
* server to the client during the client/server handshake.
|
||||
*/
|
||||
#define GUACAMOLE_PROTOCOL_VERSION "VERSION_1_1_0"
|
||||
|
||||
/* CONTROL INSTRUCTIONS */
|
||||
|
||||
/**
|
||||
@ -448,6 +435,37 @@ int guac_protocol_send_pipe(guac_socket* socket, const guac_stream* stream,
|
||||
int guac_protocol_send_blob(guac_socket* socket, const guac_stream* stream,
|
||||
const void* data, int count);
|
||||
|
||||
/**
|
||||
* Sends a series of blob instructions, splitting the given data across the
|
||||
* number of instructions required to ensure the size of each blob does not
|
||||
* exceed GUAC_PROTOCOL_BLOB_MAX_LENGTH. If the size of data provided is zero,
|
||||
* no blob instructions are sent.
|
||||
*
|
||||
* If an error occurs sending any blob instruction, a non-zero value is
|
||||
* returned, guac_error is set appropriately, and no further blobs are sent.
|
||||
*
|
||||
* @see GUAC_PROTOCOL_BLOB_MAX_LENGTH
|
||||
*
|
||||
* @param socket
|
||||
* The guac_socket connection to use to send the blob instructions.
|
||||
*
|
||||
* @param stream
|
||||
* The stream to associate with each blob sent.
|
||||
*
|
||||
* @param data
|
||||
* The data which should be sent using the required number of blob
|
||||
* instructions.
|
||||
*
|
||||
* @param count
|
||||
* The number of bytes within the given buffer of data that must be
|
||||
* written.
|
||||
*
|
||||
* @return
|
||||
* Zero on success, non-zero on error.
|
||||
*/
|
||||
int guac_protocol_send_blobs(guac_socket* socket, const guac_stream* stream,
|
||||
const void* data, int count);
|
||||
|
||||
/**
|
||||
* Sends an end instruction over the given guac_socket connection.
|
||||
*
|
||||
@ -932,6 +950,31 @@ int guac_protocol_send_size(guac_socket* socket, const guac_layer* layer,
|
||||
|
||||
/* TEXT INSTRUCTIONS */
|
||||
|
||||
/**
|
||||
* Sends an argv instruction over the given guac_socket connection.
|
||||
*
|
||||
* If an error occurs sending the instruction, a non-zero value is
|
||||
* returned, and guac_error is set appropriately.
|
||||
*
|
||||
* @param socket
|
||||
* The guac_socket connection to use to send the connection parameter
|
||||
* value.
|
||||
*
|
||||
* @param stream
|
||||
* The stream to use to send the connection parameter value.
|
||||
*
|
||||
* @param mimetype
|
||||
* The mimetype of the connection parameter value being sent.
|
||||
*
|
||||
* @param name
|
||||
* The name of the connection parameter whose current value is being sent.
|
||||
*
|
||||
* @return
|
||||
* Zero on success, non-zero on error.
|
||||
*/
|
||||
int guac_protocol_send_argv(guac_socket* socket, guac_stream* stream,
|
||||
const char* mimetype, const char* name);
|
||||
|
||||
/**
|
||||
* Sends a clipboard instruction over the given guac_socket connection.
|
||||
*
|
||||
|
@ -676,6 +676,32 @@ guac_object* guac_user_alloc_object(guac_user* user);
|
||||
*/
|
||||
void guac_user_free_object(guac_user* user, guac_object* object);
|
||||
|
||||
/**
|
||||
* Streams the given connection parameter value over an argument value stream
|
||||
* ("argv" instruction), exposing the current value of the named connection
|
||||
* parameter to the given user. The argument value stream will be automatically
|
||||
* allocated and freed.
|
||||
*
|
||||
* @param user
|
||||
* The Guacamole user who should receive the connection parameter value.
|
||||
*
|
||||
* @param socket
|
||||
* The socket over which instructions associated with the argument value
|
||||
* stream should be sent.
|
||||
*
|
||||
* @param mimetype
|
||||
* The mimetype of the data within the connection parameter value being
|
||||
* sent.
|
||||
*
|
||||
* @param name
|
||||
* The name of the connection parameter being sent.
|
||||
*
|
||||
* @param value
|
||||
* The current value of the connection parameter being sent.
|
||||
*/
|
||||
void guac_user_stream_argv(guac_user* user, guac_socket* socket,
|
||||
const char* mimetype, const char* name, const char* value);
|
||||
|
||||
/**
|
||||
* Streams the image data of the given surface over an image stream ("img"
|
||||
* instruction) as PNG-encoded data. The image stream will be automatically
|
||||
|
@ -125,6 +125,26 @@ int guac_protocol_send_args(guac_socket* socket, const char** args) {
|
||||
|
||||
}
|
||||
|
||||
int guac_protocol_send_argv(guac_socket* socket, guac_stream* stream,
|
||||
const char* mimetype, const char* name) {
|
||||
|
||||
int ret_val;
|
||||
|
||||
guac_socket_instruction_begin(socket);
|
||||
ret_val =
|
||||
guac_socket_write_string(socket, "4.argv,")
|
||||
|| __guac_socket_write_length_int(socket, stream->index)
|
||||
|| guac_socket_write_string(socket, ",")
|
||||
|| __guac_socket_write_length_string(socket, mimetype)
|
||||
|| guac_socket_write_string(socket, ",")
|
||||
|| __guac_socket_write_length_string(socket, name)
|
||||
|| guac_socket_write_string(socket, ";");
|
||||
|
||||
guac_socket_instruction_end(socket);
|
||||
return ret_val;
|
||||
|
||||
}
|
||||
|
||||
int guac_protocol_send_arc(guac_socket* socket, const guac_layer* layer,
|
||||
int x, int y, int radius, double startAngle, double endAngle,
|
||||
int negative) {
|
||||
@ -195,6 +215,33 @@ int guac_protocol_send_blob(guac_socket* socket, const guac_stream* stream,
|
||||
|
||||
}
|
||||
|
||||
int guac_protocol_send_blobs(guac_socket* socket, const guac_stream* stream,
|
||||
const void* data, int count) {
|
||||
|
||||
int ret_val = 0;
|
||||
|
||||
/* Send blob instructions while data remains and instructions are being
|
||||
* sent successfully */
|
||||
while (count > 0 && ret_val == 0) {
|
||||
|
||||
/* Limit blob size to maximum allowed */
|
||||
int blob_size = count;
|
||||
if (blob_size > GUAC_PROTOCOL_BLOB_MAX_LENGTH)
|
||||
blob_size = GUAC_PROTOCOL_BLOB_MAX_LENGTH;
|
||||
|
||||
/* Send next blob of data */
|
||||
ret_val = guac_protocol_send_blob(socket, stream, data, blob_size);
|
||||
|
||||
/* Advance to next blob */
|
||||
data = (const char*) data + blob_size;
|
||||
count -= blob_size;
|
||||
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
|
||||
}
|
||||
|
||||
int guac_protocol_send_body(guac_socket* socket, const guac_object* object,
|
||||
const guac_stream* stream, const char* mimetype, const char* name) {
|
||||
|
||||
|
@ -121,25 +121,8 @@ static void raw_encoder_flush_handler(guac_audio_stream* audio) {
|
||||
guac_socket* socket = audio->client->socket;
|
||||
guac_stream* stream = audio->stream;
|
||||
|
||||
unsigned char* current = state->buffer;
|
||||
int remaining = state->written;
|
||||
|
||||
/* Flush all data in buffer as blobs */
|
||||
while (remaining > 0) {
|
||||
|
||||
/* Determine size of blob to be written */
|
||||
int chunk_size = remaining;
|
||||
if (chunk_size > 6048)
|
||||
chunk_size = 6048;
|
||||
|
||||
/* Send audio data */
|
||||
guac_protocol_send_blob(socket, stream, current, chunk_size);
|
||||
|
||||
/* Advance to next blob */
|
||||
current += chunk_size;
|
||||
remaining -= chunk_size;
|
||||
|
||||
}
|
||||
guac_protocol_send_blobs(socket, stream, state->buffer, state->written);
|
||||
|
||||
/* All data has been flushed */
|
||||
state->written = 0;
|
||||
|
@ -229,6 +229,26 @@ void guac_user_log(guac_user* user, guac_client_log_level level,
|
||||
|
||||
}
|
||||
|
||||
void guac_user_stream_argv(guac_user* user, guac_socket* socket,
|
||||
const char* mimetype, const char* name, const char* value) {
|
||||
|
||||
/* Allocate new stream for argument value */
|
||||
guac_stream* stream = guac_user_alloc_stream(user);
|
||||
|
||||
/* Declare stream as containing connection parameter data */
|
||||
guac_protocol_send_argv(socket, stream, mimetype, name);
|
||||
|
||||
/* Write parameter data */
|
||||
guac_protocol_send_blobs(socket, stream, value, strlen(value));
|
||||
|
||||
/* Terminate stream */
|
||||
guac_protocol_send_end(socket, stream);
|
||||
|
||||
/* Free allocated stream */
|
||||
guac_user_free_stream(user, stream);
|
||||
|
||||
}
|
||||
|
||||
void guac_user_stream_png(guac_user* user, guac_socket* socket,
|
||||
guac_composite_mode mode, const guac_layer* layer, int x, int y,
|
||||
cairo_surface_t* surface) {
|
||||
|
Loading…
Reference in New Issue
Block a user