Removed resource subprotocol (in favor of protocol nesting).

This commit is contained in:
Michael Jumper 2012-10-18 01:34:25 -07:00
parent eabd17df64
commit 657b83808c
13 changed files with 1 additions and 515 deletions

View File

@ -106,20 +106,6 @@ int __guac_handle_clipboard(guac_client* client, guac_instruction* instruction);
*/ */
int __guac_handle_disconnect(guac_client* client, guac_instruction* instruction); int __guac_handle_disconnect(guac_client* client, guac_instruction* instruction);
/**
* Internal initial handler for the accept instruction. When an accept instruction
* is received, this handler will be called. The accept handler of the corresponding
* resource will be called if the resource is valid and the handler is defined.
*/
int __guac_handle_accept(guac_client* client, guac_instruction* instruction);
/**
* Internal initial handler for the reject instruction. When a reject instruction
* is received, this handler will be called. The reject handler of the corresponding
* resource will be called if the resource is valid and the handler is defined.
*/
int __guac_handle_reject(guac_client* client, guac_instruction* instruction);
/** /**
* Instruction handler mapping table. This is a NULL-terminated array of * Instruction handler mapping table. This is a NULL-terminated array of
* __guac_instruction_handler_mapping structures, each mapping an opcode * __guac_instruction_handler_mapping structures, each mapping an opcode

View File

@ -44,7 +44,6 @@
#include "instruction.h" #include "instruction.h"
#include "layer.h" #include "layer.h"
#include "pool.h" #include "pool.h"
#include "resource.h"
#include "socket.h" #include "socket.h"
#include "timestamp.h" #include "timestamp.h"
@ -134,14 +133,6 @@ typedef int guac_client_init_handler(guac_client* client, int argc, char** argv)
*/ */
#define GUAC_BUFFER_POOL_INITIAL_SIZE 1024 #define GUAC_BUFFER_POOL_INITIAL_SIZE 1024
/**
* The number of initial slots to allocate for resources within the client resource
* map. The client resource map maps resource indices to actual guac_resource instances.
* This map will need to be reallocated once the number of resources required exceeds
* the available number of slots.
*/
#define GUAC_RESOURCE_MAP_INITIAL_SIZE 1024
/** /**
* Possible current states of the Guacamole client. Currently, the only * Possible current states of the Guacamole client. Currently, the only
* two states are GUAC_CLIENT_RUNNING and GUAC_CLIENT_STOPPING. * two states are GUAC_CLIENT_RUNNING and GUAC_CLIENT_STOPPING.
@ -373,21 +364,6 @@ struct guac_client {
*/ */
guac_pool* __layer_pool; guac_pool* __layer_pool;
/**
* Pool of server-side resource indices.
*/
guac_pool* __resource_pool;
/**
* Array of all allocated resources.
*/
guac_resource** __resource_map;
/**
* The number of elements in the __resource_map array.
*/
int __available_resource_slots;
}; };
/** /**
@ -512,25 +488,6 @@ void guac_client_free_buffer(guac_client* client, guac_layer* layer);
*/ */
void guac_client_free_layer(guac_client* client, guac_layer* layer); void guac_client_free_layer(guac_client* client, guac_layer* layer);
/**
* Allocates a new resource. An arbitrary index is automatically assigned
* if no existing resource index is available for use.
*
* @param client The proxy client to allocate the resource for.
* @return The next available resource, or a newly allocated resource.
*/
guac_resource* guac_client_alloc_resource(guac_client* client);
/**
* Frees an existing resource, re-adding it to the client's resource
* pool, such that it can be reused by a subsequent call to
* guac_client_alloc_resource().
*
* @param client The proxy client to free the resource for.
* @oaran resource The resource to return to the resource pool.
*/
void guac_client_free_resource(guac_client* client, guac_resource* resource);
/** /**
* The default Guacamole client layer, layer 0. * The default Guacamole client layer, layer 0.
*/ */

View File

@ -56,13 +56,6 @@ struct guac_layer {
*/ */
int index; int index;
/**
* The URI which must be passed via a resource instruction to denote
* a resource related to this layer. This value is automatically set
* upon allocation.
*/
char* uri;
}; };
#endif #endif

View File

