WSDL caching was implemented

This commit is contained in:
Dmitry Stogov 2004-02-10 13:41:21 +00:00
parent 6529000fff
commit 20add786ae
9 changed files with 1232 additions and 107 deletions

View File

@ -3,7 +3,7 @@ General
- make sure soapserver.map(), soap_encode_to_xml() and soap_encode_to_zval() are really need
- reimplement SoapObject::__getfunctions() and SoapObject::__gettypes()
to return structures instead of strings
- memory leaks (libxml and WSDL/Schema use malloc to cache WSDL)
? memory leaks (libxml and WSDL/Schema use malloc to cache WSDL)
- error handling???
SOAP
@ -57,7 +57,7 @@ WSDL
- support for <opperation> <fault>
? server part support for "document" style encoding
- function/method overloading/redeclaration (test(int); test(string))
- wsdl caching
+ wsdl caching
- wsdl auto generation
? SOAP binding
- <soap:body> parts attribute

View File

@ -826,7 +826,7 @@ static void model_to_zval_object(zval *ret, sdlContentModelPtr model, xmlNodePtr
}
}
case XSD_CONTENT_GROUP:
model_to_zval_object(ret, model->u.group, data, sdl TSRMLS_CC);
model_to_zval_object(ret, model->u.group->model, data, sdl TSRMLS_CC);
default:
break;
}
@ -1023,7 +1023,7 @@ static int model_to_xml_object(xmlNodePtr node, sdlContentModelPtr model, HashTa
return 0;
}
case XSD_CONTENT_GROUP: {
return model_to_xml_object(node, model->u.group, prop, style, model->min_occurs > 0);
return model_to_xml_object(node, model->u.group->model, prop, style, model->min_occurs > 0);
}
default:
break;
@ -1555,7 +1555,7 @@ static zval *to_zval_array(encodeTypePtr type, xmlNodePtr data)
int dimension = 1;
int* dims = NULL;
int* pos = NULL;
xmlAttrPtr attr;
xmlAttrPtr attr;
sdlPtr sdl;
sdlAttributePtr *arrayType;
sdlExtraAttributePtr *ext;

View File

