protobuf-c-rpc/protobuf-c-rpc.c: handle server responses with NULL

messages on the client side (fixes #78)

protobuf-c-rpc/t/test-rpc.c: add a test case for #78
This commit is contained in:
Ilya Lipnitskiy 2013-11-18 22:14:36 -08:00
parent 4610a0d40e
commit 5d74333219
2 changed files with 39 additions and 18 deletions

View File

@ -562,7 +562,6 @@ handle_client_fd_events (int fd,
uint32_t header[4];
unsigned status_code, method_index, message_length, request_id;
Closure *closure;
uint8_t *packed_data;
ProtobufCMessage *msg;
protobuf_c_data_buffer_peek (&client->incoming, header, sizeof (header));
status_code = uint32_from_le (header[0]);
@ -583,23 +582,36 @@ handle_client_fd_events (int fd,
}
closure = client->info.connected.closures + (request_id - 1);
/* read message and unpack */
/* Discard the RPC header */
protobuf_c_data_buffer_discard (&client->incoming, 16);
packed_data = client->allocator->alloc (client->allocator, message_length);
protobuf_c_data_buffer_read (&client->incoming, packed_data, message_length);
/* TODO: use fast temporary allocator */
msg = protobuf_c_message_unpack (closure->response_type,
client->allocator,
message_length,
packed_data);
if (msg == NULL)
{
fprintf(stderr, "unable to unpack msg of length %u", message_length);
client_failed (client, "failed to unpack message");
client->allocator->free (client->allocator, packed_data);
return;
}
if (status_code == PROTOBUF_C_STATUS_CODE_SUCCESS)
{
/* read message and unpack */
uint8_t *packed_data =
client->allocator->alloc (client->allocator, message_length);
protobuf_c_data_buffer_read (&client->incoming, packed_data, message_length);
/* TODO: use fast temporary allocator */
msg = protobuf_c_message_unpack (closure->response_type,
client->allocator,
message_length,
packed_data);
client->allocator->free (client->allocator, packed_data);
if (msg == NULL)
{
fprintf(stderr, "unable to unpack msg of length %u", message_length);
client_failed (client, "failed to unpack message");
return;
}
}
else
{
/* Server did not send a response message */
protobuf_c_assert (message_length == 0);
msg = NULL;
}
/* invoke closure */
closure->closure (msg, closure->closure_data);
@ -609,8 +621,8 @@ handle_client_fd_events (int fd,
client->info.connected.first_free_request_id = request_id;
/* clean up */
protobuf_c_message_free_unpacked (msg, client->allocator);
client->allocator->free (client->allocator, packed_data);
if (msg)
protobuf_c_message_free_unpacked (msg, client->allocator);
}
}
}

View File

@ -33,7 +33,10 @@ test__by_name (Foo__DirLookup_Service *service,
char *email = NULL;
(void) service;
if (name->name == NULL)
{
closure (NULL, closure_data);
return;
}
else if (strcmp (name->name, "dave") == 0)
{
number = "555-1212";
@ -130,6 +133,12 @@ test_service (ProtobufCService *service)
foo__dir_lookup__by_name (service, &name, test_not_found_closure, &is_done);
while (!is_done)
protobuf_c_dispatch_run (protobuf_c_dispatch_default ());
name.name = NULL;
is_done = 0;
foo__dir_lookup__by_name (service, &name, test_defunct_closure, &is_done);
while (!is_done)
protobuf_c_dispatch_run (protobuf_c_dispatch_default ());
}
static void
test_defunct_client (ProtobufCService *service)