@ -41,7 +41,6 @@
#include <cairo/cairo.h> #include <cairo/cairo.h>
#include "layer.h" #include "layer.h"
#include "resource.h"
#include "socket.h" #include "socket.h"
#include "timestamp.h" #include "timestamp.h"
@ -193,22 +192,6 @@ int guac_protocol_send_args(guac_socket* socket, const char** args);
*/ */
int guac_protocol_send_connect(guac_socket* socket, const char** args); int guac_protocol_send_connect(guac_socket* socket, const char** args);
/**
* Sends a data 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.
* @param resource The resource associated with the data being sent.
* @param data The data to send.
* @param size The number of bytes from the beginning of the given buffer
* of data to send.
* @return Zero on success, non-zero on error.
*/
int guac_protocol_send_data(guac_socket* socket, guac_resource* resource,
const unsigned char* data, size_t size);
/** /**
* Sends a disconnect instruction over the given guac_socket connection. * Sends a disconnect instruction over the given guac_socket connection.
* *
@ -220,18 +203,6 @@ int guac_protocol_send_data(guac_socket* socket, guac_resource* resource,
*/ */
int guac_protocol_send_disconnect(guac_socket* socket); int guac_protocol_send_disconnect(guac_socket* socket);
/**
* Sends an end 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.
* @param resource The resource being closed.
* @return Zero on success, non-zero on error.
*/
int guac_protocol_send_end(guac_socket* socket, guac_resource* resource);
/** /**
* Sends an error instruction over the given guac_socket connection. * Sends an error instruction over the given guac_socket connection.
* *
@ -244,22 +215,6 @@ int guac_protocol_send_end(guac_socket* socket, guac_resource* resource);
*/ */
int guac_protocol_send_error(guac_socket* socket, const char* error); int guac_protocol_send_error(guac_socket* socket, const char* error);
/**
* Sends a resource 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.
* @param resource The resource being exposed.
* @param uri The URI this resource should be exposed to.
* @param mimetypes A NULL-terminated array of strings, where each string is
* an available mimetype.
* @return Zero on success, non-zero on error.
*/
int guac_protocol_send_resource(guac_socket* socket, guac_resource* resource,
const char* uri, const char** mimetypes);
/** /**
* Sends a set instruction over the given guac_socket connection. * Sends a set instruction over the given guac_socket connection.
* *

View File

@ -1,111 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is libguac.
*
* The Initial Developer of the Original Code is
* Michael Jumper.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef _GUAC_RESOURCE_H
#define _GUAC_RESOURCE_H
#include "client.h"
/**
* Provides functions and structures required for handling resources.
*
* NOTE: The data and end instructions are currently implemented client-side
* only, and allocation of resources must ALWAYS be server-side.
*
* Each resource is mono-directional. Two resources must be allocated for
* bidirectional communication.
*
* Exposure of client-side resources to the server will be accomplished
* over the same protocol (resource -> accept/reject -> data -> end). The
* mono-directional nature of resources will allow the index spaces of
* client and server resources to be independent.
*
* @file resource.h
*/
typedef struct guac_resource guac_resource;
/**
* Handler which begins resource transfer when the client accepts an exposed
* resource.
*/
typedef int guac_resource_accept_handler(guac_resource* resource,
const char* mimetype);
/**
* Handler which cancels resource transfer when the client rejects an exposed
* resource.
*/
typedef int guac_resource_reject_handler(guac_resource* resource);
/**
* Represents a single resource which can be requested or exposed via
* the Guacamole protocol.
*/
struct guac_resource {
/**
* The index of this resource.
*/
int index;
/**
* Handler which will be called when this resource is accepted by the
* client.
*/
guac_resource_accept_handler* accept_handler;
/**
* Handler which will be called when this resource is rejected by the
* client.
*/
guac_resource_reject_handler* reject_handler;
/**
* The client this resource was allocated for.
*/
guac_client* client;
/**
* Arbitrary data associated with this resource.
*/
void* data;
};
#endif

View File

@ -48,7 +48,6 @@ libguacinc_HEADERS = \
../include/plugin.h \ ../include/plugin.h \
../include/pool.h \ ../include/pool.h \
../include/protocol.h \ ../include/protocol.h \
../include/resource.h \
../include/socket.h \ ../include/socket.h \
../include/timestamp.h ../include/timestamp.h

