Exemple #1
0
/**
 * override __call()
 * it require two parameters, func_name and args
 **/
PHP_METHOD(McpackHessianClient, __call) {
	zend_class_entry *ce;
	zval *p_this, *args, *params, *result, *method, *tmp;
	char *func_name, *ret_str = NULL;
	int func_name_len = 0;
	size_t return_len = 0, max_len = 1024 * 1024 * 1024;

	p_this = getThis();
	if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, p_this, 
		"Osz", &ce, mcphessian_ce_ptr, &func_name, &func_name_len, &args) == FAILURE) {
		php_error(E_WARNING, "parse parameters error.");
		RETURN_NULL();
	}

	// init params
	MAKE_STD_ZVAL(params);
	array_init(params);
	add_assoc_string(params, "jsonrpc", "2.0", 0);
	add_assoc_string(params, "method", func_name, 0);
	add_assoc_zval(params, "params", args);
	add_assoc_string(params, "id", "123456", 0);
	zval *pack = array2mcpack(params);

	// post data
	zval *z_url = zend_read_property(mcphessian_ce_ptr, p_this, ZEND_STRL("url"), 1 TSRMLS_CC);
	convert_to_string(z_url);
	char *url = Z_STRVAL_P(z_url);
	php_stream_context *context = php_stream_context_alloc();
	MAKE_STD_ZVAL(method);
	ZVAL_STRING(method, "POST", 0);
	php_stream_context_set_option(context, "http", "method", method);
	php_stream_context_set_option(context, "http", "content", pack);

	// read data from stream
	php_stream *stream = php_stream_open_wrapper_ex(url, "rb", REPORT_ERRORS, NULL, context);
	if (stream) {
		ret_str = php_stream_get_line(stream, NULL, max_len, &return_len);
	} else {
		php_error(E_WARNING, "failed to open stream %s.", url);
		RETURN_NULL();
	}
	MAKE_STD_ZVAL(tmp);
	ZVAL_STRINGL(tmp, ret_str, return_len, 0);
	result = mcpack2array(tmp);
	php_stream_close(stream);
	efree(ret_str);

	// get result from array
	zval **ret_val;
	if (zend_hash_exists(Z_ARRVAL_P(result), "result", 7)) {
		zend_hash_find(Z_ARRVAL_P(result), "result", 7, (void **)&ret_val);
		RETURN_ZVAL(*ret_val, 1, 0);
	} else {
		php_error(E_WARNING, "return value illegal.");
		RETURN_NULL();
	}
}
Exemple #2
0
/* {{{ mysqlnd_vio::enable_ssl */
static enum_func_status
MYSQLND_METHOD(mysqlnd_vio, enable_ssl)(MYSQLND_VIO * const net)
{
#ifdef MYSQLND_SSL_SUPPORTED
	php_stream_context * context = php_stream_context_alloc();
	php_stream * net_stream = net->data->m.get_stream(net);
	zend_bool any_flag = FALSE;

	DBG_ENTER("mysqlnd_vio::enable_ssl");
	if (!context) {
		DBG_RETURN(FAIL);
	}

	if (net->data->options.ssl_key) {
		zval key_zval;
		ZVAL_STRING(&key_zval, net->data->options.ssl_key);
		php_stream_context_set_option(context, "ssl", "local_pk", &key_zval);
		zval_ptr_dtor(&key_zval);
		any_flag = TRUE;
	}
	if (net->data->options.ssl_cert) {
		zval cert_zval;
		ZVAL_STRING(&cert_zval, net->data->options.ssl_cert);
		php_stream_context_set_option(context, "ssl", "local_cert", &cert_zval);
		if (!net->data->options.ssl_key) {
			php_stream_context_set_option(context, "ssl", "local_pk", &cert_zval);
		}
		zval_ptr_dtor(&cert_zval);
		any_flag = TRUE;
	}
	if (net->data->options.ssl_ca) {
		zval cafile_zval;
		ZVAL_STRING(&cafile_zval, net->data->options.ssl_ca);
		php_stream_context_set_option(context, "ssl", "cafile", &cafile_zval);
		any_flag = TRUE;
	}
	if (net->data->options.ssl_capath) {
		zval capath_zval;
		ZVAL_STRING(&capath_zval, net->data->options.ssl_capath);
		php_stream_context_set_option(context, "ssl", "capath", &capath_zval);
		zval_ptr_dtor(&capath_zval);
		any_flag = TRUE;
	}
	if (net->data->options.ssl_passphrase) {
		zval passphrase_zval;
		ZVAL_STRING(&passphrase_zval, net->data->options.ssl_passphrase);
		php_stream_context_set_option(context, "ssl", "passphrase", &passphrase_zval);
		zval_ptr_dtor(&passphrase_zval);
		any_flag = TRUE;
	}
	if (net->data->options.ssl_cipher) {
		zval cipher_zval;
		ZVAL_STRING(&cipher_zval, net->data->options.ssl_cipher);
		php_stream_context_set_option(context, "ssl", "ciphers", &cipher_zval);
		zval_ptr_dtor(&cipher_zval);
		any_flag = TRUE;
	}
	{
		zval verify_peer_zval;
		zend_bool verify;

		if (net->data->options.ssl_verify_peer == MYSQLND_SSL_PEER_DEFAULT) {
			net->data->options.ssl_verify_peer = any_flag? MYSQLND_SSL_PEER_DEFAULT_ACTION:MYSQLND_SSL_PEER_DONT_VERIFY;
		}

		verify = net->data->options.ssl_verify_peer == MYSQLND_SSL_PEER_VERIFY? TRUE:FALSE;

		DBG_INF_FMT("VERIFY=%d", verify);
		ZVAL_BOOL(&verify_peer_zval, verify);
		php_stream_context_set_option(context, "ssl", "verify_peer", &verify_peer_zval);
		php_stream_context_set_option(context, "ssl", "verify_peer_name", &verify_peer_zval);
		if (net->data->options.ssl_verify_peer == MYSQLND_SSL_PEER_DONT_VERIFY) {
			ZVAL_TRUE(&verify_peer_zval);
			php_stream_context_set_option(context, "ssl", "allow_self_signed", &verify_peer_zval);
		}
	}
#if PHP_API_VERSION >= 20131106
	php_stream_context_set(net_stream, context);
#else
	php_stream_context_set(net_stream, context);
#endif
	if (php_stream_xport_crypto_setup(net_stream, STREAM_CRYPTO_METHOD_TLS_CLIENT, NULL) < 0 ||
	    php_stream_xport_crypto_enable(net_stream, 1) < 0)
	{
		DBG_ERR("Cannot connect to MySQL by using SSL");
		php_error_docref(NULL, E_WARNING, "Cannot connect to MySQL by using SSL");
		DBG_RETURN(FAIL);
	}
	net->data->ssl = TRUE;
	/*
	  get rid of the context. we are persistent and if this is a real pconn used by mysql/mysqli,
	  then the context would not survive cleaning of EG(regular_list), where it is registered, as a
	  resource. What happens is that after this destruction any use of the network will mean usage
	  of the context, which means usage of already freed memory, bad. Actually we don't need this
	  context anymore after we have enabled SSL on the connection. Thus it is very simple, we remove it.
	*/
#if PHP_API_VERSION >= 20131106
	php_stream_context_set(net_stream, NULL);
#else
	php_stream_context_set(net_stream, NULL);
#endif

	if (net->data->options.timeout_read) {
		struct timeval tv;
		DBG_INF_FMT("setting %u as PHP_STREAM_OPTION_READ_TIMEOUT", net->data->options.timeout_read);
		tv.tv_sec = net->data->options.timeout_read;
		tv.tv_usec = 0;
		php_stream_set_option(net_stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &tv);
	}

	DBG_RETURN(PASS);
#else
	DBG_ENTER("mysqlnd_vio::enable_ssl");
	DBG_INF("MYSQLND_SSL_SUPPORTED is not defined");
	DBG_RETURN(PASS);
#endif
}