diff options
Diffstat (limited to 'src/php')
-rwxr-xr-x | src/php/bin/run_tests.sh | 2 | ||||
-rw-r--r-- | src/php/ext/grpc/call.c | 32 | ||||
-rw-r--r-- | src/php/ext/grpc/call.h | 4 | ||||
-rw-r--r-- | src/php/ext/grpc/call_credentials.c | 101 | ||||
-rwxr-xr-x | src/php/ext/grpc/call_credentials.h | 14 | ||||
-rw-r--r-- | src/php/ext/grpc/channel.c | 12 | ||||
-rw-r--r-- | src/php/ext/grpc/channel_credentials.c | 10 | ||||
-rw-r--r-- | src/php/ext/grpc/package.xml | 43 | ||||
-rw-r--r-- | src/php/lib/Grpc/AbstractCall.php | 35 | ||||
-rwxr-xr-x | src/php/lib/Grpc/BaseStub.php | 86 | ||||
-rw-r--r-- | src/php/tests/generated_code/AbstractGeneratedCodeTest.php | 7 | ||||
-rwxr-xr-x | src/php/tests/generated_code/GeneratedCodeTest.php | 6 | ||||
-rw-r--r-- | src/php/tests/generated_code/GeneratedCodeWithCallbackTest.php | 5 | ||||
-rwxr-xr-x | src/php/tests/interop/interop_client.php | 32 | ||||
-rw-r--r-- | src/php/tests/unit_tests/CallCredentialsTest.php | 137 |
15 files changed, 429 insertions, 97 deletions
diff --git a/src/php/bin/run_tests.sh b/src/php/bin/run_tests.sh index 2a7335e20a..235d161ca7 100755 --- a/src/php/bin/run_tests.sh +++ b/src/php/bin/run_tests.sh @@ -30,7 +30,7 @@ # Loads the local shared library, and runs all of the test cases in tests/ # against it -set -e +set -ex cd $(dirname $0)/../../.. root=$(pwd) cd src/php/bin diff --git a/src/php/ext/grpc/call.c b/src/php/ext/grpc/call.c index 3b99de7538..7ba14a38d8 100644 --- a/src/php/ext/grpc/call.c +++ b/src/php/ext/grpc/call.c @@ -42,13 +42,13 @@ #include <ext/standard/info.h> #include <ext/spl/spl_exceptions.h> #include "php_grpc.h" +#include "call_credentials.h" #include <zend_exceptions.h> #include <zend_hash.h> #include <stdbool.h> -#include <grpc/support/log.h> #include <grpc/support/alloc.h> #include <grpc/grpc.h> @@ -515,11 +515,41 @@ PHP_METHOD(Call, cancel) { grpc_call_cancel(call->wrapped, NULL); } +/** + * Set the CallCredentials for this call. + * @param CallCredentials creds_obj The CallCredentials object + * @param int The error code + */ +PHP_METHOD(Call, setCredentials) { + zval *creds_obj; + + /* "O" == 1 Object */ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &creds_obj, + grpc_ce_call_credentials) == FAILURE) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "setCredentials expects 1 CallCredentials", + 1 TSRMLS_CC); + return; + } + + wrapped_grpc_call_credentials *creds = + (wrapped_grpc_call_credentials *)zend_object_store_get_object( + creds_obj TSRMLS_CC); + + wrapped_grpc_call *call = + (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC); + + grpc_call_error error = GRPC_CALL_ERROR; + error = grpc_call_set_credentials(call->wrapped, creds->wrapped); + RETURN_LONG(error); +} + static zend_function_entry call_methods[] = { PHP_ME(Call, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) PHP_ME(Call, startBatch, NULL, ZEND_ACC_PUBLIC) PHP_ME(Call, getPeer, NULL, ZEND_ACC_PUBLIC) PHP_ME(Call, cancel, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Call, setCredentials, NULL, ZEND_ACC_PUBLIC) PHP_FE_END}; void grpc_init_call(TSRMLS_D) { diff --git a/src/php/ext/grpc/call.h b/src/php/ext/grpc/call.h index f3ef89dc97..73efadae35 100644 --- a/src/php/ext/grpc/call.h +++ b/src/php/ext/grpc/call.h @@ -66,4 +66,8 @@ zval *grpc_php_wrap_call(grpc_call *wrapped, bool owned); * call metadata */ zval *grpc_parse_metadata_array(grpc_metadata_array *metadata_array); +/* Populates a grpc_metadata_array with the data in a PHP array object. + Returns true on success and false on failure */ +bool create_metadata_array(zval *array, grpc_metadata_array *metadata); + #endif /* NET_GRPC_PHP_GRPC_CHANNEL_H_ */ diff --git a/src/php/ext/grpc/call_credentials.c b/src/php/ext/grpc/call_credentials.c index 17f167befb..285c4e7c85 100644 --- a/src/php/ext/grpc/call_credentials.c +++ b/src/php/ext/grpc/call_credentials.c @@ -43,6 +43,7 @@ #include <ext/standard/info.h> #include <ext/spl/spl_exceptions.h> #include "php_grpc.h" +#include "call.h" #include <zend_exceptions.h> #include <zend_hash.h> @@ -103,7 +104,7 @@ PHP_METHOD(CallCredentials, createComposite) { zval *cred1_obj; zval *cred2_obj; - /* "OO" == 3 Objects */ + /* "OO" == 2 Objects */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OO", &cred1_obj, grpc_ce_call_credentials, &cred2_obj, grpc_ce_call_credentials) == FAILURE) { @@ -125,9 +126,107 @@ PHP_METHOD(CallCredentials, createComposite) { RETURN_DESTROY_ZVAL(creds_object); } +/** + * Create a call credentials object from the plugin API + * @param function callback The callback function + * @return CallCredentials The new call credentials object + */ +PHP_METHOD(CallCredentials, createFromPlugin) { + zend_fcall_info *fci; + zend_fcall_info_cache *fci_cache; + + fci = (zend_fcall_info *)emalloc(sizeof(zend_fcall_info)); + fci_cache = (zend_fcall_info_cache *)emalloc(sizeof(zend_fcall_info_cache)); + memset(fci, 0, sizeof(zend_fcall_info)); + memset(fci_cache, 0, sizeof(zend_fcall_info_cache)); + + /* "f" == 1 function */ + if (zend_parse_parameters(ZEND_NUM_ARGS(), "f", fci, + fci_cache, + fci->params, + fci->param_count) == FAILURE) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "createFromPlugin expects 1 callback", + 1 TSRMLS_CC); + return; + } + + plugin_state *state; + state = (plugin_state *)emalloc(sizeof(plugin_state)); + memset(state, 0, sizeof(plugin_state)); + + /* save the user provided PHP callback function */ + state->fci = fci; + state->fci_cache = fci_cache; + + grpc_metadata_credentials_plugin plugin; + plugin.get_metadata = plugin_get_metadata; + plugin.destroy = plugin_destroy_state; + plugin.state = (void *)state; + plugin.type = ""; + + grpc_call_credentials *creds = grpc_metadata_credentials_create_from_plugin( + plugin, NULL); + zval *creds_object = grpc_php_wrap_call_credentials(creds); + RETURN_DESTROY_ZVAL(creds_object); +} + +/* Callback function for plugin creds API */ +void plugin_get_metadata(void *ptr, grpc_auth_metadata_context context, + grpc_credentials_plugin_metadata_cb cb, + void *user_data) { + plugin_state *state = (plugin_state *)ptr; + + /* prepare to call the user callback function with info from the + * grpc_auth_metadata_context */ + zval **params[1]; + zval *arg; + zval *retval; + MAKE_STD_ZVAL(arg); + object_init(arg); + add_property_string(arg, "service_url", context.service_url, true); + add_property_string(arg, "method_name", context.method_name, true); + params[0] = &arg; + state->fci->param_count = 1; + state->fci->params = params; + state->fci->retval_ptr_ptr = &retval; + + /* call the user callback function */ + zend_call_function(state->fci, state->fci_cache); + + if (Z_TYPE_P(retval) != IS_ARRAY) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "plugin callback must return metadata array", + 1 TSRMLS_CC); + } + + grpc_metadata_array metadata; + if (!create_metadata_array(retval, &metadata)) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "invalid metadata", 1 TSRMLS_CC); + grpc_metadata_array_destroy(&metadata); + } + + /* TODO: handle error */ + grpc_status_code code = GRPC_STATUS_OK; + + /* Pass control back to core */ + cb(user_data, metadata.metadata, metadata.count, code, NULL); +} + +/* Cleanup function for plugin creds API */ +void plugin_destroy_state(void *ptr) { + plugin_state *state = (plugin_state *)ptr; + efree(state->fci); + efree(state->fci_cache); + efree(state); +} + static zend_function_entry call_credentials_methods[] = { PHP_ME(CallCredentials, createComposite, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(CallCredentials, createFromPlugin, NULL, + ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_FE_END}; void grpc_init_call_credentials(TSRMLS_D) { diff --git a/src/php/ext/grpc/call_credentials.h b/src/php/ext/grpc/call_credentials.h index 8f35ac68bc..d2f6a92449 100755 --- a/src/php/ext/grpc/call_credentials.h +++ b/src/php/ext/grpc/call_credentials.h @@ -57,6 +57,20 @@ typedef struct wrapped_grpc_call_credentials { grpc_call_credentials *wrapped; } wrapped_grpc_call_credentials; +/* Struct to hold callback function for plugin creds API */ +typedef struct plugin_state { + zend_fcall_info *fci; + zend_fcall_info_cache *fci_cache; +} plugin_state; + +/* Callback function for plugin creds API */ +void plugin_get_metadata(void *state, grpc_auth_metadata_context context, + grpc_credentials_plugin_metadata_cb cb, + void *user_data); + +/* Cleanup function for plugin creds API */ +void plugin_destroy_state(void *ptr); + /* Initializes the CallCredentials PHP class */ void grpc_init_call_credentials(TSRMLS_D); diff --git a/src/php/ext/grpc/channel.c b/src/php/ext/grpc/channel.c index f8c4f0423f..60c94412dc 100644 --- a/src/php/ext/grpc/channel.c +++ b/src/php/ext/grpc/channel.c @@ -154,16 +154,20 @@ PHP_METHOD(Channel, __construct) { array_hash = Z_ARRVAL_P(args_array); if (zend_hash_find(array_hash, "credentials", sizeof("credentials"), (void **)&creds_obj) == SUCCESS) { - if (zend_get_class_entry(*creds_obj TSRMLS_CC) != + if (Z_TYPE_P(*creds_obj) == IS_NULL) { + creds = NULL; + zend_hash_del(array_hash, "credentials", 12); + } else if (zend_get_class_entry(*creds_obj TSRMLS_CC) != grpc_ce_channel_credentials) { zend_throw_exception(spl_ce_InvalidArgumentException, "credentials must be a ChannelCredentials object", 1 TSRMLS_CC); return; + } else { + creds = (wrapped_grpc_channel_credentials *)zend_object_store_get_object( + *creds_obj TSRMLS_CC); + zend_hash_del(array_hash, "credentials", 12); } - creds = (wrapped_grpc_channel_credentials *)zend_object_store_get_object( - *creds_obj TSRMLS_CC); - zend_hash_del(array_hash, "credentials", 12); } php_grpc_read_args_array(args_array, &args); if (creds == NULL) { diff --git a/src/php/ext/grpc/channel_credentials.c b/src/php/ext/grpc/channel_credentials.c index df4a5d5162..ae9a9897fc 100644 --- a/src/php/ext/grpc/channel_credentials.c +++ b/src/php/ext/grpc/channel_credentials.c @@ -169,6 +169,14 @@ PHP_METHOD(ChannelCredentials, createComposite) { RETURN_DESTROY_ZVAL(creds_object); } +/** + * Create insecure channel credentials + * @return null + */ +PHP_METHOD(ChannelCredentials, createInsecure) { + RETURN_NULL(); +} + static zend_function_entry channel_credentials_methods[] = { PHP_ME(ChannelCredentials, createDefault, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) @@ -176,6 +184,8 @@ static zend_function_entry channel_credentials_methods[] = { ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_ME(ChannelCredentials, createComposite, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(ChannelCredentials, createInsecure, NULL, + ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_FE_END}; void grpc_init_channel_credentials(TSRMLS_D) { diff --git a/src/php/ext/grpc/package.xml b/src/php/ext/grpc/package.xml index a2e3e2826a..9c98f82540 100644 --- a/src/php/ext/grpc/package.xml +++ b/src/php/ext/grpc/package.xml @@ -10,11 +10,11 @@ <email>grpc-packages@google.com</email> <active>yes</active> </lead> - <date>2015-10-21</date> - <time>17:04:32</time> + <date>2015-12-16</date> + <time>12:56:11</time> <version> - <release>0.6.1</release> - <api>0.6.0</api> + <release>0.7.0</release> + <api>0.7.0</api> </version> <stability> <release>beta</release> @@ -22,19 +22,22 @@ </stability> <license>BSD</license> <notes> -- fixed undefined constant fatal error when run with apache/nginx #2275 +- Breaking change to Credentials class (removed) #3765 +- Replaced by ChannelCredentials and CallCredentials class #3765 +- New plugin based metadata auth API #4394 +- Explicit ChannelCredentials::createInsecure() call </notes> <contents> <dir baseinstalldir="/" name="/"> <file baseinstalldir="/" md5sum="6f19828fb869b7b8a590cbb76b4f996d" name="byte_buffer.c" role="src" /> <file baseinstalldir="/" md5sum="c8de0f819499c48adfc8d7f472c0196b" name="byte_buffer.h" role="src" /> - <file baseinstalldir="/" md5sum="d64c9005993de02abac55664b0b9e0b2" name="call.c" role="src" /> - <file baseinstalldir="/" md5sum="26acbf04c30162c2d2aca4688bb2aec8" name="call.h" role="src" /> - <file baseinstalldir="/" md5sum="6fa13d260dfde216f795225644f04e7a" name="call_credentials.c" role="src" /> - <file baseinstalldir="/" md5sum="e45269975f9a30fd349a90daf6b31aa2" name="call_credentials.h" role="src" /> - <file baseinstalldir="/" md5sum="0779db3b196c98081b2260ceec22cd4d" name="channel.c" role="src" /> + <file baseinstalldir="/" md5sum="ee7eb7757f9e6f0e36f8f616b6bd0af5" name="call.c" role="src" /> + <file baseinstalldir="/" md5sum="44c56bd9912d2538cbd6059e3e0452b6" name="call.h" role="src" /> + <file baseinstalldir="/" md5sum="ff90f6c03ed44b5f4170bf3259a6704e" name="call_credentials.c" role="src" /> + <file baseinstalldir="/" md5sum="3c3860e1d84f43cb6b2fbaa8d2ae1ab7" name="call_credentials.h" role="src" /> + <file baseinstalldir="/" md5sum="aee9b63f790522aec2c682055240cc61" name="channel.c" role="src" /> <file baseinstalldir="/" md5sum="ed4b00c0cf3702b115d0cfa87450dc09" name="channel.h" role="src" /> - <file baseinstalldir="/" md5sum="1b40f50fa6184ad7d24a961ac76151ff" name="channel_credentials.c" role="src" /> + <file baseinstalldir="/" md5sum="1a51c76d0b7b7d3ab570ed7d60c2ea46" name="channel_credentials.c" role="src" /> <file baseinstalldir="/" md5sum="a86250e03f610ce6c2c7595a84e08821" name="channel_credentials.h" role="src" /> <file baseinstalldir="/" md5sum="55ab7a42f9dd9bfc7e28a61cfc5fca63" name="completion_queue.c" role="src" /> <file baseinstalldir="/" md5sum="f10b5bb232d74a6878e829e2e76cdaa2" name="completion_queue.h" role="src" /> @@ -130,5 +133,23 @@ Update to wrap gRPC C Core version 0.10.0 - fixed undefined constant fatal error when run with apache/nginx #2275 </notes> </release> + <release> + <version> + <release>0.7.0</release> + <api>0.7.0</api> + </version> + <stability> + <release>beta</release> + <api>beta</api> + </stability> + <date>2015-12-16</date> + <license>BSD</license> + <notes> +- Breaking change to Credentials class (removed) #3765 +- Replaced by ChannelCredentials and CallCredentials class #3765 +- New plugin based metadata auth API #4394 +- Explicit ChannelCredentials::createInsecure() call + </notes> + </release> </changelog> </package> diff --git a/src/php/lib/Grpc/AbstractCall.php b/src/php/lib/Grpc/AbstractCall.php index 53849d51fc..712af91eb2 100644 --- a/src/php/lib/Grpc/AbstractCall.php +++ b/src/php/lib/Grpc/AbstractCall.php @@ -43,19 +43,20 @@ abstract class AbstractCall /** * Create a new Call wrapper object. * - * @param Channel $channel The channel to communicate on - * @param string $method The method to call on the - * remote server - * @param callback $deserialize A callback function to deserialize - * the response - * @param (optional) long $timeout Timeout in microseconds + * @param Channel $channel The channel to communicate on + * @param string $method The method to call on the + * remote server + * @param callback $deserialize A callback function to deserialize + * the response + * @param array $options Call options (optional) */ public function __construct(Channel $channel, $method, $deserialize, - $timeout = false) + $options = []) { - if ($timeout) { + if (isset($options['timeout']) && + is_numeric($timeout = $options['timeout'])) { $now = Timeval::now(); $delta = new Timeval($timeout); $deadline = $now->add($delta); @@ -65,6 +66,13 @@ abstract class AbstractCall $this->call = new Call($channel, $method, $deadline); $this->deserialize = $deserialize; $this->metadata = null; + if (isset($options['call_credentials_callback']) && + is_callable($call_credentials_callback = + $options['call_credentials_callback'])) { + $call_credentials = CallCredentials::createFromPlugin( + $call_credentials_callback); + $this->call->setCredentials($call_credentials); + } } /** @@ -106,4 +114,15 @@ abstract class AbstractCall return call_user_func($this->deserialize, $value); } + + /** + * Set the CallCredentials for the underlying Call. + * + * @param CallCredentials $call_credentials The CallCredentials + * object + */ + public function setCallCredentials($call_credentials) + { + $this->call->setCredentials($call_credentials); + } } diff --git a/src/php/lib/Grpc/BaseStub.php b/src/php/lib/Grpc/BaseStub.php index 7b2627f516..2de1b337e5 100755 --- a/src/php/lib/Grpc/BaseStub.php +++ b/src/php/lib/Grpc/BaseStub.php @@ -72,6 +72,11 @@ class BaseStub } $opts['grpc.primary_user_agent'] .= 'grpc-php/'.$package_config['version']; + if (!array_key_exists('credentials', $opts)) { + throw new \Exception("The opts['credentials'] key is now ". + 'required. Please see one of the '. + 'ChannelCredentials::create methods'); + } $this->channel = new Channel($hostname, $opts); } @@ -159,25 +164,6 @@ class BaseStub } /** - * extract $timeout from $metadata. - * - * @param $metadata The metadata map - * - * @return list($metadata_copy, $timeout) - */ - private function _extract_timeout_from_metadata($metadata) - { - $timeout = false; - $metadata_copy = $metadata; - if (isset($metadata['timeout'])) { - $timeout = $metadata['timeout']; - unset($metadata_copy['timeout']); - } - - return [$metadata_copy, $timeout]; - } - - /** * validate and normalize the metadata array. * * @param $metadata The metadata map @@ -220,21 +206,19 @@ class BaseStub $metadata = [], $options = []) { - list($actual_metadata, $timeout) = - $this->_extract_timeout_from_metadata($metadata); $call = new UnaryCall($this->channel, $method, $deserialize, - $timeout); + $options); $jwt_aud_uri = $this->_get_jwt_aud_uri($method); if (is_callable($this->update_metadata)) { - $actual_metadata = call_user_func($this->update_metadata, - $actual_metadata, + $metadata = call_user_func($this->update_metadata, + $metadata, $jwt_aud_uri); } - $actual_metadata = $this->_validate_and_normalize_metadata( - $actual_metadata); - $call->start($argument, $actual_metadata, $options); + $metadata = $this->_validate_and_normalize_metadata( + $metadata); + $call->start($argument, $metadata, $options); return $call; } @@ -253,23 +237,22 @@ class BaseStub */ public function _clientStreamRequest($method, callable $deserialize, - $metadata = []) + $metadata = [], + $options = []) { - list($actual_metadata, $timeout) = - $this->_extract_timeout_from_metadata($metadata); $call = new ClientStreamingCall($this->channel, $method, $deserialize, - $timeout); + $options); $jwt_aud_uri = $this->_get_jwt_aud_uri($method); if (is_callable($this->update_metadata)) { - $actual_metadata = call_user_func($this->update_metadata, - $actual_metadata, + $metadata = call_user_func($this->update_metadata, + $metadata, $jwt_aud_uri); } - $actual_metadata = $this->_validate_and_normalize_metadata( - $actual_metadata); - $call->start($actual_metadata); + $metadata = $this->_validate_and_normalize_metadata( + $metadata); + $call->start($metadata); return $call; } @@ -291,21 +274,19 @@ class BaseStub $metadata = [], $options = []) { - list($actual_metadata, $timeout) = - $this->_extract_timeout_from_metadata($metadata); $call = new ServerStreamingCall($this->channel, $method, $deserialize, - $timeout); + $options); $jwt_aud_uri = $this->_get_jwt_aud_uri($method); if (is_callable($this->update_metadata)) { - $actual_metadata = call_user_func($this->update_metadata, - $actual_metadata, + $metadata = call_user_func($this->update_metadata, + $metadata, $jwt_aud_uri); } - $actual_metadata = $this->_validate_and_normalize_metadata( - $actual_metadata); - $call->start($argument, $actual_metadata, $options); + $metadata = $this->_validate_and_normalize_metadata( + $metadata); + $call->start($argument, $metadata, $options); return $call; } @@ -321,23 +302,22 @@ class BaseStub */ public function _bidiRequest($method, callable $deserialize, - $metadata = []) + $metadata = [], + $options = []) { - list($actual_metadata, $timeout) = - $this->_extract_timeout_from_metadata($metadata); $call = new BidiStreamingCall($this->channel, $method, $deserialize, - $timeout); + $options); $jwt_aud_uri = $this->_get_jwt_aud_uri($method); if (is_callable($this->update_metadata)) { - $actual_metadata = call_user_func($this->update_metadata, - $actual_metadata, + $metadata = call_user_func($this->update_metadata, + $metadata, $jwt_aud_uri); } - $actual_metadata = $this->_validate_and_normalize_metadata( - $actual_metadata); - $call->start($actual_metadata); + $metadata = $this->_validate_and_normalize_metadata( + $metadata); + $call->start($metadata); return $call; } diff --git a/src/php/tests/generated_code/AbstractGeneratedCodeTest.php b/src/php/tests/generated_code/AbstractGeneratedCodeTest.php index 4a0bd6a1f1..1fe81b9d54 100644 --- a/src/php/tests/generated_code/AbstractGeneratedCodeTest.php +++ b/src/php/tests/generated_code/AbstractGeneratedCodeTest.php @@ -41,7 +41,6 @@ abstract class AbstractGeneratedCodeTest extends PHPUnit_Framework_TestCase * running on $GRPC_TEST_HOST. */ protected static $client; - protected static $timeout; public function testWaitForNotReady() { @@ -93,7 +92,7 @@ abstract class AbstractGeneratedCodeTest extends PHPUnit_Framework_TestCase public function testTimeout() { $div_arg = new math\DivArgs(); - $call = self::$client->Div($div_arg, ['timeout' => 100]); + $call = self::$client->Div($div_arg, [], ['timeout' => 100]); list($response, $status) = $call->wait(); $this->assertSame(\Grpc\STATUS_DEADLINE_EXCEEDED, $status->code); } @@ -112,7 +111,9 @@ abstract class AbstractGeneratedCodeTest extends PHPUnit_Framework_TestCase */ public function testInvalidMethodName() { - $invalid_client = new DummyInvalidClient('host', []); + $invalid_client = new DummyInvalidClient('host', [ + 'credentials' => Grpc\ChannelCredentials::createInsecure(), + ]); $div_arg = new math\DivArgs(); $invalid_client->InvalidUnaryCall($div_arg); } diff --git a/src/php/tests/generated_code/GeneratedCodeTest.php b/src/php/tests/generated_code/GeneratedCodeTest.php index 7043e8e1d1..0cdce6cf92 100755 --- a/src/php/tests/generated_code/GeneratedCodeTest.php +++ b/src/php/tests/generated_code/GeneratedCodeTest.php @@ -38,10 +38,12 @@ class GeneratedCodeTest extends AbstractGeneratedCodeTest public function setUp() { self::$client = new math\MathClient( - getenv('GRPC_TEST_HOST'), []); + getenv('GRPC_TEST_HOST'), [ + 'credentials' => Grpc\ChannelCredentials::createInsecure(), + ]); } - public static function tearDownAfterClass() + public function tearDown() { self::$client->close(); } diff --git a/src/php/tests/generated_code/GeneratedCodeWithCallbackTest.php b/src/php/tests/generated_code/GeneratedCodeWithCallbackTest.php index 5a20e684c7..6bb1955ccb 100644 --- a/src/php/tests/generated_code/GeneratedCodeWithCallbackTest.php +++ b/src/php/tests/generated_code/GeneratedCodeWithCallbackTest.php @@ -39,7 +39,8 @@ class GeneratedCodeWithCallbackTest extends AbstractGeneratedCodeTest { self::$client = new math\MathClient( getenv('GRPC_TEST_HOST'), - ['update_metadata' => function ($a_hash, + ['credentials' => Grpc\ChannelCredentials::createInsecure(), + 'update_metadata' => function ($a_hash, $client = []) { $a_copy = $a_hash; $a_copy['foo'] = ['bar']; @@ -48,7 +49,7 @@ class GeneratedCodeWithCallbackTest extends AbstractGeneratedCodeTest }]); } - public static function tearDownAfterClass() + public function tearDown() { self::$client->close(); } diff --git a/src/php/tests/interop/interop_client.php b/src/php/tests/interop/interop_client.php index 9aab5c966c..aebf80f6bf 100755 --- a/src/php/tests/interop/interop_client.php +++ b/src/php/tests/interop/interop_client.php @@ -84,7 +84,7 @@ function largeUnary($stub) * @param $fillOauthScope boolean whether to fill result with oauth scope */ function performLargeUnary($stub, $fillUsername = false, $fillOauthScope = false, - $metadata = []) + $callback = false) { $request_len = 271828; $response_len = 314159; @@ -99,7 +99,12 @@ function performLargeUnary($stub, $fillUsername = false, $fillOauthScope = false $request->setFillUsername($fillUsername); $request->setFillOauthScope($fillOauthScope); - list($result, $status) = $stub->UnaryCall($request, $metadata)->wait(); + $options = false; + if ($callback) { + $options['call_credentials_callback'] = $callback; + } + + list($result, $status) = $stub->UnaryCall($request, [], $options)->wait(); hardAssert($status->code === Grpc\STATUS_OK, 'Call did not complete successfully'); hardAssert($result !== null, 'Call returned a null response'); $payload = $result->getPayload(); @@ -186,6 +191,15 @@ function oauth2AuthToken($stub, $args) 'invalid email returned'); } +function updateAuthMetadataCallback($context) +{ + $authUri = $context->service_url; + $methodName = $context->method_name; + $auth_credentials = ApplicationDefaultCredentials::getCredentials(); + + return $auth_credentials->updateMetadata($metadata = [], $authUri); +} + /** * Run the per_rpc_creds auth test. * @@ -197,15 +211,9 @@ function perRpcCreds($stub, $args) $jsonKey = json_decode( file_get_contents(getenv(CredentialsLoader::ENV_VAR)), true); - $auth_credentials = ApplicationDefaultCredentials::getCredentials( - $args['oauth_scope'] - ); - $token = $auth_credentials->fetchAuthToken(); - $metadata = [CredentialsLoader::AUTH_METADATA_KEY => [sprintf('%s %s', - $token['token_type'], - $token['access_token'])]]; + $result = performLargeUnary($stub, $fillUsername = true, $fillOauthScope = true, - $metadata); + 'updateAuthMetadataCallback'); hardAssert($result->getUsername() == $jsonKey['client_email'], 'invalid email returned'); } @@ -363,7 +371,7 @@ function cancelAfterFirstResponse($stub) function timeoutOnSleepingServer($stub) { - $call = $stub->FullDuplexCall(['timeout' => 1000]); + $call = $stub->FullDuplexCall([], ['timeout' => 1000]); $request = new grpc\testing\StreamingOutputCallRequest(); $request->setResponseType(grpc\testing\PayloadType::COMPRESSABLE); $response_parameters = new grpc\testing\ResponseParameters(); @@ -430,6 +438,8 @@ if ($use_tls) { } $opts['credentials'] = $ssl_credentials; $opts['grpc.ssl_target_name_override'] = $host_override; +} else { + $opts['credentials'] = Grpc\ChannelCredentials::createInsecure(); } if (in_array($test_case, ['service_account_creds', diff --git a/src/php/tests/unit_tests/CallCredentialsTest.php b/src/php/tests/unit_tests/CallCredentialsTest.php new file mode 100644 index 0000000000..0918412781 --- /dev/null +++ b/src/php/tests/unit_tests/CallCredentialsTest.php @@ -0,0 +1,137 @@ +<?php +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +class CallCredentialsTest extends PHPUnit_Framework_TestCase +{ + public function setUp() + { + $credentials = Grpc\ChannelCredentials::createSsl( + file_get_contents(dirname(__FILE__).'/../data/ca.pem')); + $call_credentials = Grpc\CallCredentials::createFromPlugin( + array($this, 'callbackFunc')); + $credentials = Grpc\ChannelCredentials::createComposite( + $credentials, + $call_credentials + ); + $server_credentials = Grpc\ServerCredentials::createSsl( + null, + file_get_contents(dirname(__FILE__).'/../data/server1.key'), + file_get_contents(dirname(__FILE__).'/../data/server1.pem')); + $this->server = new Grpc\Server(); + $this->port = $this->server->addSecureHttp2Port('0.0.0.0:0', + $server_credentials); + $this->server->start(); + $this->host_override = 'foo.test.google.fr'; + $this->channel = new Grpc\Channel( + 'localhost:'.$this->port, + [ + 'grpc.ssl_target_name_override' => $this->host_override, + 'grpc.default_authority' => $this->host_override, + 'credentials' => $credentials, + ] + ); + } + + public function tearDown() + { + unset($this->channel); + unset($this->server); + } + + public function callbackFunc($context) + { + $this->assertTrue(is_string($context->service_url)); + $this->assertTrue(is_string($context->method_name)); + + return ['k1' => ['v1'], 'k2' => ['v2']]; + } + + public function testCreateFromPlugin() + { + $deadline = Grpc\Timeval::infFuture(); + $status_text = 'xyz'; + $call = new Grpc\Call($this->channel, + '/abc/dummy_method', + $deadline, + $this->host_override); + + $event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + ]); + + $this->assertTrue($event->send_metadata); + $this->assertTrue($event->send_close); + + $event = $this->server->requestCall(); + + $this->assertTrue(is_array($event->metadata)); + $metadata = $event->metadata; + $this->assertTrue(array_key_exists('k1', $metadata)); + $this->assertTrue(array_key_exists('k2', $metadata)); + $this->assertSame($metadata['k1'], ['v1']); + $this->assertSame($metadata['k2'], ['v2']); + + $this->assertSame('/abc/dummy_method', $event->method); + $server_call = $event->call; + + $event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => Grpc\STATUS_OK, + 'details' => $status_text, + ], + Grpc\OP_RECV_CLOSE_ON_SERVER => true, + ]); + + $this->assertTrue($event->send_metadata); + $this->assertTrue($event->send_status); + $this->assertFalse($event->cancelled); + + $event = $call->startBatch([ + Grpc\OP_RECV_INITIAL_METADATA => true, + Grpc\OP_RECV_STATUS_ON_CLIENT => true, + ]); + + $this->assertSame([], $event->metadata); + $status = $event->status; + $this->assertSame([], $status->metadata); + $this->assertSame(Grpc\STATUS_OK, $status->code); + $this->assertSame($status_text, $status->details); + + unset($call); + unset($server_call); + } +} |