View File

@ -50,8 +50,6 @@ __guac_instruction_handler_mapping __guac_instruction_handler_map[] = {
{"key", __guac_handle_key}, {"key", __guac_handle_key},
{"clipboard", __guac_handle_clipboard}, {"clipboard", __guac_handle_clipboard},
{"disconnect", __guac_handle_disconnect}, {"disconnect", __guac_handle_disconnect},
{"accept", __guac_handle_accept},
{"reject", __guac_handle_reject},
{NULL, NULL} {NULL, NULL}
}; };
@ -122,42 +120,3 @@ int __guac_handle_disconnect(guac_client* client, guac_instruction* instruction)
return -1; return -1;
} }
int __guac_handle_accept(guac_client* client, guac_instruction* instruction) {
/* Get index, check validity */
int index = __guac_parse_int(instruction->argv[0]);
if (index < client->__available_resource_slots) {
/* Build parameters */
char* mimetype = instruction->argv[1];
guac_resource* resource = client->__resource_map[index];
/* If accept handler defined, call it */
if (resource->accept_handler)
return resource->accept_handler(resource, mimetype);
}
/* Ignore invalid indices */
return 0;
}
int __guac_handle_reject(guac_client* client, guac_instruction* instruction) {
/* Get index, check validity */
int index = __guac_parse_int(instruction->argv[0]);
if (index < client->__available_resource_slots) {
/* Build parameters */
guac_resource* resource = client->__resource_map[index];
/* If reject handler defined, call it */
if (resource->reject_handler)
return resource->reject_handler(resource);
}
return 0;
}

View File

