diff --git a/src/php/ext/grpc/byte_buffer.c b/src/php/ext/grpc/byte_buffer.c index 1ced1bf3f03..9f122d6da67 100644 --- a/src/php/ext/grpc/byte_buffer.c +++ b/src/php/ext/grpc/byte_buffer.c @@ -57,6 +57,11 @@ grpc_byte_buffer *string_to_byte_buffer(char *string, size_t length) { void byte_buffer_to_string(grpc_byte_buffer *buffer, char **out_string, size_t *out_length) { + if (buffer == NULL) { + *out_string = NULL; + *out_length = 0; + return; + } size_t length = grpc_byte_buffer_length(buffer); char *string = ecalloc(length + 1, sizeof(char)); size_t offset = 0; diff --git a/src/php/ext/grpc/call.c b/src/php/ext/grpc/call.c index d0e324e2ccd..ba1b2a407d3 100644 --- a/src/php/ext/grpc/call.c +++ b/src/php/ext/grpc/call.c @@ -448,8 +448,12 @@ PHP_METHOD(Call, start_batch) { break; case GRPC_OP_RECV_MESSAGE: byte_buffer_to_string(message, &message_str, &message_len); - add_property_stringl(result, "message", message_str, message_len, - false); + if (message_str == NULL) { + add_property_null(result, "message"); + } else { + add_property_stringl(result, "message", message_str, message_len, + false); + } break; case GRPC_OP_RECV_STATUS_ON_CLIENT: MAKE_STD_ZVAL(recv_status); @@ -478,9 +482,20 @@ cleanup: RETURN_DESTROY_ZVAL(result); } +/** + * Cancel the call. This will cause the call to end with STATUS_CANCELLED if it + * has not already ended with another status. + */ +PHP_METHOD(Call, cancel) { + wrapped_grpc_call *call = + (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC); + grpc_call_cancel(call->wrapped); +} + static zend_function_entry call_methods[] = { PHP_ME(Call, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) - PHP_ME(Call, start_batch, NULL, ZEND_ACC_PUBLIC) PHP_FE_END}; + PHP_ME(Call, start_batch, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Call, cancel, NULL, ZEND_ACC_PUBLIC) PHP_FE_END}; void grpc_init_call(TSRMLS_D) { zend_class_entry ce; diff --git a/src/php/lib/Grpc/ActiveCall.php b/src/php/lib/Grpc/ActiveCall.php index af4dca50d76..9e048ae03b4 100755 --- a/src/php/lib/Grpc/ActiveCall.php +++ b/src/php/lib/Grpc/ActiveCall.php @@ -77,7 +77,7 @@ class ActiveCall { */ public function read() { $read_event = $this->call->start_batch([OP_RECV_MESSAGE => true]); - return $read_event->data; + return $read_event->message; } /** @@ -102,7 +102,9 @@ class ActiveCall { * and array $metadata members */ public function getStatus() { - $status_event = $this->call->start_batch([RECV_STATUS_ON_CLIENT => true]); - return $status_event->data; + $status_event = $this->call->start_batch([ + OP_RECV_STATUS_ON_CLIENT => true + ]); + return $status_event->status; } } diff --git a/src/php/tests/interop/interop_client.php b/src/php/tests/interop/interop_client.php index 82ca4381690..7ee089e2415 100755 --- a/src/php/tests/interop/interop_client.php +++ b/src/php/tests/interop/interop_client.php @@ -132,8 +132,6 @@ function serverStreaming($stub) { } $call = $stub->StreamingOutputCall($request); - hardAssert($call->getStatus()->code === Grpc\STATUS_OK, - 'Call did not complete successfully'); $i = 0; foreach($call->responses() as $value) { hardAssert($i < 4, 'Too many responses'); @@ -142,7 +140,10 @@ function serverStreaming($stub) { 'Payload ' . $i . ' had the wrong type'); hardAssert(strlen($payload->getBody()) === $sizes[$i], 'Response ' . $i . ' had the wrong length'); + $i += 1; } + hardAssert($call->getStatus()->code === Grpc\STATUS_OK, + 'Call did not complete successfully'); } /** @@ -240,4 +241,6 @@ switch($args['test_case']) { break; case 'cancel_after_first_response': cancelAfterFirstResponse($stub); + default: + exit(1); }