コード例 #1
0
/**
 * Create SSL credentials.
 * @param string pem_root_certs PEM encoding of the server root certificates
 * @param string pem_private_key PEM encoding of the client's private key
 * @param string pem_cert_chain PEM encoding of the client's certificate chain
 * @return Credentials The new SSL credentials object
 */
PHP_METHOD(ServerCredentials, createSsl) {
  zend_string *pem_root_certs = NULL;
  zend_string *private_key;
  zend_string *cert_chain;

  grpc_ssl_pem_key_cert_pair pem_key_cert_pair;

  /* "S!SS" == 1 nullable string, 2 strings */
  /* TODO: support multiple key cert pairs. */
  if (zend_parse_parameters(ZEND_NUM_ARGS(), "S!SS", &pem_root_certs,
                            &private_key, &cert_chain) == FAILURE) {
    zend_throw_exception(spl_ce_InvalidArgumentException,
                         "createSsl expects 3 strings", 1);
    return;
  }

  if (private_key) {
    pem_key_cert_pair.private_key = ZSTR_VAL(private_key);
  }
  if (cert_chain) {
    pem_key_cert_pair.cert_chain = ZSTR_VAL(cert_chain);
  }
  /* TODO: add a client_certificate_request field in ServerCredentials and pass
   * it as the last parameter. */
  grpc_server_credentials *creds =
    grpc_ssl_server_credentials_create_ex(
        pem_root_certs == NULL ? NULL :
        ZSTR_VAL(pem_root_certs),
        &pem_key_cert_pair, 1,
        GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, NULL);
  grpc_php_wrap_server_credentials(creds, return_value);
  RETURN_DESTROY_ZVAL(return_value);
}
コード例 #2
0
ファイル: timeval.c プロジェクト: mdhheydari/grpc-php7
/**
 * Adds another Timeval to this one and returns the sum. Calculations saturate
 * at infinities.
 * @param Timeval $other The other Timeval object to add
 * @return Timeval A new Timeval object containing the sum
 */
PHP_METHOD(Timeval, add) {
  zval *other_obj;

  /* "O" == 1 Object */
#ifndef FAST_ZPP
  if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &other_obj, grpc_ce_timeval)
      == FAILURE) {
    zend_throw_exception(spl_ce_InvalidArgumentException,
                         "add expects a Timeval", 1);
    return;
  }
#else
  ZEND_PARSE_PARAMETERS_START(1, 1)
    Z_PARAM_OBJECT_OF_CLASS(other_obj, grpc_ce_timeval)
  ZEND_PARSE_PARAMETERS_END();
#endif

  wrapped_grpc_timeval *self = Z_WRAPPED_GRPC_TIMEVAL_P(getThis());
  wrapped_grpc_timeval *other = Z_WRAPPED_GRPC_TIMEVAL_P(other_obj);
  grpc_php_wrap_timeval(gpr_time_add(self->wrapped, other->wrapped), return_value);
  RETURN_DESTROY_ZVAL(return_value);
}
コード例 #3
0
ファイル: call.c プロジェクト: sunzhijie/grpc-php7
/**
 * Start a batch of RPC actions.
 * @param array batch Array of actions to take
 * @return object Object with results of all actions
 */
PHP_METHOD(Call, startBatch) {
  wrapped_grpc_call *call = Z_WRAPPED_GRPC_CALL_P(getThis());
  grpc_op ops[8];
  size_t op_num = 0;
  zval *array;
  zval *value;
  zval *inner_value;
  HashTable *array_hash;
  HashPosition array_pointer;
  HashTable *status_hash;
  HashTable *message_hash;
  zval *message_value;
  zval *message_flags;
  zend_string *key;
  zend_ulong index;
  
  grpc_metadata_array metadata;
  grpc_metadata_array trailing_metadata;
  grpc_metadata_array recv_metadata;
  grpc_metadata_array recv_trailing_metadata;
  grpc_status_code status;
  char *status_details = NULL;
  size_t status_details_capacity = 0;
  grpc_byte_buffer *message;
  int cancelled;
  grpc_call_error error;
  char *message_str;
  size_t message_len;
  zval recv_status;
  
  grpc_metadata_array_init(&metadata);
  grpc_metadata_array_init(&trailing_metadata);
  grpc_metadata_array_init(&recv_metadata);
  grpc_metadata_array_init(&recv_trailing_metadata);
  object_init(return_value);
  
  /* "a" == 1 array */
#ifndef FAST_ZPP
  if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &array) == FAILURE) {
    zend_throw_exception(spl_ce_InvalidArgumentException,
                         "start_batch expects an array", 1);
    goto cleanup;
  }
