Craig Tiller | 1a61b17 | 2015-02-16 11:53:47 -0800 | [diff] [blame] | 1 | /* |
| 2 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 3 | * Copyright 2015 gRPC authors. |
Craig Tiller | 1a61b17 | 2015-02-16 11:53:47 -0800 | [diff] [blame] | 4 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 5 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | * you may not use this file except in compliance with the License. |
| 7 | * You may obtain a copy of the License at |
Craig Tiller | 1a61b17 | 2015-02-16 11:53:47 -0800 | [diff] [blame] | 8 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 9 | * http://www.apache.org/licenses/LICENSE-2.0 |
Craig Tiller | 1a61b17 | 2015-02-16 11:53:47 -0800 | [diff] [blame] | 10 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 11 | * Unless required by applicable law or agreed to in writing, software |
| 12 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | * See the License for the specific language governing permissions and |
| 15 | * limitations under the License. |
Craig Tiller | 1a61b17 | 2015-02-16 11:53:47 -0800 | [diff] [blame] | 16 | * |
| 17 | */ |
| 18 | |
mlumish | b892a27 | 2014-12-09 16:28:23 -0800 | [diff] [blame] | 19 | #include "call.h" |
| 20 | |
murgatroid99 | 8242ba7 | 2015-04-01 15:29:44 -0700 | [diff] [blame] | 21 | #include <ext/spl/spl_exceptions.h> |
murgatroid99 | 8242ba7 | 2015-04-01 15:29:44 -0700 | [diff] [blame] | 22 | #include <zend_exceptions.h> |
mlumish | b892a27 | 2014-12-09 16:28:23 -0800 | [diff] [blame] | 23 | |
murgatroid99 | 8242ba7 | 2015-04-01 15:29:44 -0700 | [diff] [blame] | 24 | #include <grpc/support/alloc.h> |
mlumish | b892a27 | 2014-12-09 16:28:23 -0800 | [diff] [blame] | 25 | |
thinkerou | 771c205 | 2018-05-15 10:37:43 +0800 | [diff] [blame] | 26 | #include "call_credentials.h" |
murgatroid99 | 268acd5 | 2015-05-14 15:05:00 -0700 | [diff] [blame] | 27 | #include "completion_queue.h" |
mlumish | b892a27 | 2014-12-09 16:28:23 -0800 | [diff] [blame] | 28 | #include "timeval.h" |
| 29 | #include "channel.h" |
mlumish | b892a27 | 2014-12-09 16:28:23 -0800 | [diff] [blame] | 30 | #include "byte_buffer.h" |
| 31 | |
Xiaoguang Sun | 8a929a9 | 2015-03-13 14:22:31 +0800 | [diff] [blame] | 32 | zend_class_entry *grpc_ce_call; |
thinkerou | fe037cb | 2018-05-16 12:51:28 +0800 | [diff] [blame^] | 33 | PHP_GRPC_DECLARE_OBJECT_HANDLER(call_ce_handlers) |
Xiaoguang Sun | 8a929a9 | 2015-03-13 14:22:31 +0800 | [diff] [blame] | 34 | |
mlumish | b892a27 | 2014-12-09 16:28:23 -0800 | [diff] [blame] | 35 | /* Frees and destroys an instance of wrapped_grpc_call */ |
thinkerou | 011d1ef | 2016-07-27 09:44:49 +0800 | [diff] [blame] | 36 | PHP_GRPC_FREE_WRAPPED_FUNC_START(wrapped_grpc_call) |
| 37 | if (p->owned && p->wrapped != NULL) { |
Craig Tiller | dd36b15 | 2017-03-31 08:27:28 -0700 | [diff] [blame] | 38 | grpc_call_unref(p->wrapped); |
mlumish | b892a27 | 2014-12-09 16:28:23 -0800 | [diff] [blame] | 39 | } |
thinkerou | 011d1ef | 2016-07-27 09:44:49 +0800 | [diff] [blame] | 40 | PHP_GRPC_FREE_WRAPPED_FUNC_END() |
| 41 | |
thinkerou | 03dc219 | 2016-08-16 19:31:44 +0800 | [diff] [blame] | 42 | /* Initializes an instance of wrapped_grpc_call to be associated with an |
| 43 | * object of a class specified by class_type */ |
thinkerou | dba5b0c | 2016-07-27 18:39:16 +0800 | [diff] [blame] | 44 | php_grpc_zend_object create_wrapped_grpc_call(zend_class_entry *class_type |
| 45 | TSRMLS_DC) { |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 46 | PHP_GRPC_ALLOC_CLASS_OBJECT(wrapped_grpc_call); |
mlumish | b892a27 | 2014-12-09 16:28:23 -0800 | [diff] [blame] | 47 | zend_object_std_init(&intern->std, class_type TSRMLS_CC); |
| 48 | object_properties_init(&intern->std, class_type); |
thinkerou | dc673c5 | 2016-07-28 09:49:38 +0800 | [diff] [blame] | 49 | PHP_GRPC_FREE_CLASS_OBJECT(wrapped_grpc_call, call_ce_handlers); |
thinkerou | dba5b0c | 2016-07-27 18:39:16 +0800 | [diff] [blame] | 50 | } |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 51 | |
| 52 | /* Creates and returns a PHP array object with the data in a |
| 53 | * grpc_metadata_array. Returns NULL on failure */ |
thinkerou | 6f9d30b | 2016-07-27 03:19:03 +0800 | [diff] [blame] | 54 | zval *grpc_parse_metadata_array(grpc_metadata_array |
| 55 | *metadata_array TSRMLS_DC) { |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 56 | int count = metadata_array->count; |
| 57 | grpc_metadata *elements = metadata_array->metadata; |
thinkerou | 6f9d30b | 2016-07-27 03:19:03 +0800 | [diff] [blame] | 58 | zval *array; |
| 59 | PHP_GRPC_MAKE_STD_ZVAL(array); |
| 60 | array_init(array); |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 61 | int i; |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 62 | HashTable *array_hash; |
thinkerou | 6f9d30b | 2016-07-27 03:19:03 +0800 | [diff] [blame] | 63 | zval *inner_array; |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 64 | char *str_key; |
| 65 | char *str_val; |
| 66 | size_t key_len; |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 67 | zval *data = NULL; |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 68 | |
thinkerou | 6f9d30b | 2016-07-27 03:19:03 +0800 | [diff] [blame] | 69 | array_hash = Z_ARRVAL_P(array); |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 70 | grpc_metadata *elem; |
| 71 | for (i = 0; i < count; i++) { |
| 72 | elem = &elements[i]; |
Craig Tiller | 7c70b6c | 2017-01-23 07:48:42 -0800 | [diff] [blame] | 73 | key_len = GRPC_SLICE_LENGTH(elem->key); |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 74 | str_key = ecalloc(key_len + 1, sizeof(char)); |
Craig Tiller | 7c70b6c | 2017-01-23 07:48:42 -0800 | [diff] [blame] | 75 | memcpy(str_key, GRPC_SLICE_START_PTR(elem->key), key_len); |
| 76 | str_val = ecalloc(GRPC_SLICE_LENGTH(elem->value) + 1, sizeof(char)); |
Stanley Cheung | 6a5c83d | 2017-02-16 12:25:32 -0800 | [diff] [blame] | 77 | memcpy(str_val, GRPC_SLICE_START_PTR(elem->value), |
| 78 | GRPC_SLICE_LENGTH(elem->value)); |
thinkerou | 5dafd82 | 2016-07-28 22:43:38 +0800 | [diff] [blame] | 79 | if (php_grpc_zend_hash_find(array_hash, str_key, key_len, (void **)&data) |
| 80 | == SUCCESS) { |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 81 | if (Z_TYPE_P(data) != IS_ARRAY) { |
thinkerou | 6f9d30b | 2016-07-27 03:19:03 +0800 | [diff] [blame] | 82 | zend_throw_exception(zend_exception_get_default(TSRMLS_C), |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 83 | "Metadata hash somehow contains wrong types.", |
thinkerou | 6f9d30b | 2016-07-27 03:19:03 +0800 | [diff] [blame] | 84 | 1 TSRMLS_CC); |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 85 | efree(str_key); |
| 86 | efree(str_val); |
Zhouyihai Ding | b0821f0 | 2018-01-23 20:38:02 -0800 | [diff] [blame] | 87 | PHP_GRPC_FREE_STD_ZVAL(array); |
thinkerou | 6f9d30b | 2016-07-27 03:19:03 +0800 | [diff] [blame] | 88 | return NULL; |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 89 | } |
Stanley Cheung | 6a5c83d | 2017-02-16 12:25:32 -0800 | [diff] [blame] | 90 | php_grpc_add_next_index_stringl(data, str_val, |
| 91 | GRPC_SLICE_LENGTH(elem->value), |
thinkerou | 6f9d30b | 2016-07-27 03:19:03 +0800 | [diff] [blame] | 92 | false); |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 93 | } else { |
thinkerou | 6f9d30b | 2016-07-27 03:19:03 +0800 | [diff] [blame] | 94 | PHP_GRPC_MAKE_STD_ZVAL(inner_array); |
| 95 | array_init(inner_array); |
| 96 | php_grpc_add_next_index_stringl(inner_array, str_val, |
Craig Tiller | 7c70b6c | 2017-01-23 07:48:42 -0800 | [diff] [blame] | 97 | GRPC_SLICE_LENGTH(elem->value), false); |
thinkerou | 6f9d30b | 2016-07-27 03:19:03 +0800 | [diff] [blame] | 98 | add_assoc_zval(array, str_key, inner_array); |
Stanley Cheung | e9595ba | 2017-05-09 15:43:58 -0700 | [diff] [blame] | 99 | PHP_GRPC_FREE_STD_ZVAL(inner_array); |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 100 | } |
Stanley Cheung | e9595ba | 2017-05-09 15:43:58 -0700 | [diff] [blame] | 101 | efree(str_key); |
| 102 | #if PHP_MAJOR_VERSION >= 7 |
| 103 | efree(str_val); |
| 104 | #endif |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 105 | } |
thinkerou | 6f9d30b | 2016-07-27 03:19:03 +0800 | [diff] [blame] | 106 | return array; |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 107 | } |
| 108 | |
| 109 | /* Populates a grpc_metadata_array with the data in a PHP array object. |
| 110 | Returns true on success and false on failure */ |
| 111 | bool create_metadata_array(zval *array, grpc_metadata_array *metadata) { |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 112 | HashTable *array_hash; |
| 113 | HashTable *inner_array_hash; |
thinkerou | 6f9d30b | 2016-07-27 03:19:03 +0800 | [diff] [blame] | 114 | zval *value; |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 115 | zval *inner_array; |
Zhouyihai Ding | ec0669c | 2018-01-23 20:43:53 -0800 | [diff] [blame] | 116 | grpc_metadata_array_init(metadata); |
| 117 | metadata->count = 0; |
| 118 | metadata->metadata = NULL; |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 119 | if (Z_TYPE_P(array) != IS_ARRAY) { |
| 120 | return false; |
| 121 | } |
thinkerou | 6f9d30b | 2016-07-27 03:19:03 +0800 | [diff] [blame] | 122 | array_hash = Z_ARRVAL_P(array); |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 123 | |
thinkerou | 11cb5c5 | 2016-07-28 07:29:17 +0800 | [diff] [blame] | 124 | char *key; |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 125 | int key_type; |
| 126 | PHP_GRPC_HASH_FOREACH_STR_KEY_VAL_START(array_hash, key, key_type, |
| 127 | inner_array) |
thinkerou | 11cb5c5 | 2016-07-28 07:29:17 +0800 | [diff] [blame] | 128 | if (key_type != HASH_KEY_IS_STRING || key == NULL) { |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 129 | return false; |
| 130 | } |
| 131 | if (Z_TYPE_P(inner_array) != IS_ARRAY) { |
| 132 | return false; |
| 133 | } |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 134 | inner_array_hash = Z_ARRVAL_P(inner_array); |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 135 | metadata->capacity += zend_hash_num_elements(inner_array_hash); |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 136 | PHP_GRPC_HASH_FOREACH_END() |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 137 | |
| 138 | metadata->metadata = gpr_malloc(metadata->capacity * sizeof(grpc_metadata)); |
| 139 | |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 140 | char *key1 = NULL; |
| 141 | int key_type1; |
| 142 | PHP_GRPC_HASH_FOREACH_STR_KEY_VAL_START(array_hash, key1, key_type1, |
| 143 | inner_array) |
| 144 | if (key_type1 != HASH_KEY_IS_STRING) { |
thinkerou | 6f9d30b | 2016-07-27 03:19:03 +0800 | [diff] [blame] | 145 | return false; |
| 146 | } |
Craig Tiller | 7c70b6c | 2017-01-23 07:48:42 -0800 | [diff] [blame] | 147 | if (!grpc_header_key_is_legal(grpc_slice_from_static_string(key1))) { |
Stanley Cheung | 129bca6 | 2016-08-26 19:54:57 -0700 | [diff] [blame] | 148 | return false; |
| 149 | } |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 150 | inner_array_hash = Z_ARRVAL_P(inner_array); |
| 151 | PHP_GRPC_HASH_FOREACH_VAL_START(inner_array_hash, value) |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 152 | if (Z_TYPE_P(value) != IS_STRING) { |
| 153 | return false; |
| 154 | } |
Stanley Cheung | 6a5c83d | 2017-02-16 12:25:32 -0800 | [diff] [blame] | 155 | metadata->metadata[metadata->count].key = |
| 156 | grpc_slice_from_copied_string(key1); |
| 157 | metadata->metadata[metadata->count].value = |
| 158 | grpc_slice_from_copied_buffer(Z_STRVAL_P(value), Z_STRLEN_P(value)); |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 159 | metadata->count += 1; |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 160 | PHP_GRPC_HASH_FOREACH_END() |
| 161 | PHP_GRPC_HASH_FOREACH_END() |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 162 | return true; |
| 163 | } |
| 164 | |
ZhouyihaiDing | 0464879 | 2017-12-06 18:31:40 +0000 | [diff] [blame] | 165 | void grpc_php_metadata_array_destroy_including_entries( |
| 166 | grpc_metadata_array* array) { |
| 167 | size_t i; |
| 168 | if (array->metadata) { |
| 169 | for (i = 0; i < array->count; i++) { |
| 170 | grpc_slice_unref(array->metadata[i].key); |
| 171 | grpc_slice_unref(array->metadata[i].value); |
| 172 | } |
| 173 | } |
| 174 | grpc_metadata_array_destroy(array); |
| 175 | } |
| 176 | |
thinkerou | 6f9d30b | 2016-07-27 03:19:03 +0800 | [diff] [blame] | 177 | /* Wraps a grpc_call struct in a PHP object. Owned indicates whether the |
| 178 | struct should be destroyed at the end of the object's lifecycle */ |
| 179 | zval *grpc_php_wrap_call(grpc_call *wrapped, bool owned TSRMLS_DC) { |
| 180 | zval *call_object; |
| 181 | PHP_GRPC_MAKE_STD_ZVAL(call_object); |
| 182 | object_init_ex(call_object, grpc_ce_call); |
thinkerou | fe037cb | 2018-05-16 12:51:28 +0800 | [diff] [blame^] | 183 | wrapped_grpc_call *call = PHP_GRPC_GET_WRAPPED_OBJECT(wrapped_grpc_call, |
| 184 | call_object); |
thinkerou | 6f9d30b | 2016-07-27 03:19:03 +0800 | [diff] [blame] | 185 | call->wrapped = wrapped; |
| 186 | call->owned = owned; |
| 187 | return call_object; |
| 188 | } |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 189 | |
mlumish | b892a27 | 2014-12-09 16:28:23 -0800 | [diff] [blame] | 190 | /** |
| 191 | * Constructs a new instance of the Call class. |
thinkerou | 03dc219 | 2016-08-16 19:31:44 +0800 | [diff] [blame] | 192 | * @param Channel $channel_obj The channel to associate the call with. |
| 193 | * Must not be closed. |
mlumish | b892a27 | 2014-12-09 16:28:23 -0800 | [diff] [blame] | 194 | * @param string $method The method to call |
thinkerou | 03dc219 | 2016-08-16 19:31:44 +0800 | [diff] [blame] | 195 | * @param Timeval $deadline_obj The deadline for completing the call |
thinkerou | efbc9e7 | 2016-08-16 20:00:36 +0800 | [diff] [blame] | 196 | * @param string $host_override The host is set by user (optional) |
mlumish | b892a27 | 2014-12-09 16:28:23 -0800 | [diff] [blame] | 197 | */ |
Craig Tiller | b5dcec5 | 2015-01-13 11:13:42 -0800 | [diff] [blame] | 198 | PHP_METHOD(Call, __construct) { |
mlumish | b892a27 | 2014-12-09 16:28:23 -0800 | [diff] [blame] | 199 | zval *channel_obj; |
| 200 | char *method; |
thinkerou | 1930468 | 2016-07-22 02:43:19 +0800 | [diff] [blame] | 201 | php_grpc_int method_len; |
mlumish | b892a27 | 2014-12-09 16:28:23 -0800 | [diff] [blame] | 202 | zval *deadline_obj; |
Stanley Cheung | 478fb00 | 2015-08-19 14:25:00 -0700 | [diff] [blame] | 203 | char *host_override = NULL; |
thinkerou | 1930468 | 2016-07-22 02:43:19 +0800 | [diff] [blame] | 204 | php_grpc_int host_override_len = 0; |
thinkerou | fe037cb | 2018-05-16 12:51:28 +0800 | [diff] [blame^] | 205 | wrapped_grpc_call *call = PHP_GRPC_GET_WRAPPED_OBJECT(wrapped_grpc_call, |
| 206 | getThis()); |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 207 | |
Stanley Cheung | 478fb00 | 2015-08-19 14:25:00 -0700 | [diff] [blame] | 208 | /* "OsO|s" == 1 Object, 1 string, 1 Object, 1 optional string */ |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 209 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OsO|s", &channel_obj, |
| 210 | grpc_ce_channel, &method, &method_len, |
| 211 | &deadline_obj, grpc_ce_timeval, &host_override, |
| 212 | &host_override_len) == FAILURE) { |
| 213 | zend_throw_exception(spl_ce_InvalidArgumentException, |
| 214 | "Call expects a Channel, a String, a Timeval and " |
| 215 | "an optional String", 1 TSRMLS_CC); |
mlumish | b892a27 | 2014-12-09 16:28:23 -0800 | [diff] [blame] | 216 | return; |
| 217 | } |
thinkerou | fe037cb | 2018-05-16 12:51:28 +0800 | [diff] [blame^] | 218 | wrapped_grpc_channel *channel = |
| 219 | PHP_GRPC_GET_WRAPPED_OBJECT(wrapped_grpc_channel, channel_obj); |
Stanley Cheung | 5b3dc4a | 2017-08-03 18:00:25 -0700 | [diff] [blame] | 220 | gpr_mu_lock(&channel->wrapper->mu); |
ZhouyihaiDing | 9ef881e | 2018-04-12 16:43:33 -0700 | [diff] [blame] | 221 | if (channel->wrapper == NULL || channel->wrapper->wrapped == NULL) { |
mlumish | b892a27 | 2014-12-09 16:28:23 -0800 | [diff] [blame] | 222 | zend_throw_exception(spl_ce_InvalidArgumentException, |
| 223 | "Call cannot be constructed from a closed Channel", |
| 224 | 1 TSRMLS_CC); |
Stanley Cheung | 5b3dc4a | 2017-08-03 18:00:25 -0700 | [diff] [blame] | 225 | gpr_mu_unlock(&channel->wrapper->mu); |
mlumish | b892a27 | 2014-12-09 16:28:23 -0800 | [diff] [blame] | 226 | return; |
| 227 | } |
| 228 | add_property_zval(getThis(), "channel", channel_obj); |
thinkerou | fe037cb | 2018-05-16 12:51:28 +0800 | [diff] [blame^] | 229 | wrapped_grpc_timeval *deadline = |
| 230 | PHP_GRPC_GET_WRAPPED_OBJECT(wrapped_grpc_timeval, deadline_obj); |
Craig Tiller | 7c70b6c | 2017-01-23 07:48:42 -0800 | [diff] [blame] | 231 | grpc_slice method_slice = grpc_slice_from_copied_string(method); |
| 232 | grpc_slice host_slice = host_override != NULL ? |
| 233 | grpc_slice_from_copied_string(host_override) : grpc_empty_slice(); |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 234 | call->wrapped = |
Stanley Cheung | 5b3dc4a | 2017-08-03 18:00:25 -0700 | [diff] [blame] | 235 | grpc_channel_create_call(channel->wrapper->wrapped, NULL, |
| 236 | GRPC_PROPAGATE_DEFAULTS, |
Stanley Cheung | 6a5c83d | 2017-02-16 12:25:32 -0800 | [diff] [blame] | 237 | completion_queue, method_slice, |
| 238 | host_override != NULL ? &host_slice : NULL, |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 239 | deadline->wrapped, NULL); |
Craig Tiller | 7c70b6c | 2017-01-23 07:48:42 -0800 | [diff] [blame] | 240 | grpc_slice_unref(method_slice); |
| 241 | grpc_slice_unref(host_slice); |
Stanley Cheung | 51b3691 | 2016-06-29 15:05:59 -0700 | [diff] [blame] | 242 | call->owned = true; |
ZhouyihaiDing | 9ef881e | 2018-04-12 16:43:33 -0700 | [diff] [blame] | 243 | call->channel = channel; |
Stanley Cheung | 5b3dc4a | 2017-08-03 18:00:25 -0700 | [diff] [blame] | 244 | gpr_mu_unlock(&channel->wrapper->mu); |
mlumish | b892a27 | 2014-12-09 16:28:23 -0800 | [diff] [blame] | 245 | } |
| 246 | |
| 247 | /** |
murgatroid99 | afd541c | 2015-03-03 18:16:09 -0800 | [diff] [blame] | 248 | * Start a batch of RPC actions. |
thinkerou | efbc9e7 | 2016-08-16 20:00:36 +0800 | [diff] [blame] | 249 | * @param array $array Array of actions to take |
murgatroid99 | afd541c | 2015-03-03 18:16:09 -0800 | [diff] [blame] | 250 | * @return object Object with results of all actions |
mlumish | b892a27 | 2014-12-09 16:28:23 -0800 | [diff] [blame] | 251 | */ |
murgatroid99 | c1d7e24 | 2015-04-02 10:02:43 -0700 | [diff] [blame] | 252 | PHP_METHOD(Call, startBatch) { |
thinkerou | 6f9d30b | 2016-07-27 03:19:03 +0800 | [diff] [blame] | 253 | zval *result; |
| 254 | PHP_GRPC_MAKE_STD_ZVAL(result); |
| 255 | object_init(result); |
| 256 | php_grpc_ulong index; |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 257 | zval *recv_status; |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 258 | zval *value; |
| 259 | zval *inner_value; |
| 260 | zval *message_value; |
| 261 | zval *message_flags; |
thinkerou | fe037cb | 2018-05-16 12:51:28 +0800 | [diff] [blame^] | 262 | wrapped_grpc_call *call = PHP_GRPC_GET_WRAPPED_OBJECT(wrapped_grpc_call, |
| 263 | getThis()); |
ZhouyihaiDing | 9ef881e | 2018-04-12 16:43:33 -0700 | [diff] [blame] | 264 | if (call->channel) { |
| 265 | // startBatch in gRPC PHP server doesn't have channel in it. |
| 266 | if (call->channel->wrapper == NULL || |
| 267 | call->channel->wrapper->wrapped == NULL) { |
| 268 | zend_throw_exception(spl_ce_RuntimeException, |
| 269 | "startBatch Error. Channel is closed", |
| 270 | 1 TSRMLS_CC); |
| 271 | } |
| 272 | } |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 273 | |
| 274 | grpc_op ops[8]; |
| 275 | size_t op_num = 0; |
| 276 | zval *array; |
| 277 | HashTable *array_hash; |
| 278 | HashTable *status_hash; |
| 279 | HashTable *message_hash; |
| 280 | |
murgatroid99 | afd541c | 2015-03-03 18:16:09 -0800 | [diff] [blame] | 281 | grpc_metadata_array metadata; |
| 282 | grpc_metadata_array trailing_metadata; |
| 283 | grpc_metadata_array recv_metadata; |
| 284 | grpc_metadata_array recv_trailing_metadata; |
| 285 | grpc_status_code status; |
Craig Tiller | 7c70b6c | 2017-01-23 07:48:42 -0800 | [diff] [blame] | 286 | grpc_slice recv_status_details = grpc_empty_slice(); |
| 287 | grpc_slice send_status_details = grpc_empty_slice(); |
murgatroid99 | afd541c | 2015-03-03 18:16:09 -0800 | [diff] [blame] | 288 | grpc_byte_buffer *message; |
| 289 | int cancelled; |
| 290 | grpc_call_error error; |
murgatroid99 | afd541c | 2015-03-03 18:16:09 -0800 | [diff] [blame] | 291 | char *message_str; |
| 292 | size_t message_len; |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 293 | |
murgatroid99 | afd541c | 2015-03-03 18:16:09 -0800 | [diff] [blame] | 294 | grpc_metadata_array_init(&metadata); |
| 295 | grpc_metadata_array_init(&trailing_metadata); |
murgatroid99 | d8bb957 | 2015-03-11 09:18:06 -0700 | [diff] [blame] | 296 | grpc_metadata_array_init(&recv_metadata); |
| 297 | grpc_metadata_array_init(&recv_trailing_metadata); |
David Garcia Quintas | a301eaa | 2016-05-06 16:59:03 -0700 | [diff] [blame] | 298 | memset(ops, 0, sizeof(ops)); |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 299 | |
murgatroid99 | afd541c | 2015-03-03 18:16:09 -0800 | [diff] [blame] | 300 | /* "a" == 1 array */ |
| 301 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == |
Craig Tiller | b5dcec5 | 2015-01-13 11:13:42 -0800 | [diff] [blame] | 302 | FAILURE) { |
mlumish | b892a27 | 2014-12-09 16:28:23 -0800 | [diff] [blame] | 303 | zend_throw_exception(spl_ce_InvalidArgumentException, |
thinkerou | 11cb5c5 | 2016-07-28 07:29:17 +0800 | [diff] [blame] | 304 | "start_batch expects an array", 1 TSRMLS_CC); |
| 305 | goto cleanup; |
mlumish | b892a27 | 2014-12-09 16:28:23 -0800 | [diff] [blame] | 306 | } |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 307 | |
mlumish | b892a27 | 2014-12-09 16:28:23 -0800 | [diff] [blame] | 308 | array_hash = Z_ARRVAL_P(array); |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 309 | |
| 310 | char *key = NULL; |
| 311 | int key_type; |
| 312 | PHP_GRPC_HASH_FOREACH_LONG_KEY_VAL_START(array_hash, key, key_type, index, |
thinkerou | 5dafd82 | 2016-07-28 22:43:38 +0800 | [diff] [blame] | 313 | value) |
thinkerou | 11cb5c5 | 2016-07-28 07:29:17 +0800 | [diff] [blame] | 314 | if (key_type != HASH_KEY_IS_LONG || key != NULL) { |
murgatroid99 | 5ca9f92 | 2015-02-03 11:21:11 -0800 | [diff] [blame] | 315 | zend_throw_exception(spl_ce_InvalidArgumentException, |
murgatroid99 | afd541c | 2015-03-03 18:16:09 -0800 | [diff] [blame] | 316 | "batch keys must be integers", 1 TSRMLS_CC); |
| 317 | goto cleanup; |
murgatroid99 | 5ca9f92 | 2015-02-03 11:21:11 -0800 | [diff] [blame] | 318 | } |
thinkerou | b408469 | 2017-09-25 10:09:34 +0800 | [diff] [blame] | 319 | |
| 320 | ops[op_num].op = (grpc_op_type)index; |
| 321 | ops[op_num].flags = 0; |
| 322 | ops[op_num].reserved = NULL; |
| 323 | |
murgatroid99 | afd541c | 2015-03-03 18:16:09 -0800 | [diff] [blame] | 324 | switch(index) { |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 325 | case GRPC_OP_SEND_INITIAL_METADATA: |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 326 | if (!create_metadata_array(value, &metadata)) { |
murgatroid99 | 5ca9f92 | 2015-02-03 11:21:11 -0800 | [diff] [blame] | 327 | zend_throw_exception(spl_ce_InvalidArgumentException, |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 328 | "Bad metadata value given", 1 TSRMLS_CC); |
murgatroid99 | afd541c | 2015-03-03 18:16:09 -0800 | [diff] [blame] | 329 | goto cleanup; |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 330 | } |
thinkerou | 5dafd82 | 2016-07-28 22:43:38 +0800 | [diff] [blame] | 331 | ops[op_num].data.send_initial_metadata.count = metadata.count; |
| 332 | ops[op_num].data.send_initial_metadata.metadata = metadata.metadata; |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 333 | break; |
| 334 | case GRPC_OP_SEND_MESSAGE: |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 335 | if (Z_TYPE_P(value) != IS_ARRAY) { |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 336 | zend_throw_exception(spl_ce_InvalidArgumentException, |
| 337 | "Expected an array for send message", |
| 338 | 1 TSRMLS_CC); |
| 339 | goto cleanup; |
| 340 | } |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 341 | message_hash = Z_ARRVAL_P(value); |
| 342 | if (php_grpc_zend_hash_find(message_hash, "flags", sizeof("flags"), |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 343 | (void **)&message_flags) == SUCCESS) { |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 344 | if (Z_TYPE_P(message_flags) != IS_LONG) { |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 345 | zend_throw_exception(spl_ce_InvalidArgumentException, |
| 346 | "Expected an int for message flags", |
| 347 | 1 TSRMLS_CC); |
| 348 | } |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 349 | ops[op_num].flags = Z_LVAL_P(message_flags) & GRPC_WRITE_USED_MASK; |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 350 | } |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 351 | if (php_grpc_zend_hash_find(message_hash, "message", sizeof("message"), |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 352 | (void **)&message_value) != SUCCESS || |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 353 | Z_TYPE_P(message_value) != IS_STRING) { |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 354 | zend_throw_exception(spl_ce_InvalidArgumentException, |
| 355 | "Expected a string for send message", |
| 356 | 1 TSRMLS_CC); |
| 357 | goto cleanup; |
| 358 | } |
Mark D. Roth | 448c1f0 | 2017-01-25 10:44:30 -0800 | [diff] [blame] | 359 | ops[op_num].data.send_message.send_message = |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 360 | string_to_byte_buffer(Z_STRVAL_P(message_value), |
| 361 | Z_STRLEN_P(message_value)); |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 362 | break; |
| 363 | case GRPC_OP_SEND_CLOSE_FROM_CLIENT: |
| 364 | break; |
| 365 | case GRPC_OP_SEND_STATUS_FROM_SERVER: |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 366 | status_hash = Z_ARRVAL_P(value); |
| 367 | if (php_grpc_zend_hash_find(status_hash, "metadata", sizeof("metadata"), |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 368 | (void **)&inner_value) == SUCCESS) { |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 369 | if (!create_metadata_array(inner_value, &trailing_metadata)) { |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 370 | zend_throw_exception(spl_ce_InvalidArgumentException, |
| 371 | "Bad trailing metadata value given", |
| 372 | 1 TSRMLS_CC); |
| 373 | goto cleanup; |
| 374 | } |
| 375 | ops[op_num].data.send_status_from_server.trailing_metadata = |
| 376 | trailing_metadata.metadata; |
| 377 | ops[op_num].data.send_status_from_server.trailing_metadata_count = |
| 378 | trailing_metadata.count; |
| 379 | } |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 380 | if (php_grpc_zend_hash_find(status_hash, "code", sizeof("code"), |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 381 | (void**)&inner_value) == SUCCESS) { |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 382 | if (Z_TYPE_P(inner_value) != IS_LONG) { |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 383 | zend_throw_exception(spl_ce_InvalidArgumentException, |
| 384 | "Status code must be an integer", |
| 385 | 1 TSRMLS_CC); |
| 386 | goto cleanup; |
| 387 | } |
| 388 | ops[op_num].data.send_status_from_server.status = |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 389 | Z_LVAL_P(inner_value); |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 390 | } else { |
| 391 | zend_throw_exception(spl_ce_InvalidArgumentException, |
| 392 | "Integer status code is required", |
| 393 | 1 TSRMLS_CC); |
| 394 | goto cleanup; |
| 395 | } |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 396 | if (php_grpc_zend_hash_find(status_hash, "details", sizeof("details"), |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 397 | (void**)&inner_value) == SUCCESS) { |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 398 | if (Z_TYPE_P(inner_value) != IS_STRING) { |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 399 | zend_throw_exception(spl_ce_InvalidArgumentException, |
| 400 | "Status details must be a string", |
| 401 | 1 TSRMLS_CC); |
| 402 | goto cleanup; |
| 403 | } |
Stanley Cheung | 6a5c83d | 2017-02-16 12:25:32 -0800 | [diff] [blame] | 404 | send_status_details = grpc_slice_from_copied_string( |
| 405 | Z_STRVAL_P(inner_value)); |
| 406 | ops[op_num].data.send_status_from_server.status_details = |
| 407 | &send_status_details; |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 408 | } else { |
| 409 | zend_throw_exception(spl_ce_InvalidArgumentException, |
| 410 | "String status details is required", |
| 411 | 1 TSRMLS_CC); |
| 412 | goto cleanup; |
| 413 | } |
| 414 | break; |
| 415 | case GRPC_OP_RECV_INITIAL_METADATA: |
Mark D. Roth | 448c1f0 | 2017-01-25 10:44:30 -0800 | [diff] [blame] | 416 | ops[op_num].data.recv_initial_metadata.recv_initial_metadata = |
| 417 | &recv_metadata; |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 418 | break; |
| 419 | case GRPC_OP_RECV_MESSAGE: |
Mark D. Roth | 448c1f0 | 2017-01-25 10:44:30 -0800 | [diff] [blame] | 420 | ops[op_num].data.recv_message.recv_message = &message; |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 421 | break; |
| 422 | case GRPC_OP_RECV_STATUS_ON_CLIENT: |
| 423 | ops[op_num].data.recv_status_on_client.trailing_metadata = |
| 424 | &recv_trailing_metadata; |
| 425 | ops[op_num].data.recv_status_on_client.status = &status; |
| 426 | ops[op_num].data.recv_status_on_client.status_details = |
Craig Tiller | 7c70b6c | 2017-01-23 07:48:42 -0800 | [diff] [blame] | 427 | &recv_status_details; |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 428 | break; |
| 429 | case GRPC_OP_RECV_CLOSE_ON_SERVER: |
| 430 | ops[op_num].data.recv_close_on_server.cancelled = &cancelled; |
| 431 | break; |
| 432 | default: |
| 433 | zend_throw_exception(spl_ce_InvalidArgumentException, |
| 434 | "Unrecognized key in batch", 1 TSRMLS_CC); |
| 435 | goto cleanup; |
murgatroid99 | afd541c | 2015-03-03 18:16:09 -0800 | [diff] [blame] | 436 | } |
murgatroid99 | afd541c | 2015-03-03 18:16:09 -0800 | [diff] [blame] | 437 | op_num++; |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 438 | PHP_GRPC_HASH_FOREACH_END() |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 439 | |
Nicolas "Pixel" Noble | 150b7c4 | 2015-08-01 01:15:10 +0200 | [diff] [blame] | 440 | error = grpc_call_start_batch(call->wrapped, ops, op_num, call->wrapped, |
| 441 | NULL); |
murgatroid99 | afd541c | 2015-03-03 18:16:09 -0800 | [diff] [blame] | 442 | if (error != GRPC_CALL_OK) { |
| 443 | zend_throw_exception(spl_ce_LogicException, |
| 444 | "start_batch was called incorrectly", |
| 445 | (long)error TSRMLS_CC); |
| 446 | goto cleanup; |
| 447 | } |
Stanley Cheung | c0c9ba9 | 2015-08-18 16:19:38 -0700 | [diff] [blame] | 448 | grpc_completion_queue_pluck(completion_queue, call->wrapped, |
| 449 | gpr_inf_future(GPR_CLOCK_REALTIME), NULL); |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 450 | #if PHP_MAJOR_VERSION >= 7 |
Stanley Cheung | e9595ba | 2017-05-09 15:43:58 -0700 | [diff] [blame] | 451 | zval *recv_md; |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 452 | #endif |
murgatroid99 | afd541c | 2015-03-03 18:16:09 -0800 | [diff] [blame] | 453 | for (int i = 0; i < op_num; i++) { |
| 454 | switch(ops[i].op) { |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 455 | case GRPC_OP_SEND_INITIAL_METADATA: |
| 456 | add_property_bool(result, "send_metadata", true); |
| 457 | break; |
| 458 | case GRPC_OP_SEND_MESSAGE: |
| 459 | add_property_bool(result, "send_message", true); |
| 460 | break; |
| 461 | case GRPC_OP_SEND_CLOSE_FROM_CLIENT: |
| 462 | add_property_bool(result, "send_close", true); |
| 463 | break; |
| 464 | case GRPC_OP_SEND_STATUS_FROM_SERVER: |
| 465 | add_property_bool(result, "send_status", true); |
| 466 | break; |
| 467 | case GRPC_OP_RECV_INITIAL_METADATA: |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 468 | #if PHP_MAJOR_VERSION < 7 |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 469 | array = grpc_parse_metadata_array(&recv_metadata TSRMLS_CC); |
| 470 | add_property_zval(result, "metadata", array); |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 471 | #else |
Stanley Cheung | e9595ba | 2017-05-09 15:43:58 -0700 | [diff] [blame] | 472 | recv_md = grpc_parse_metadata_array(&recv_metadata); |
| 473 | add_property_zval(result, "metadata", recv_md); |
| 474 | zval_ptr_dtor(recv_md); |
| 475 | PHP_GRPC_FREE_STD_ZVAL(recv_md); |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 476 | #endif |
| 477 | PHP_GRPC_DELREF(array); |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 478 | break; |
| 479 | case GRPC_OP_RECV_MESSAGE: |
| 480 | byte_buffer_to_string(message, &message_str, &message_len); |
| 481 | if (message_str == NULL) { |
thinkerou | 6f9d30b | 2016-07-27 03:19:03 +0800 | [diff] [blame] | 482 | add_property_null(result, "message"); |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 483 | } else { |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 484 | php_grpc_add_property_stringl(result, "message", message_str, |
| 485 | message_len, false); |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 486 | } |
| 487 | break; |
| 488 | case GRPC_OP_RECV_STATUS_ON_CLIENT: |
Stanley Cheung | e9595ba | 2017-05-09 15:43:58 -0700 | [diff] [blame] | 489 | PHP_GRPC_MAKE_STD_ZVAL(recv_status); |
| 490 | object_init(recv_status); |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 491 | #if PHP_MAJOR_VERSION < 7 |
| 492 | array = grpc_parse_metadata_array(&recv_trailing_metadata TSRMLS_CC); |
| 493 | add_property_zval(recv_status, "metadata", array); |
| 494 | #else |
Stanley Cheung | e9595ba | 2017-05-09 15:43:58 -0700 | [diff] [blame] | 495 | recv_md = grpc_parse_metadata_array(&recv_trailing_metadata); |
| 496 | add_property_zval(recv_status, "metadata", recv_md); |
| 497 | zval_ptr_dtor(recv_md); |
| 498 | PHP_GRPC_FREE_STD_ZVAL(recv_md); |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 499 | #endif |
| 500 | PHP_GRPC_DELREF(array); |
| 501 | add_property_long(recv_status, "code", status); |
Craig Tiller | 7c70b6c | 2017-01-23 07:48:42 -0800 | [diff] [blame] | 502 | char *status_details_text = grpc_slice_to_c_string(recv_status_details); |
| 503 | php_grpc_add_property_string(recv_status, "details", status_details_text, |
Stanley Cheung | 8e56502 | 2016-07-28 10:32:43 -0700 | [diff] [blame] | 504 | true); |
Craig Tiller | 7c70b6c | 2017-01-23 07:48:42 -0800 | [diff] [blame] | 505 | gpr_free(status_details_text); |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 506 | add_property_zval(result, "status", recv_status); |
Stanley Cheung | e9595ba | 2017-05-09 15:43:58 -0700 | [diff] [blame] | 507 | #if PHP_MAJOR_VERSION >= 7 |
| 508 | zval_ptr_dtor(recv_status); |
| 509 | #endif |
thinkerou | ba75c01 | 2016-07-28 02:30:08 +0800 | [diff] [blame] | 510 | PHP_GRPC_DELREF(recv_status); |
thinkerou | 8d77014 | 2017-01-10 13:26:42 +0800 | [diff] [blame] | 511 | PHP_GRPC_FREE_STD_ZVAL(recv_status); |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 512 | break; |
| 513 | case GRPC_OP_RECV_CLOSE_ON_SERVER: |
thinkerou | 6f9d30b | 2016-07-27 03:19:03 +0800 | [diff] [blame] | 514 | add_property_bool(result, "cancelled", cancelled); |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 515 | break; |
| 516 | default: |
| 517 | break; |
| 518 | } |
| 519 | } |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 520 | |
murgatroid99 | afd541c | 2015-03-03 18:16:09 -0800 | [diff] [blame] | 521 | cleanup: |
ZhouyihaiDing | 0464879 | 2017-12-06 18:31:40 +0000 | [diff] [blame] | 522 | grpc_php_metadata_array_destroy_including_entries(&metadata); |
| 523 | grpc_php_metadata_array_destroy_including_entries(&trailing_metadata); |
murgatroid99 | afd541c | 2015-03-03 18:16:09 -0800 | [diff] [blame] | 524 | grpc_metadata_array_destroy(&recv_metadata); |
| 525 | grpc_metadata_array_destroy(&recv_trailing_metadata); |
Craig Tiller | 7c70b6c | 2017-01-23 07:48:42 -0800 | [diff] [blame] | 526 | grpc_slice_unref(recv_status_details); |
| 527 | grpc_slice_unref(send_status_details); |
Stanley Cheung | 82e6f32 | 2016-04-06 11:51:57 -0700 | [diff] [blame] | 528 | for (int i = 0; i < op_num; i++) { |
| 529 | if (ops[i].op == GRPC_OP_SEND_MESSAGE) { |
Mark D. Roth | 448c1f0 | 2017-01-25 10:44:30 -0800 | [diff] [blame] | 530 | grpc_byte_buffer_destroy(ops[i].data.send_message.send_message); |
Stanley Cheung | 82e6f32 | 2016-04-06 11:51:57 -0700 | [diff] [blame] | 531 | } |
| 532 | if (ops[i].op == GRPC_OP_RECV_MESSAGE) { |
| 533 | grpc_byte_buffer_destroy(message); |
thinkerou | 8d77014 | 2017-01-10 13:26:42 +0800 | [diff] [blame] | 534 | PHP_GRPC_FREE_STD_ZVAL(message_str); |
Stanley Cheung | 82e6f32 | 2016-04-06 11:51:57 -0700 | [diff] [blame] | 535 | } |
| 536 | } |
murgatroid99 | afd541c | 2015-03-03 18:16:09 -0800 | [diff] [blame] | 537 | RETURN_DESTROY_ZVAL(result); |
mlumish | b892a27 | 2014-12-09 16:28:23 -0800 | [diff] [blame] | 538 | } |
| 539 | |
murgatroid99 | c1da8f2 | 2015-03-25 11:33:05 -0700 | [diff] [blame] | 540 | /** |
Stanley Cheung | db98e08 | 2015-07-27 10:19:45 -0700 | [diff] [blame] | 541 | * Get the endpoint this call/stream is connected to |
| 542 | * @return string The URI of the endpoint |
| 543 | */ |
| 544 | PHP_METHOD(Call, getPeer) { |
thinkerou | fe037cb | 2018-05-16 12:51:28 +0800 | [diff] [blame^] | 545 | wrapped_grpc_call *call = PHP_GRPC_GET_WRAPPED_OBJECT(wrapped_grpc_call, |
| 546 | getThis()); |
Zhouyihai Ding | 159ceb6 | 2018-01-23 20:39:36 -0800 | [diff] [blame] | 547 | char *peer = grpc_call_get_peer(call->wrapped); |
| 548 | PHP_GRPC_RETVAL_STRING(peer, 1); |
| 549 | gpr_free(peer); |
Stanley Cheung | db98e08 | 2015-07-27 10:19:45 -0700 | [diff] [blame] | 550 | } |
| 551 | |
| 552 | /** |
thinkerou | efbc9e7 | 2016-08-16 20:00:36 +0800 | [diff] [blame] | 553 | * Cancel the call. This will cause the call to end with STATUS_CANCELLED |
| 554 | * if it has not already ended with another status. |
| 555 | * @return void |
murgatroid99 | c1da8f2 | 2015-03-25 11:33:05 -0700 | [diff] [blame] | 556 | */ |
| 557 | PHP_METHOD(Call, cancel) { |
thinkerou | fe037cb | 2018-05-16 12:51:28 +0800 | [diff] [blame^] | 558 | wrapped_grpc_call *call = PHP_GRPC_GET_WRAPPED_OBJECT(wrapped_grpc_call, |
| 559 | getThis()); |
Nicolas "Pixel" Noble | 150b7c4 | 2015-08-01 01:15:10 +0200 | [diff] [blame] | 560 | grpc_call_cancel(call->wrapped, NULL); |
murgatroid99 | c1da8f2 | 2015-03-25 11:33:05 -0700 | [diff] [blame] | 561 | } |
| 562 | |
Stanley Cheung | 3580580 | 2015-12-10 11:42:55 -0800 | [diff] [blame] | 563 | /** |
| 564 | * Set the CallCredentials for this call. |
thinkerou | efbc9e7 | 2016-08-16 20:00:36 +0800 | [diff] [blame] | 565 | * @param CallCredentials $creds_obj The CallCredentials object |
| 566 | * @return int The error code |
Stanley Cheung | 3580580 | 2015-12-10 11:42:55 -0800 | [diff] [blame] | 567 | */ |
| 568 | PHP_METHOD(Call, setCredentials) { |
| 569 | zval *creds_obj; |
| 570 | |
| 571 | /* "O" == 1 Object */ |
| 572 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &creds_obj, |
| 573 | grpc_ce_call_credentials) == FAILURE) { |
| 574 | zend_throw_exception(spl_ce_InvalidArgumentException, |
| 575 | "setCredentials expects 1 CallCredentials", |
| 576 | 1 TSRMLS_CC); |
| 577 | return; |
| 578 | } |
| 579 | |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 580 | wrapped_grpc_call_credentials *creds = |
thinkerou | fe037cb | 2018-05-16 12:51:28 +0800 | [diff] [blame^] | 581 | PHP_GRPC_GET_WRAPPED_OBJECT(wrapped_grpc_call_credentials, creds_obj); |
| 582 | wrapped_grpc_call *call = PHP_GRPC_GET_WRAPPED_OBJECT(wrapped_grpc_call, |
| 583 | getThis()); |
Stanley Cheung | 3580580 | 2015-12-10 11:42:55 -0800 | [diff] [blame] | 584 | |
| 585 | grpc_call_error error = GRPC_CALL_ERROR; |
| 586 | error = grpc_call_set_credentials(call->wrapped, creds->wrapped); |
| 587 | RETURN_LONG(error); |
| 588 | } |
| 589 | |
Stanley Cheung | 6a5c83d | 2017-02-16 12:25:32 -0800 | [diff] [blame] | 590 | ZEND_BEGIN_ARG_INFO_EX(arginfo_construct, 0, 0, 3) |
| 591 | ZEND_ARG_INFO(0, channel) |
| 592 | ZEND_ARG_INFO(0, method) |
| 593 | ZEND_ARG_INFO(0, deadline) |
| 594 | ZEND_ARG_INFO(0, host_override) |
| 595 | ZEND_END_ARG_INFO() |
| 596 | |
| 597 | ZEND_BEGIN_ARG_INFO_EX(arginfo_startBatch, 0, 0, 1) |
| 598 | ZEND_ARG_INFO(0, ops) |
| 599 | ZEND_END_ARG_INFO() |
| 600 | |
| 601 | ZEND_BEGIN_ARG_INFO_EX(arginfo_getPeer, 0, 0, 0) |
| 602 | ZEND_END_ARG_INFO() |
| 603 | |
| 604 | ZEND_BEGIN_ARG_INFO_EX(arginfo_cancel, 0, 0, 0) |
| 605 | ZEND_END_ARG_INFO() |
| 606 | |
| 607 | ZEND_BEGIN_ARG_INFO_EX(arginfo_setCredentials, 0, 0, 1) |
| 608 | ZEND_ARG_INFO(0, credentials) |
| 609 | ZEND_END_ARG_INFO() |
| 610 | |
mlumish | b892a27 | 2014-12-09 16:28:23 -0800 | [diff] [blame] | 611 | static zend_function_entry call_methods[] = { |
Stanley Cheung | 6a5c83d | 2017-02-16 12:25:32 -0800 | [diff] [blame] | 612 | PHP_ME(Call, __construct, arginfo_construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) |
| 613 | PHP_ME(Call, startBatch, arginfo_startBatch, ZEND_ACC_PUBLIC) |
| 614 | PHP_ME(Call, getPeer, arginfo_getPeer, ZEND_ACC_PUBLIC) |
| 615 | PHP_ME(Call, cancel, arginfo_cancel, ZEND_ACC_PUBLIC) |
| 616 | PHP_ME(Call, setCredentials, arginfo_setCredentials, ZEND_ACC_PUBLIC) |
thinkerou | a3730b7 | 2016-07-20 16:59:54 +0800 | [diff] [blame] | 617 | PHP_FE_END |
| 618 | }; |
mlumish | b892a27 | 2014-12-09 16:28:23 -0800 | [diff] [blame] | 619 | |
Craig Tiller | b5dcec5 | 2015-01-13 11:13:42 -0800 | [diff] [blame] | 620 | void grpc_init_call(TSRMLS_D) { |
mlumish | b892a27 | 2014-12-09 16:28:23 -0800 | [diff] [blame] | 621 | zend_class_entry ce; |
| 622 | INIT_CLASS_ENTRY(ce, "Grpc\\Call", call_methods); |
| 623 | ce.create_object = create_wrapped_grpc_call; |
| 624 | grpc_ce_call = zend_register_internal_class(&ce TSRMLS_CC); |
thinkerou | 5dafd82 | 2016-07-28 22:43:38 +0800 | [diff] [blame] | 625 | PHP_GRPC_INIT_HANDLER(wrapped_grpc_call, call_ce_handlers); |
mlumish | b892a27 | 2014-12-09 16:28:23 -0800 | [diff] [blame] | 626 | } |