@ -240,63 +240,66 @@ int parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunction
char *name, *ns = NULL;
zval* tmp;
sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)fn->bindingAttributes;
int res_count = zend_hash_num_elements(fn->responseParameters);
int res_count;
hdrs = fnb->output.headers;
zend_hash_internal_pointer_reset(fn->responseParameters);
while (zend_hash_get_current_data(fn->responseParameters, (void **)&h_param) == SUCCESS) {
param = (*h_param);
if (fnb->style == SOAP_DOCUMENT) {
name = param->encode->details.type_str;
ns = param->encode->details.ns;
} else {
name = fn->responseName;
/* ns = ? */
}
/* Get value of parameter */
cur = get_node_ex(resp, name, ns);
if (!cur) {
cur = get_node(resp, name);
/* TODO: produce warning invalid ns */
}
if (cur) {
if (fn->responseParameters) {
res_count = zend_hash_num_elements(fn->responseParameters);
zend_hash_internal_pointer_reset(fn->responseParameters);
while (zend_hash_get_current_data(fn->responseParameters, (void **)&h_param) == SUCCESS) {
param = (*h_param);
if (fnb->style == SOAP_DOCUMENT) {
val = cur;
name = param->encode->details.type_str;
ns = param->encode->details.ns;
} else {
val = get_node(cur->children, param->paramName);
if (val == NULL && res_count == 1) {
val = get_node(cur->children, "return");
}
if (val == NULL && res_count == 1) {
val = get_node(cur->children, "result");
name = fn->responseName;
/* ns = ? */
}
/* Get value of parameter */
cur = get_node_ex(resp, name, ns);
if (!cur) {
cur = get_node(resp, name);
/* TODO: produce warning invalid ns */
}
if (cur) {
if (fnb->style == SOAP_DOCUMENT) {
val = cur;
} else {
val = get_node(cur->children, param->paramName);
if (val == NULL && res_count == 1) {
val = get_node(cur->children, "return");
}
if (val == NULL && res_count == 1) {
val = get_node(cur->children, "result");
}
}
}
}
if (!val) {
/* TODO: may be "nil" is not OK? */
MAKE_STD_ZVAL(tmp);
ZVAL_NULL(tmp);
if (!val) {
/* TODO: may be "nil" is not OK? */
MAKE_STD_ZVAL(tmp);
ZVAL_NULL(tmp);
/*
add_soap_fault(this_ptr, "Client", "Can't find response data", NULL, NULL TSRMLS_CC);
xmlFreeDoc(response);
return FALSE;
add_soap_fault(this_ptr, "Client", "Can't find response data", NULL, NULL TSRMLS_CC);
xmlFreeDoc(response);
return FALSE;
*/
} else {
/* Decoding value of parameter */
if (param != NULL) {
tmp = master_to_zval(param->encode, val);
} else {
tmp = master_to_zval(NULL, val);
/* Decoding value of parameter */
if (param != NULL) {
tmp = master_to_zval(param->encode, val);
} else {
tmp = master_to_zval(NULL, val);
}
}
add_assoc_zval(return_value, param->paramName, tmp);
param_count++;
zend_hash_move_forward(fn->responseParameters);
}
add_assoc_zval(return_value, param->paramName, tmp);
param_count++;
zend_hash_move_forward(fn->responseParameters);
}
} else {
/* Function hasn't WSDL description */

View File

@ -46,13 +46,6 @@ static int schema_restriction_var_char(xmlNodePtr val, sdlRestrictionCharPtr *va
static void schema_type_fixup(sdlCtx *ctx, sdlTypePtr type);
static void delete_model(void *handle);
static void delete_type(void *data);
static void delete_extra_attribute(void *attribute);
static void delete_attribute(void *attribute);
static void delete_restriction_var_int(void *rvi);
static void delete_schema_restriction_var_char(void *srvc);
static encodePtr create_encoder(sdlPtr sdl, sdlTypePtr cur_type, const char *ns, const char *type)
{
smart_str nscat = {0};
@ -697,7 +690,7 @@ static int schema_restriction_simpleContent(sdlPtr sdl, xmlAttrPtr tsn, xmlNodeP
schema_restriction_var_char(trav, &enumval);
if (cur_type->restrictions->enumeration == NULL) {
cur_type->restrictions->enumeration = sdl_malloc(sizeof(HashTable));
zend_hash_init(cur_type->restrictions->enumeration, 0, NULL, delete_schema_restriction_var_char, SDL_PERSISTENT);
zend_hash_init(cur_type->restrictions->enumeration, 0, NULL, delete_restriction_var_char, SDL_PERSISTENT);
}
zend_hash_add(cur_type->restrictions->enumeration, enumval->value, strlen(enumval->value)+1, &enumval, sizeof(sdlRestrictionCharPtr), NULL);
} else {
@ -2113,7 +2106,7 @@ static void schema_content_model_fixup(sdlCtx *ctx, sdlContentModelPtr model)
schema_type_fixup(ctx,*tmp);
efree(model->u.group_ref);
model->kind = XSD_CONTENT_GROUP;
model->u.group = (*tmp)->model;
model->u.group = (*tmp);
} else {
php_error(E_ERROR, "SOAP-ERROR: Parsing Schema: unresolved group 'ref' attribute");
}
@ -2231,7 +2224,7 @@ void schema_pass2(sdlCtx *ctx)
}
}
static void delete_model(void *handle)
void delete_model(void *handle)
{
sdlContentModelPtr tmp = *((sdlContentModelPtr*)handle);
switch (tmp->kind) {
@ -2251,7 +2244,7 @@ static void delete_model(void *handle)
sdl_free(tmp);
}
static void delete_type(void *data)
void delete_type(void *data)
{
sdlTypePtr type = *((sdlTypePtr*)data);
if (type->name) {
@ -2287,8 +2280,8 @@ static void delete_type(void *data)
delete_restriction_var_int(&type->restrictions->length);
delete_restriction_var_int(&type->restrictions->minLength);
delete_restriction_var_int(&type->restrictions->maxLength);
delete_schema_restriction_var_char(&type->restrictions->whiteSpace);
delete_schema_restriction_var_char(&type->restrictions->pattern);
delete_restriction_var_char(&type->restrictions->whiteSpace);
delete_restriction_var_char(&type->restrictions->pattern);
if (type->restrictions->enumeration) {
zend_hash_destroy(type->restrictions->enumeration);
sdl_free(type->restrictions->enumeration);
@ -2298,7 +2291,7 @@ static void delete_type(void *data)
sdl_free(type);
}
static void delete_extra_attribute(void *attribute)
void delete_extra_attribute(void *attribute)
{
sdlExtraAttributePtr attr = *((sdlExtraAttributePtr*)attribute);
@ -2311,7 +2304,7 @@ static void delete_extra_attribute(void *attribute)
sdl_free(attr);
}
static void delete_attribute(void *attribute)
void delete_attribute(void *attribute)
{
sdlAttributePtr attr = *((sdlAttributePtr*)attribute);
@ -2334,7 +2327,7 @@ static void delete_attribute(void *attribute)
sdl_free(attr);
}
static void delete_restriction_var_int(void *rvi)
void delete_restriction_var_int(void *rvi)
{
sdlRestrictionIntPtr ptr = *((sdlRestrictionIntPtr*)rvi);
if (ptr) {
@ -2342,7 +2335,7 @@ static void delete_restriction_var_int(void *rvi)
}
}
static void delete_schema_restriction_var_char(void *srvc)
void delete_restriction_var_char(void *srvc)
{
sdlRestrictionCharPtr ptr = *((sdlRestrictionCharPtr*)srvc);
if (ptr) {

View File

@ -25,4 +25,10 @@
int load_schema(sdlCtx *ctx, xmlNodePtr schema);
void schema_pass2(sdlCtx *ctx);
void delete_model(void *handle);
void delete_type(void *data);
void delete_extra_attribute(void *attribute);
void delete_attribute(void *attribute);
void delete_restriction_var_int(void *rvi);
void delete_restriction_var_char(void *srvc);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -38,14 +38,20 @@
#define XSD_WHITESPACE_PRESERVE 1
#define XSD_WHITESPACE_REPLACE 1
#define BINDING_SOAP 1
#define BINDING_HTTP 2
typedef enum _sdlBindingType {
BINDING_SOAP = 1,
BINDING_HTTP = 2
} sdlBindingType;
#define SOAP_RPC 1
#define SOAP_DOCUMENT 2
typedef enum _sdlEncodingStyle {
SOAP_RPC = 1,
SOAP_DOCUMENT = 2
} sdlEncodingStyle;
#define SOAP_ENCODED 1
#define SOAP_LITERAL 2
typedef enum _sdlEncodingUse {
SOAP_ENCODED = 1,
SOAP_LITERAL = 2
} sdlEncodingUse;
struct _sdl {
HashTable functions; /* array of sdlFunction */
@ -74,42 +80,42 @@ typedef struct sdlCtx {
} sdlCtx;
struct _sdlBinding {
char *name;
char *location;
int bindingType;
void *bindingAttributes; /* sdlSoapBindingPtr */
char *name;
char *location;
sdlBindingType bindingType;
void *bindingAttributes; /* sdlSoapBindingPtr */
};
/* Soap Binding Specfic stuff */
struct _sdlSoapBinding {
char *transport;
int style;
char *transport;
sdlEncodingStyle style;
};
typedef struct _sdlSoapBindingFunctionHeader {
char *name;
char *ns;
int use;
sdlTypePtr element;
encodePtr encode;
char *encodingStyle; /* not implemented yet */
char *name;
char *ns;
sdlEncodingUse use;
sdlTypePtr element;
encodePtr encode;
char *encodingStyle; /* not implemented yet */
} sdlSoapBindingFunctionHeader, *sdlSoapBindingFunctionHeaderPtr;
struct _sdlSoapBindingFunctionBody {
char *ns;
int use;
char *parts; /* not implemented yet */
char *encodingStyle; /* not implemented yet */
HashTable *headers; /* array of sdlSoapBindingFunctionHeaderPtr */
char *ns;
sdlEncodingUse use;
char *parts; /* not implemented yet */
char *encodingStyle; /* not implemented yet */
HashTable *headers; /* array of sdlSoapBindingFunctionHeaderPtr */
};
struct _sdlSoapBindingFunction {
char *soapAction;
int style;
char *soapAction;
sdlEncodingStyle style;
sdlSoapBindingFunctionBody input;
sdlSoapBindingFunctionBody output;
sdlSoapBindingFunctionBody falut;
sdlSoapBindingFunctionBody input;
sdlSoapBindingFunctionBody output;
sdlSoapBindingFunctionBody fault;
};
struct _sdlRestrictionInt {
@ -155,7 +161,7 @@ struct _sdlContentModel {
int max_occurs;
union {
sdlTypePtr element; /* pointer to element */
sdlContentModelPtr group; /* pointer to group */
sdlTypePtr group; /* pointer to group */
HashTable *content; /* array of sdlContentModel for sequnce,all,choice*/
char *group_ref; /* reference to group */
} u;
@ -174,7 +180,7 @@ struct _sdlType {
sdlTypeKind kind;
char *name;
char *namens;
int nillable;
char nillable;
HashTable *elements; /* array of sdlTypePtr */
HashTable *attributes; /* array of sdlAttributePtr */
sdlRestrictionsPtr restrictions;
@ -231,7 +237,7 @@ struct _sdlAttribute {
encodePtr encode;
};
sdlPtr get_sdl(char *uri);
sdlPtr get_sdl(char *uri TSRMLS_DC);
encodePtr get_encoder_from_prefix(sdlPtr sdl, xmlNodePtr data, const char *type);
encodePtr get_encoder(sdlPtr sdl, const char *ns, const char *type);

View File

@ -148,6 +148,9 @@ ZEND_BEGIN_MODULE_GLOBALS(soap)
int soap_version;
sdlPtr sdl;
zend_bool use_soap_error_handler;
zend_bool cache_enabled;
char* cache_dir;
long cache_ttl;
ZEND_END_MODULE_GLOBALS(soap)
#ifdef PHP_WIN32

View File

@ -278,6 +278,20 @@ zend_module_entry soap_module_entry = {
ZEND_GET_MODULE(soap)
#endif
PHP_INI_BEGIN()
STD_PHP_INI_ENTRY("soap.wsdl_cache_enabled", "1", PHP_INI_ALL, OnUpdateBool,
cache_enabled, zend_soap_globals, soap_globals)
STD_PHP_INI_ENTRY("soap.wsdl_cache_dir", "/tmp", PHP_INI_ALL, OnUpdateString,
cache_dir, zend_soap_globals, soap_globals)
#ifdef ZEND_ENGINE_2
STD_PHP_INI_ENTRY("soap.wsdl_cache_ttl", "86400", PHP_INI_ALL, OnUpdateLong,
cache_ttl, zend_soap_globals, soap_globals)
#else
STD_PHP_INI_ENTRY("soap.wsdl_cache_ttl", "86400", PHP_INI_ALL, OnUpdateInt,
cache_ttl, zend_soap_globals, soap_globals)
#endif
PHP_INI_END()
static void php_soap_init_globals(zend_soap_globals *soap_globals)
{
int i;
@ -343,6 +357,7 @@ PHP_MINIT_FUNCTION(soap)
/* TODO: add ini entry for always use soap errors */
ZEND_INIT_MODULE_GLOBALS(soap, php_soap_init_globals, NULL);
REGISTER_INI_ENTRIES();
#ifndef ZEND_ENGINE_2
/* Enable php stream/wrapper support for libxml */
@ -489,6 +504,7 @@ PHP_MINFO_FUNCTION(soap)
php_info_print_table_row(2, "Soap Client", "enabled");
php_info_print_table_row(2, "Soap Server", "enabled");
php_info_print_table_end();
DISPLAY_INI_ENTRIES();
}
#ifdef HAVE_PHP_DOMXML
@ -695,7 +711,7 @@ PHP_METHOD(soapserver,soapserver)
zend_hash_init(service->soap_functions.ft, 0, NULL, ZVAL_PTR_DTOR, 0);
if (wsdl) {
service->sdl = get_sdl(Z_STRVAL_P(wsdl));
service->sdl = get_sdl(Z_STRVAL_P(wsdl) TSRMLS_CC);
if (service->uri == NULL) {
if (service->sdl->target_ns) {
service->uri = estrdup(service->sdl->target_ns);
@ -1130,6 +1146,7 @@ PHP_METHOD(soapserver, handle)
php_error(E_ERROR, "PHP-SOAP requires 'always_populate_raw_post_data' to be on please check your php.ini file");
}
php_error(E_ERROR, "Can't find HTTP_RAW_POST_DATA");
return;
}
} else {
doc_request = soap_xmlParseMemory(arg,arg_len);
@ -1577,7 +1594,7 @@ PHP_METHOD(soapclient, soapclient)
old_soap_version = SOAP_GLOBAL(soap_version);
SOAP_GLOBAL(soap_version) = soap_version;
sdl = get_sdl(Z_STRVAL_P(wsdl));
sdl = get_sdl(Z_STRVAL_P(wsdl) TSRMLS_CC);
ret = zend_list_insert(sdl, le_sdl);
add_property_resource(this_ptr, "sdl", ret);