#else
  ZEND_PARSE_PARAMETERS_START(1, 1)
    Z_PARAM_ARRAY(array)
  ZEND_PARSE_PARAMETERS_END();
#endif

  array_hash = HASH_OF(array);
  //TODO(thinkerou): why phpunit wrong when use ZEND_HASH_FOREACH_VAL marco?
  //ZEND_HASH_FOREACH_VAL(array_hash, value) {
  for (zend_hash_internal_pointer_reset_ex(array_hash, &array_pointer);
       (value = zend_hash_get_current_data_ex(array_hash,
                                              &array_pointer)) != NULL;
       zend_hash_move_forward_ex(array_hash, &array_pointer)) {
    if (zend_hash_get_current_key_ex(array_hash, &key, &index,
                                     &array_pointer) != HASH_KEY_IS_LONG) {
      zend_throw_exception(spl_ce_InvalidArgumentException,
                           "batch keys must be integers", 1);
      goto cleanup;
    }
    switch(index) {
      case GRPC_OP_SEND_INITIAL_METADATA:
        if (!create_metadata_array(value, &metadata)) {
          zend_throw_exception(spl_ce_InvalidArgumentException,
                               "Bad metadata value given", 1);
          goto cleanup;
        }
        ops[op_num].data.send_initial_metadata.count = metadata.count;
        ops[op_num].data.send_initial_metadata.metadata = metadata.metadata;
        break;
      case GRPC_OP_SEND_MESSAGE:
        if (Z_TYPE_P(value) != IS_ARRAY) {
          zend_throw_exception(spl_ce_InvalidArgumentException,
                               "Expected an array for send message", 1);
          goto cleanup;
        }
        message_hash = HASH_OF(value);
        if ((message_flags = zend_hash_str_find(message_hash, "flags",
                                                sizeof("flags") - 1)) != NULL) {
          if (Z_TYPE_P(message_flags) != IS_LONG) {
            zend_throw_exception(spl_ce_InvalidArgumentException,
                                 "Expected an int for message flags", 1);
          }
          ops[op_num].flags = Z_LVAL_P(message_flags) & GRPC_WRITE_USED_MASK;
        }
        if ((message_value = zend_hash_str_find(
            message_hash, "message", sizeof("message") - 1)) == NULL ||
            Z_TYPE_P(message_value) != IS_STRING) {
          zend_throw_exception(spl_ce_InvalidArgumentException,
                               "Expected a string for send message", 1);
          goto cleanup;
        }
        ops[op_num].data.send_message =
            string_to_byte_buffer(Z_STRVAL_P(message_value),
                                  Z_STRLEN_P(message_value));
        break;
      case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
        break;
      case GRPC_OP_SEND_STATUS_FROM_SERVER:
        status_hash = HASH_OF(value);
        if ((inner_value = zend_hash_str_find(
            status_hash, "metadata", sizeof("metadata") - 1)) != NULL) {
          if (!create_metadata_array(inner_value, &trailing_metadata)) {
            zend_throw_exception(spl_ce_InvalidArgumentException,
                                 "Bad trailing metadata value given", 1);
            goto cleanup;
          }
          ops[op_num].data.send_status_from_server.trailing_metadata =
              trailing_metadata.metadata;
          ops[op_num].data.send_status_from_server.trailing_metadata_count =
              trailing_metadata.count;
        }
        if ((inner_value = zend_hash_str_find(
            status_hash, "code", sizeof("code") - 1)) != NULL) {
          if (Z_TYPE_P(inner_value) != IS_LONG) {
            zend_throw_exception(spl_ce_InvalidArgumentException,
                                 "Status code must be an integer", 1);
            goto cleanup;
          }
          ops[op_num].data.send_status_from_server.status =
              Z_LVAL_P(inner_value);
        } else {
          zend_throw_exception(spl_ce_InvalidArgumentException,
                               "Integer status code is required", 1);
          goto cleanup;
        }
        if ((inner_value = zend_hash_str_find(
            status_hash, "details", sizeof("details") - 1)) != NULL) {
          if (Z_TYPE_P(inner_value) != IS_STRING) {
            zend_throw_exception(spl_ce_InvalidArgumentException,
                                 "Status details must be a string", 1);
            goto cleanup;
          }
          ops[op_num].data.send_status_from_server.status_details =
              Z_STRVAL_P(inner_value);
        } else {
          zend_throw_exception(spl_ce_InvalidArgumentException,
                               "String status details is required", 1);
          goto cleanup;
        }
        break;
      case GRPC_OP_RECV_INITIAL_METADATA:
        ops[op_num].data.recv_initial_metadata = &recv_metadata;
        break;
      case GRPC_OP_RECV_MESSAGE:
        ops[op_num].data.recv_message = &message;
        break;
      case GRPC_OP_RECV_STATUS_ON_CLIENT:
        ops[op_num].data.recv_status_on_client.trailing_metadata =
            &recv_trailing_metadata;
        ops[op_num].data.recv_status_on_client.status = &status;
        ops[op_num].data.recv_status_on_client.status_details =
            &status_details;
        ops[op_num].data.recv_status_on_client.status_details_capacity =
            &status_details_capacity;
        break;
      case GRPC_OP_RECV_CLOSE_ON_SERVER:
        ops[op_num].data.recv_close_on_server.cancelled = &cancelled;
        break;
      default:
        zend_throw_exception(spl_ce_InvalidArgumentException,
                             "Unrecognized key in batch", 1);
        goto cleanup;
    }
    ops[op_num].op = (grpc_op_type)index;
    ops[op_num].flags = 0;
    ops[op_num].reserved = NULL;
    op_num++;
  }
  //ZEND_HASH_FOREACH_END();

  error = grpc_call_start_batch(call->wrapped, ops, op_num,
                                call->wrapped, NULL);
  if (error != GRPC_CALL_OK) {
    zend_throw_exception(spl_ce_LogicException,
                         "start_batch was called incorrectly",
                         (long)error);
    goto cleanup;
  }
  grpc_completion_queue_pluck(completion_queue, call->wrapped,
                              gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
  for (int i = 0; i < op_num; i++) {
    switch(ops[i].op) {
      case GRPC_OP_SEND_INITIAL_METADATA:
        add_property_bool(return_value, "send_metadata", true);
        break;
      case GRPC_OP_SEND_MESSAGE:
        add_property_bool(return_value, "send_message", true);
        break;
      case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
        add_property_bool(return_value, "send_close", true);
        break;
      case GRPC_OP_SEND_STATUS_FROM_SERVER:
        add_property_bool(return_value, "send_status", true);
        break;
      case GRPC_OP_RECV_INITIAL_METADATA:
        grpc_parse_metadata_array(&recv_metadata, array);
        add_property_zval(return_value, "metadata", array);
        //Z_DELREF_P(array);
        break;
      case GRPC_OP_RECV_MESSAGE:
        byte_buffer_to_string(message, &message_str, &message_len);
        if (message_str == NULL) {
          add_property_null(return_value, "message");
        } else {
          add_property_stringl(return_value, "message", message_str, message_len);
        }
        break;
      case GRPC_OP_RECV_STATUS_ON_CLIENT:
        object_init(&recv_status);
        grpc_parse_metadata_array(&recv_trailing_metadata, array);
        add_property_zval(&recv_status, "metadata", array);
        //Z_DELREF_P(array);
        add_property_long(&recv_status, "code", status);
        add_property_string(&recv_status, "details", status_details);
        add_property_zval(return_value, "status", &recv_status);
        //Z_DELREF_P(&recv_status);
        break;
      case GRPC_OP_RECV_CLOSE_ON_SERVER:
        add_property_bool(return_value, "cancelled", cancelled);
        break;
      default:
        break;
    }
  }

cleanup:
  grpc_metadata_array_destroy(&metadata);
  grpc_metadata_array_destroy(&trailing_metadata);
  grpc_metadata_array_destroy(&recv_metadata);
  grpc_metadata_array_destroy(&recv_trailing_metadata);
  if (status_details != NULL) {
    gpr_free(status_details);
  }
  for (int i = 0; i < op_num; i++) {
    if (ops[i].op == GRPC_OP_SEND_MESSAGE) {
      grpc_byte_buffer_destroy(ops[i].data.send_message);
    }
    if (ops[i].op == GRPC_OP_RECV_MESSAGE) {
      grpc_byte_buffer_destroy(message);
    }
  }
  RETURN_DESTROY_ZVAL(return_value);
}
コード例 #4
0
ファイル: timeval.c プロジェクト: mdhheydari/grpc-php7
/**
 * Returns the infinite past time value as a timeval object
 * @return Timeval Infinite past time value
 */
PHP_METHOD(Timeval, infPast) {
  grpc_php_wrap_timeval(gpr_inf_past(GPR_CLOCK_REALTIME), return_value);
  RETURN_DESTROY_ZVAL(return_value);
}
コード例 #5
0
ファイル: timeval.c プロジェクト: mdhheydari/grpc-php7
/**
 * Returns the current time as a timeval object
 * @return Timeval The current time
 */
PHP_METHOD(Timeval, now) {
  grpc_php_wrap_timeval(gpr_now(GPR_CLOCK_REALTIME), return_value);
  RETURN_DESTROY_ZVAL(return_value);
}