mirror of
https://github.com/php/php-src.git
synced 2024-11-25 19:05:31 +08:00
Allowing user defined SOAP transports with SoapClient::__doRequest()
This commit is contained in:
parent
af2aa721df
commit
38ef28e41b
@ -186,11 +186,11 @@ static int in_domain(const char *host, const char *domain)
|
||||
}
|
||||
}
|
||||
|
||||
int send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *location, char *soapaction, int soap_version TSRMLS_DC)
|
||||
int send_http_soap_request(zval *this_ptr, char *buf, int buf_size, char *location, char *soapaction, int soap_version TSRMLS_DC)
|
||||
{
|
||||
xmlChar *buf, *request;
|
||||
char *request;
|
||||
smart_str soap_headers = {0};
|
||||
int buf_size, request_size, err;
|
||||
int request_size, err;
|
||||
php_url *phpurl = NULL;
|
||||
php_stream *stream;
|
||||
zval **trace, **tmp;
|
||||
@ -210,16 +210,6 @@ int send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *location, char *so
|
||||
stream = NULL;
|
||||
}
|
||||
|
||||
xmlDocDumpMemory(doc, &buf, &buf_size);
|
||||
if (!buf) {
|
||||
add_soap_fault(this_ptr, "HTTP", "Error build soap request", NULL, NULL TSRMLS_CC);
|
||||
return FALSE;
|
||||
}
|
||||
if (zend_hash_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace"), (void **) &trace) == SUCCESS &&
|
||||
Z_LVAL_PP(trace) > 0) {
|
||||
add_property_stringl(this_ptr, "__last_request", buf, buf_size, 1);
|
||||
}
|
||||
|
||||
if (location != NULL && location[0] != '\000') {
|
||||
phpurl = php_url_parse(location);
|
||||
}
|
||||
@ -494,7 +484,7 @@ int send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *location, char *so
|
||||
|
||||
}
|
||||
if (request != buf) {efree(request);}
|
||||
xmlFree(buf);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -790,10 +780,6 @@ int get_http_soap_response(zval *this_ptr, char **buffer, int *buffer_len TSRMLS
|
||||
*buffer = http_body;
|
||||
*buffer_len = http_body_size;
|
||||
}
|
||||
if (zend_hash_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace"), (void **) &trace) == SUCCESS &&
|
||||
Z_LVAL_PP(trace) > 0) {
|
||||
add_property_stringl(this_ptr, "__last_response", *buffer, *buffer_len, 1);
|
||||
}
|
||||
|
||||
efree(http_headers);
|
||||
return TRUE;
|
||||
|
@ -22,7 +22,7 @@
|
||||
#ifndef PHP_HTTP_H
|
||||
#define PHP_HTTP_H
|
||||
|
||||
int send_http_soap_request(zval *this_ptr, xmlDoc *doc, char *location, char *soapaction, int soap_version TSRMLS_DC);
|
||||
int send_http_soap_request(zval *this_ptr, char *request, int request_size, char *location, char *soapaction, int soap_version TSRMLS_DC);
|
||||
int get_http_soap_response(zval *this_ptr, char **buffer, int *buffer_len TSRMLS_DC);
|
||||
|
||||
#endif
|
||||
|
106
ext/soap/soap.c
106
ext/soap/soap.c
@ -234,6 +234,7 @@ PHP_METHOD(SoapClient, __getLastRequestHeaders);
|
||||
PHP_METHOD(SoapClient, __getLastResponseHeaders);
|
||||
PHP_METHOD(SoapClient, __getFunctions);
|
||||
PHP_METHOD(SoapClient, __getTypes);
|
||||
PHP_METHOD(SoapClient, __doRequest);
|
||||
|
||||
/* SoapVar Functions */
|
||||
PHP_METHOD(SoapVar, SoapVar);
|
||||
@ -303,6 +304,7 @@ static zend_function_entry soap_client_functions[] = {
|
||||
PHP_ME(SoapClient, __getLastResponseHeaders, NULL, 0)
|
||||
PHP_ME(SoapClient, __getFunctions, NULL, 0)
|
||||
PHP_ME(SoapClient, __getTypes, NULL, 0)
|
||||
PHP_ME(SoapClient, __doRequest, NULL, 0)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
@ -1313,7 +1315,7 @@ PHP_METHOD(SoapServer, handle)
|
||||
doc_request = soap_xmlParseMemory(arg,arg_len);
|
||||
}
|
||||
|
||||
if (doc_request == NULL) {
|
||||
if (doc_request == NULL) {
|
||||
soap_server_fault("Client", "Bad Request", NULL, NULL, NULL TSRMLS_CC);
|
||||
}
|
||||
if (xmlGetIntSubset(doc_request) != NULL) {
|
||||
@ -1914,6 +1916,52 @@ PHP_METHOD(SoapClient, SoapClient)
|
||||
SOAP_CLIENT_END_CODE();
|
||||
}
|
||||
|
||||
static int do_request(zval *this_ptr, xmlDoc *request, char *location, char *action, int version, zval *response TSRMLS_DC)
|
||||
{
|
||||
int ret = TRUE;
|
||||
char *buf;
|
||||
int buf_size;
|
||||
zval func;
|
||||
zval *params[4];
|
||||
zval **trace;
|
||||
|
||||
INIT_ZVAL(*response);
|
||||
|
||||
xmlDocDumpMemory(request, (xmlChar**)&buf, &buf_size);
|
||||
if (!buf) {
|
||||
add_soap_fault(this_ptr, "HTTP", "Error build soap request", NULL, NULL TSRMLS_CC);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (zend_hash_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace"), (void **) &trace) == SUCCESS &&
|
||||
Z_LVAL_PP(trace) > 0) {
|
||||
add_property_stringl(this_ptr, "__last_request", buf, buf_size, 1);
|
||||
}
|
||||
|
||||
INIT_ZVAL(func);
|
||||
ZVAL_STRINGL(&func,"__doRequest",sizeof("__doRequest")-1,0);
|
||||
ALLOC_INIT_ZVAL(params[0]);
|
||||
ZVAL_STRINGL(params[0], buf, buf_size, 0);
|
||||
ALLOC_INIT_ZVAL(params[1]);
|
||||
ZVAL_STRING(params[1], location, 0);
|
||||
ALLOC_INIT_ZVAL(params[2]);
|
||||
ZVAL_STRING(params[2], action, 0);
|
||||
ALLOC_INIT_ZVAL(params[3]);
|
||||
ZVAL_LONG(params[3], version);
|
||||
|
||||
if (call_user_function(NULL, &this_ptr, &func, response, 4, params TSRMLS_CC) != SUCCESS) {
|
||||
add_soap_fault(this_ptr, "Client", "SoapSlient::__doRequest() failed", NULL, NULL TSRMLS_CC);
|
||||
ret = FALSE;
|
||||
} else if (Z_TYPE_P(response) != IS_STRING) {
|
||||
ret = FALSE;
|
||||
} else if (zend_hash_find(Z_OBJPROP_P(this_ptr), "trace", sizeof("trace"), (void **) &trace) == SUCCESS &&
|
||||
Z_LVAL_PP(trace) > 0) {
|
||||
add_property_stringl(this_ptr, "__last_response", Z_STRVAL_P(response), Z_STRLEN_P(response), 1);
|
||||
}
|
||||
xmlFree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void do_soap_call(zval* this_ptr,
|
||||
char* function,
|
||||
int function_len,
|
||||
@ -1936,6 +1984,7 @@ static void do_soap_call(zval* this_ptr,
|
||||
int len;
|
||||
int ret = FALSE;
|
||||
int soap_version;
|
||||
zval response;
|
||||
|
||||
SOAP_CLIENT_BEGIN_CODE();
|
||||
|
||||
@ -1964,24 +2013,23 @@ static void do_soap_call(zval* this_ptr,
|
||||
fn = get_function(sdl, function);
|
||||
if (fn != NULL) {
|
||||
sdlBindingPtr binding = fn->binding;
|
||||
if (binding->bindingType == BINDING_SOAP) {
|
||||
sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)fn->bindingAttributes;
|
||||
if (binding->bindingType == BINDING_SOAP) {
|
||||
sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)fn->bindingAttributes;
|
||||
request = serialize_function_call(this_ptr, fn, NULL, fnb->input.ns, real_args, arg_count, soap_version, soap_headers TSRMLS_CC);
|
||||
ret = send_http_soap_request(this_ptr, request, binding->location, fnb->soapAction, soap_version TSRMLS_CC);
|
||||
ret = do_request(this_ptr, request, binding->location, fnb->soapAction, soap_version, &response TSRMLS_CC);
|
||||
} else {
|
||||
request = serialize_function_call(this_ptr, fn, NULL, sdl->target_ns, real_args, arg_count, soap_version, soap_headers TSRMLS_CC);
|
||||
ret = send_http_soap_request(this_ptr, request, binding->location, NULL, soap_version TSRMLS_CC);
|
||||
ret = do_request(this_ptr, request, binding->location, NULL, soap_version, &response TSRMLS_CC);
|
||||
}
|
||||
|
||||
xmlFreeDoc(request);
|
||||
xmlFreeDoc(request);
|
||||
|
||||
if (ret) {
|
||||
ret = get_http_soap_response(this_ptr, &buffer, &len TSRMLS_CC);
|
||||
if (ret) {
|
||||
parse_packet_soap(this_ptr, buffer, len, fn, NULL, return_value, output_headers TSRMLS_CC);
|
||||
efree(buffer);
|
||||
}
|
||||
if (ret && Z_TYPE(response) == IS_STRING) {
|
||||
ret = parse_packet_soap(this_ptr, Z_STRVAL(response), Z_STRLEN(response), fn, NULL, return_value, output_headers TSRMLS_CC);
|
||||
}
|
||||
|
||||
zval_dtor(&response);
|
||||
|
||||
} else {
|
||||
smart_str error = {0};
|
||||
smart_str_appends(&error,"Function (\"");
|
||||
@ -2014,18 +2062,16 @@ static void do_soap_call(zval* this_ptr,
|
||||
}
|
||||
smart_str_0(&action);
|
||||
|
||||
ret = send_http_soap_request(this_ptr, request, Z_STRVAL_PP(location), action.c, soap_version TSRMLS_CC);
|
||||
ret = do_request(this_ptr, request, Z_STRVAL_PP(location), action.c, soap_version, &response TSRMLS_CC);
|
||||
|
||||
smart_str_free(&action);
|
||||
xmlFreeDoc(request);
|
||||
|
||||
if (ret) {
|
||||
ret = get_http_soap_response(this_ptr, &buffer, &len TSRMLS_CC);
|
||||
if (ret) {
|
||||
ret = parse_packet_soap(this_ptr, buffer, len, NULL, function, return_value, output_headers TSRMLS_CC);
|
||||
efree(buffer);
|
||||
}
|
||||
if (ret && Z_TYPE(response) == IS_STRING) {
|
||||
ret = parse_packet_soap(this_ptr, Z_STRVAL(response), Z_STRLEN(response), NULL, function, return_value, output_headers TSRMLS_CC);
|
||||
}
|
||||
|
||||
zval_dtor(&response);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2232,6 +2278,28 @@ PHP_METHOD(SoapClient, __getLastResponseHeaders)
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
PHP_METHOD(SoapClient, __doRequest)
|
||||
{
|
||||
char *buf, *location, *action;
|
||||
int buf_size, location_size, action_size;
|
||||
long version;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sssl",
|
||||
&buf, &buf_size,
|
||||
&location, &location_size,
|
||||
&action, &action_size,
|
||||
&version) == FAILURE) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR, "wrong parameters");
|
||||
}
|
||||
if (send_http_soap_request(this_ptr, buf, buf_size, location, action, version TSRMLS_CC)) {
|
||||
if (get_http_soap_response(this_ptr, &Z_STRVAL_P(return_value), &Z_STRLEN_P(return_value) TSRMLS_CC)) {
|
||||
return_value->type = IS_STRING;
|
||||
return;
|
||||
}
|
||||
}
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
#ifndef ZEND_ENGINE_2
|
||||
static void soap_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference)
|
||||
{
|
||||
|
36
ext/soap/tests/transport001.phpt
Normal file
36
ext/soap/tests/transport001.phpt
Normal file
@ -0,0 +1,36 @@
|
||||
--TEST--
|
||||
SOAP Transport 1: Local transport using SoapClient::__doRequest
|
||||
--SKIPIF--
|
||||
<?php require_once('skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
function Add($x,$y) {
|
||||
return $x+$y;
|
||||
}
|
||||
|
||||
class LocalSoapClient extends SoapClient {
|
||||
|
||||
function LocalSoapClient($wsdl, $options) {
|
||||
$this->SoapClient($wsdl, $options);
|
||||
$this->server = new SoapServer($wsdl, $options);
|
||||
$this->server->addFunction('Add');
|
||||
}
|
||||
|
||||
function __doRequest($request, $location, $action, $version) {
|
||||
ob_start();
|
||||
$this->server->handle($request);
|
||||
$response = ob_get_contents();
|
||||
ob_end_clean();
|
||||
return $response;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$x = new LocalSoapClient(NULL,array('location'=>'test://',
|
||||
'uri'=>'http://testuri.org'));
|
||||
var_dump($x->Add(3,4));
|
||||
echo "ok\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
int(7)
|
||||
ok
|
Loading…
Reference in New Issue
Block a user