@ -50,42 +50,16 @@
#include "time.h" #include "time.h"
guac_layer __GUAC_DEFAULT_LAYER = { guac_layer __GUAC_DEFAULT_LAYER = {
.index = 0, .index = 0
.uri = "layer://0",
}; };
const guac_layer* GUAC_DEFAULT_LAYER = &__GUAC_DEFAULT_LAYER; const guac_layer* GUAC_DEFAULT_LAYER = &__GUAC_DEFAULT_LAYER;
guac_resource* guac_client_alloc_resource(guac_client* client) {
/* Init new layer */
guac_resource* resource = malloc(sizeof(guac_resource));
resource->index = guac_pool_next_int(client->__resource_pool);
resource->accept_handler = NULL;
resource->reject_handler = NULL;
resource->data = NULL;
/* Resize resource map if necessary */
if (resource->index >= client->__available_resource_slots) {
client->__available_resource_slots = resource->index * 2;
client->__resource_map = realloc(client->__resource_map,
sizeof(guac_resource*) * client->__available_resource_slots);
}
/* Store resource in map */
client->__resource_map[resource->index] = resource;
return resource;
}
guac_layer* guac_client_alloc_layer(guac_client* client) { guac_layer* guac_client_alloc_layer(guac_client* client) {
/* Init new layer */ /* Init new layer */
guac_layer* allocd_layer = malloc(sizeof(guac_layer)); guac_layer* allocd_layer = malloc(sizeof(guac_layer));
allocd_layer->index = guac_pool_next_int(client->__layer_pool)+1; allocd_layer->index = guac_pool_next_int(client->__layer_pool)+1;
allocd_layer->uri = malloc(64);
snprintf(allocd_layer->uri, 64, "layer://%i", allocd_layer->index);
return allocd_layer; return allocd_layer;
@ -96,23 +70,11 @@ guac_layer* guac_client_alloc_buffer(guac_client* client) {
/* Init new layer */ /* Init new layer */
guac_layer* allocd_layer = malloc(sizeof(guac_layer)); guac_layer* allocd_layer = malloc(sizeof(guac_layer));
allocd_layer->index = -guac_pool_next_int(client->__buffer_pool) - 1; allocd_layer->index = -guac_pool_next_int(client->__buffer_pool) - 1;
allocd_layer->uri = malloc(64);
snprintf(allocd_layer->uri, 64, "layer://%i", allocd_layer->index);
return allocd_layer; return allocd_layer;
} }
void guac_client_free_resource(guac_client* client, guac_resource* resource) {
/* Release index to pool */
guac_pool_free_int(client->__resource_pool, resource->index);
/* Free resource */
free(resource);
}
void guac_client_free_buffer(guac_client* client, guac_layer* layer) { void guac_client_free_buffer(guac_client* client, guac_layer* layer) {
/* Release index to pool */ /* Release index to pool */
@ -155,12 +117,6 @@ guac_client* guac_client_alloc() {
client->__buffer_pool = guac_pool_alloc(GUAC_BUFFER_POOL_INITIAL_SIZE); client->__buffer_pool = guac_pool_alloc(GUAC_BUFFER_POOL_INITIAL_SIZE);
client->__layer_pool = guac_pool_alloc(GUAC_BUFFER_POOL_INITIAL_SIZE); client->__layer_pool = guac_pool_alloc(GUAC_BUFFER_POOL_INITIAL_SIZE);
/* Allocate resource pool */
client->__resource_pool = guac_pool_alloc(0);
client->__available_resource_slots = GUAC_RESOURCE_MAP_INITIAL_SIZE;
client->__resource_map =
malloc(sizeof(guac_resource*) * client->__available_resource_slots);
return client; return client;
} }
@ -178,10 +134,6 @@ void guac_client_free(guac_client* client) {
guac_pool_free(client->__buffer_pool); guac_pool_free(client->__buffer_pool);
guac_pool_free(client->__layer_pool); guac_pool_free(client->__layer_pool);
/* Free resource pool */
guac_pool_free(client->__resource_pool);
free(client->__resource_map);
free(client); free(client);
} }

View File

@ -575,26 +575,6 @@ int guac_protocol_send_curve(guac_socket* socket, const guac_layer* layer,
} }
int guac_protocol_send_data(guac_socket* socket, guac_resource* resource,
const unsigned char* data, size_t size) {
/* Calculate base64 length */
int base64_length = (size + 2) / 3 * 4;
/* Send base64-encoded data */
return
guac_socket_write_string(socket, "4.data,")
|| __guac_socket_write_length_int(socket, resource->index)
|| guac_socket_write_string(socket, ",")
|| guac_socket_write_int(socket, base64_length)
|| guac_socket_write_string(socket, ".")
|| guac_socket_write_base64(socket, data, size)
|| guac_socket_flush_base64(socket)
|| guac_socket_write_string(socket, ";");
}
int guac_protocol_send_disconnect(guac_socket* socket) { int guac_protocol_send_disconnect(guac_socket* socket) {
return guac_socket_write_string(socket, "10.disconnect;"); return guac_socket_write_string(socket, "10.disconnect;");
} }
@ -634,15 +614,6 @@ int guac_protocol_send_distort(guac_socket* socket, const guac_layer* layer,
} }
int guac_protocol_send_end(guac_socket* socket, guac_resource* resource) {
return
guac_socket_write_string(socket, "3.end,")
|| __guac_socket_write_length_int(socket, resource->index)
|| guac_socket_write_string(socket, ";");
}
int guac_protocol_send_error(guac_socket* socket, const char* error) { int guac_protocol_send_error(guac_socket* socket, const char* error) {
return return
@ -813,39 +784,6 @@ int guac_protocol_send_reset(guac_socket* socket, const guac_layer* layer) {
} }
int guac_protocol_send_resource(guac_socket* socket, guac_resource* resource,
const char* uri, const char** mimetypes) {
/* Write resource header */
if (
guac_socket_write_string(socket, "8.resource,")
|| __guac_socket_write_length_int(socket, resource->index)
|| guac_socket_write_string(socket, ",")
|| __guac_socket_write_length_string(socket, uri)
)
return -1;
/* Write each mimetype */
while (*mimetypes != NULL) {
/* Write mimetype */
if (
guac_socket_write_string(socket, ",")
|| __guac_socket_write_length_string(socket, *mimetypes)
)
return -1;
/* Next mimetype */
mimetypes++;
}
/* Finish instruction */
return guac_socket_write_string(socket, ";");
}
int guac_protocol_send_set(guac_socket* socket, const guac_layer* layer, int guac_protocol_send_set(guac_socket* socket, const guac_layer* layer,
const char* name, const char* value) { const char* name, const char* value) {

View File

@ -51,7 +51,6 @@ test_libguac_SOURCES = \
client/client_suite.c \ client/client_suite.c \
client/buffer_pool.c \ client/buffer_pool.c \
client/layer_pool.c \ client/layer_pool.c \
client/resource_pool.c \
protocol/suite.c \ protocol/suite.c \
protocol/instruction_read.c \ protocol/instruction_read.c \
protocol/instruction_write.c \ protocol/instruction_write.c \

View File

@ -61,7 +61,6 @@ int register_client_suite() {
if ( if (
CU_add_test(suite, "layer-pool", test_layer_pool) == NULL CU_add_test(suite, "layer-pool", test_layer_pool) == NULL
|| CU_add_test(suite, "buffer-pool", test_buffer_pool) == NULL || CU_add_test(suite, "buffer-pool", test_buffer_pool) == NULL
|| CU_add_test(suite, "resource-pool", test_resource_pool) == NULL
) { ) {
CU_cleanup_registry(); CU_cleanup_registry();
return CU_get_error(); return CU_get_error();

View File

@ -42,7 +42,6 @@ int register_client_suite();
void test_layer_pool(); void test_layer_pool();
void test_buffer_pool(); void test_buffer_pool();
void test_resource_pool();
#endif #endif

View File

@ -1,139 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is libguac.
*
* The Initial Developer of the Original Code is
* Michael Jumper.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <CUnit/Basic.h>
#include "client.h"
#include "client_suite.h"
void test_resource_pool() {
guac_client* client;
guac_resource* resource0;
guac_resource* resource1;
guac_resource* resource2;
/* Get client */
client = guac_client_alloc();
CU_ASSERT_PTR_NOT_NULL_FATAL(client);
/*
* POOL: [ EMPTY ]
* IN USE: [ NONE ]
*/
/* First resource should be resource 0 */
resource0 = guac_client_alloc_resource(client);
CU_ASSERT_PTR_NOT_NULL_FATAL(resource0);
CU_ASSERT_EQUAL_FATAL(0, resource0->index);
/*
* POOL: [ EMPTY ]
* IN USE: [ 0 ]
*/
/* Put 0 back in pool (1) */
guac_client_free_resource(client, resource0);
/*
* POOL: [ 0 ]
* IN USE: [ NONE ]
*/
/* Since we free'd 0, we should get 0 again here (1) */
resource0 = guac_client_alloc_resource(client);
CU_ASSERT_PTR_NOT_NULL_FATAL(resource0);
CU_ASSERT_EQUAL_FATAL(0, resource0->index);
/*
* POOL: [ EMPTY ]
* IN USE: [ 0 ]
*/
/* We should get a new resource here */
resource1 = guac_client_alloc_resource(client);
CU_ASSERT_PTR_NOT_NULL_FATAL(resource1);
CU_ASSERT_EQUAL_FATAL(1, resource1->index);
/*
* POOL: [ EMPTY ]
* IN USE: [ 0 1 ]
*/
/* Put 0 back in pool (2) */
guac_client_free_resource(client, resource0);
/*
* POOL: [ 0 ]
* IN USE: [ 1 ]
*/
/* Since we free'd 0, we should get 0 again here (2) */
resource0 = guac_client_alloc_resource(client);
CU_ASSERT_PTR_NOT_NULL_FATAL(resource0);
CU_ASSERT_EQUAL_FATAL(0, resource0->index);
/*
* POOL: [ EMPTY ]
* IN USE: [ 0 1 ]
*/
/* We should get a new resource here */
resource2 = guac_client_alloc_resource(client);
CU_ASSERT_PTR_NOT_NULL_FATAL(resource2);
CU_ASSERT_EQUAL_FATAL(2, resource2->index);
/*
* POOL: [ EMPTY ]
* IN USE: [ 0 1 2 ]
*/
/* Free all resources */
guac_client_free_resource(client, resource2);
guac_client_free_resource(client, resource1);
guac_client_free_resource(client, resource0);
/*
* POOL: [ 0 1 2 ]
* IN USE: [ EMPTY ]
*/
/* Free client */
guac_client_free(client);
}