dmitry          Thu Feb 19 03:21:15 2004 EDT

  Modified files:              
    /php-src/ext/soap   TODO php_sdl.c php_sdl.h soap.c 
  Log:
  Support for SOAP Fault encoding according to WSDL <fault> and <soap:fault>
  
  
http://cvs.php.net/diff.php/php-src/ext/soap/TODO?r1=1.44&r2=1.45&ty=u
Index: php-src/ext/soap/TODO
diff -u php-src/ext/soap/TODO:1.44 php-src/ext/soap/TODO:1.45
--- php-src/ext/soap/TODO:1.44  Fri Feb 13 10:19:09 2004
+++ php-src/ext/soap/TODO       Thu Feb 19 03:21:12 2004
@@ -49,11 +49,12 @@
 WSDL
 ----
 ? server part support for "document" style encoding
+? support for <fault>, <soap:fault>
+- <soap:headerfault>
 - <soap:body> parts attribute (with MIME/DIME binding)
 - MIME binding
 - DIME binding
 - support for portType/operation parameterOrder attribute
-- support for <fault>, <soap:fault>, <soap:headerfault>
 - support for binding operation input/output name attribute (part of overloading)
 - function/method overloading/redeclaration (test(int); test(string))
 - wsdl auto generation
http://cvs.php.net/diff.php/php-src/ext/soap/php_sdl.c?r1=1.62&r2=1.63&ty=u
Index: php-src/ext/soap/php_sdl.c
diff -u php-src/ext/soap/php_sdl.c:1.62 php-src/ext/soap/php_sdl.c:1.63
--- php-src/ext/soap/php_sdl.c:1.62     Tue Feb 17 10:10:16 2004
+++ php-src/ext/soap/php_sdl.c  Thu Feb 19 03:21:12 2004
@@ -17,7 +17,7 @@
   |          Dmitry Stogov <[EMAIL PROTECTED]>                             |
   +----------------------------------------------------------------------+
 */
-/* $Id: php_sdl.c,v 1.62 2004/02/17 15:10:16 dmitry Exp $ */
+/* $Id: php_sdl.c,v 1.63 2004/02/19 08:21:12 dmitry Exp $ */
 
 #include "php_soap.h"
 #include "libxml/uri.h"
@@ -33,6 +33,7 @@
 # define O_BINARY 0
 #endif
 
+static void delete_fault(void *fault);
 static void delete_binding(void *binding);
 static void delete_function(void *function);
 static void delete_parameter(void *paramater);
@@ -344,14 +345,16 @@
 
                        if (binding->use == SOAP_ENCODED) {
                                tmp = get_attribute(body->properties, "encodingStyle");
-                               if (tmp &&
-                                   
strncmp(tmp->children->content,SOAP_1_1_ENC_NAMESPACE,sizeof(SOAP_1_1_ENC_NAMESPACE)) 
!= 0 &&
-                                 
strncmp(tmp->children->content,SOAP_1_2_ENC_NAMESPACE,sizeof(SOAP_1_2_ENC_NAMESPACE)) 
!= 0) {
-                                       php_error(E_ERROR, "SOAP-ERROR: Parsing WSDL: 
Unknown encodingStyle '%s'",tmp->children->content);
-                               } else if (tmp == NULL) {
-                                       php_error(E_ERROR, "SOAP-ERROR: Parsing WSDL: 
Unspecified encodingStyle");
+                               if (tmp) {
+                                       if 
(strncmp(tmp->children->content,SOAP_1_1_ENC_NAMESPACE,sizeof(SOAP_1_1_ENC_NAMESPACE)) 
== 0) {
+                                               binding->encodingStyle = 
SOAP_ENCODING_1_1;
+                                       } else if 
(strncmp(tmp->children->content,SOAP_1_2_ENC_NAMESPACE,sizeof(SOAP_1_2_ENC_NAMESPACE)) 
== 0) {
+                                               binding->encodingStyle = 
SOAP_ENCODING_1_2;
+                                       } else {
+                                               php_error(E_ERROR, "SOAP-ERROR: 
Parsing WSDL: Unknown encodingStyle '%s'",tmp->children->content);
+                                       }
                                } else {
-                                       binding->encodingStyle = 
estrdup(tmp->children->content);
+                                       php_error(E_ERROR, "SOAP-ERROR: Parsing WSDL: 
Unspecified encodingStyle");
                                }
                        }
                } else if (node_is_equal_ex(trav, "header", wsdl_soap_namespace)) {
@@ -404,14 +407,16 @@
 
                        if (h->use == SOAP_ENCODED) {
                                tmp = get_attribute(header->properties, 
"encodingStyle");
-                               if (tmp &&
-                                   
strncmp(tmp->children->content,SOAP_1_1_ENC_NAMESPACE,sizeof(SOAP_1_1_ENC_NAMESPACE)) 
!= 0 &&
-                                   
strncmp(tmp->children->content,SOAP_1_2_ENC_NAMESPACE,sizeof(SOAP_1_2_ENC_NAMESPACE)) 
!= 0) {
-                                       php_error(E_ERROR, "SOAP-ERROR: Parsing WSDL: 
Unknown encodingStyle '%s'",tmp->children->content);
-                               } else if (tmp == NULL) {
-                                       php_error(E_ERROR, "SOAP-ERROR: Parsing WSDL: 
Unspecified encodingStyle");
+                               if (tmp) {
+                                       if 
(strncmp(tmp->children->content,SOAP_1_1_ENC_NAMESPACE,sizeof(SOAP_1_1_ENC_NAMESPACE)) 
== 0) {
+                                               h->encodingStyle = SOAP_ENCODING_1_1;
+                                       } else if 
(strncmp(tmp->children->content,SOAP_1_2_ENC_NAMESPACE,sizeof(SOAP_1_2_ENC_NAMESPACE)) 
== 0) {
+                                               h->encodingStyle = SOAP_ENCODING_1_2;
+                                       } else {
+                                               php_error(E_ERROR, "SOAP-ERROR: 
Parsing WSDL: Unknown encodingStyle '%s'",tmp->children->content);
+                                       }
                                } else {
-                                       h->encodingStyle = 
estrdup(tmp->children->content);
+                                       php_error(E_ERROR, "SOAP-ERROR: Parsing WSDL: 
Unspecified encodingStyle");
                                }
                        }
 
@@ -647,10 +652,11 @@
 
                                                tmp = 
get_attribute(soapBindingNode->properties, "transport");
                                                if (tmp) {
-                                                       if 
(strncmp(tmp->children->content, WSDL_HTTP_TRANSPORT, sizeof(WSDL_HTTP_TRANSPORT))) {
+                                                       if 
(strncmp(tmp->children->content, WSDL_HTTP_TRANSPORT, sizeof(WSDL_HTTP_TRANSPORT)) == 
0) {
+                                                               soapBinding->transport 
= SOAP_TRANSPORT_HTTP;
+                                                       } else {
                                                                php_error(E_ERROR, 
"SOAP-ERROR: Parsing WSDL: PHP-SOAP doesn't support transport '%s'", 
tmp->children->content);
                                                        }
-                                                       soapBinding->transport = 
estrdup(tmp->children->content);
                                                }
                                        }
                                        tmpbinding->bindingAttributes = (void 
*)soapBinding;
@@ -722,12 +728,8 @@
                                        }
 
                                        function = emalloc(sizeof(sdlFunction));
+                                       memset(function, 0, sizeof(sdlFunction));
                                        function->functionName = 
estrdup(op_name->children->content);
-                                       function->requestParameters = NULL;
-                                       function->responseParameters = NULL;
-                                       function->responseName = NULL;
-                                       function->requestName = NULL;
-                                       function->bindingAttributes = NULL;
 
                                        if (tmpbinding->bindingType == BINDING_SOAP) {
                                                sdlSoapBindingFunctionPtr 
soapFunctionBinding;
@@ -824,9 +826,84 @@
                                                /* FIXME: */
                                        }
 
-                                       fault = get_node_ex(operation->children, 
"fault", WSDL_NAMESPACE);
-                                       if (!fault) {
-                                               /* FIXME: */
+                                       fault = portTypeOperation->children;
+                                       while (fault != NULL) {
+                                               if (node_is_equal_ex(fault, "fault", 
WSDL_NAMESPACE)) {
+                                                       xmlAttrPtr message, name;
+                                                       sdlFaultPtr f;
+
+                                                       name = 
get_attribute(fault->properties, "name");
+                                                       if (name == NULL) {
+                                                               php_error(E_ERROR, 
"SOAP-ERROR: Parsing WSDL: Missing name for <fault> of '%s'", 
op_name->children->content);
+                                                       }
+                                                       message = 
get_attribute(fault->properties, "message");
+                                                       if (message == NULL) {
+                                                               php_error(E_ERROR, 
"SOAP-ERROR: Parsing WSDL: Missing name for <output> of '%s'", 
op_name->children->content);
+                                                       }
+
+                                                       f = emalloc(sizeof(sdlFault));
+                                                       memset(f, 0, sizeof(sdlFault));
+
+                                                       f->name = 
estrdup(name->children->content);
+                                                       f->details = 
wsdl_message(&ctx, message->children->content);
+                                                       if (f->details == NULL || 
zend_hash_num_elements(f->details) != 1) {
+                                                               php_error(E_ERROR, 
"SOAP-ERROR: Parsing WSDL: The fault message '%s' must have a single part", 
message->children->content);
+                                                       }
+
+                                                       if (tmpbinding->bindingType == 
BINDING_SOAP) {
+                                                               xmlNodePtr soap_fault 
= get_node_with_attribute_ex(operation->children, "fault", WSDL_NAMESPACE, "name", 
f->name, NULL);
+                                                               if (soap_fault != 
NULL) {
+                                                                       xmlNodePtr 
trav = soap_fault->children;
+                                                                       while (trav != 
NULL) {
+                                                                               if 
(node_is_equal_ex(trav, "fault", wsdl_soap_namespace)) {
+                                                                                      
 xmlAttrPtr tmp;
+                                                                                 
sdlSoapBindingFunctionFaultPtr binding;
+
+                                                                                      
 binding = f->bindingAttributes = emalloc(sizeof(sdlSoapBindingFunctionFault));
+                                                                                      
 memset(f->bindingAttributes, 0, sizeof(sdlSoapBindingFunctionFault));
+
+                                                                                      
 tmp = get_attribute(trav->properties, "use");
+                                                                                      
 if (tmp && !strncmp(tmp->children->content, "encoded", sizeof("encoded"))) {
+                                                                                      
         binding->use = SOAP_ENCODED;
+                                                                                      
 } else {
+                                                                                      
         binding->use = SOAP_LITERAL;
+                                                                                      
 }
+
+                                                                                      
 tmp = get_attribute(trav->properties, "namespace");
+                                                                                      
 if (tmp) {
+                                                                                      
         binding->ns = estrdup(tmp->children->content);
+                                                                                      
 }
+
+                                                                                      
 if (binding->use == SOAP_ENCODED) {
+                                                                                      
         tmp = get_attribute(trav->properties, "encodingStyle");
+                                                                                      
         if (tmp) {
+                                                                                      
                 if 
(strncmp(tmp->children->content,SOAP_1_1_ENC_NAMESPACE,sizeof(SOAP_1_1_ENC_NAMESPACE)) 
== 0) {
+                                                                                      
                         binding->encodingStyle = SOAP_ENCODING_1_1;
+                                                                                      
                 } else if 
(strncmp(tmp->children->content,SOAP_1_2_ENC_NAMESPACE,sizeof(SOAP_1_2_ENC_NAMESPACE)) 
== 0) {
+                                                                                      
                         binding->encodingStyle = SOAP_ENCODING_1_2;
+                                                                                      
                 } else {
+                                                                                      
                         php_error(E_ERROR, "SOAP-ERROR: Parsing WSDL: Unknown 
encodingStyle '%s'",tmp->children->content);
+                                                                                      
                 }
+                                                                                      
         } else {
+                                                                                      
                 php_error(E_ERROR, "SOAP-ERROR: Parsing WSDL: Unspecified 
encodingStyle");
+                                                                                      
         }
+                                                                                      
 }
+                                                                               } else 
if (is_wsdl_element(trav) && !node_is_equal(trav,"documentation")) {
+                                                                                      
 php_error(E_ERROR,"SOAP-ERROR: Parsing WSDL: Unexpected WSDL element 
<%s>",trav->name);
+                                                                               }
+                                                                               trav = 
trav->next;
+                                                                       }
+                                                               }
+                                                       }
+                                                       if (function->faults == NULL) {
+                                                               function->faults = 
emalloc(sizeof(HashTable));
+                                                               
zend_hash_init(function->faults, 0, NULL, delete_fault, 0);
+                                                       }
+                                                       if 
(zend_hash_add(function->faults, f->name, strlen(f->name)+1, (void**)&f, 
sizeof(sdlFaultPtr), NULL) != SUCCESS) {
+                                                               php_error(E_ERROR, 
"SOAP-ERROR: Parsing WSDL: <fault> with name '%s' already defined in '%s'", f->name, 
op_name->children->content);
+                                                       }
+                                               }
+                                               fault = fault->next;
                                        }
 
                                        function->binding = tmpbinding;
@@ -877,7 +954,7 @@
        return ctx.sdl;
 }
 
-#define WSDL_CACHE_VERSION 03
+#define WSDL_CACHE_VERSION 06
 
 #define WSDL_CACHE_GET(ret,type,buf)   memcpy(&ret,*buf,sizeof(type)); *buf += 
sizeof(type);
 #define WSDL_CACHE_GET_INT(ret,buf)    ret = 
((int)(*buf)[0])|((int)(*buf)[1]<<8)|((int)(*buf)[2]<<16)|((int)(*buf)[3]<<24); *buf 
+= 4;
@@ -1118,9 +1195,13 @@
        int i, n;
 
        WSDL_CACHE_GET_1(body->use, sdlEncodingUse, in);
+       if (body->use == SOAP_ENCODED) {
+               WSDL_CACHE_GET_1(body->encodingStyle, sdlRpcEncodingStyle, in);
+       } else {
+               body->encodingStyle = SOAP_ENCODING_DEFAULT;
+       }
        body->ns = sdl_deserialize_string(in);
        body->parts = sdl_deserialize_string(in);
-       body->encodingStyle = sdl_deserialize_string(in);
        WSDL_CACHE_GET_INT(i, in);
        if (i > 0) {
                body->headers = emalloc(sizeof(HashTable));
@@ -1129,9 +1210,13 @@
                        sdlSoapBindingFunctionHeaderPtr tmp = 
emalloc(sizeof(sdlSoapBindingFunctionHeader));
                        sdl_deserialize_key(body->headers, tmp, in);
                        WSDL_CACHE_GET_1(tmp->use, sdlEncodingUse, in);
+                       if (tmp->use == SOAP_ENCODED) {
+                               WSDL_CACHE_GET_1(tmp->encodingStyle, 
sdlRpcEncodingStyle, in);
+                       } else {
+                               tmp->encodingStyle = SOAP_ENCODING_DEFAULT;
+                       }
                        tmp->name = sdl_deserialize_string(in);
                        tmp->ns = sdl_deserialize_string(in);
-                       tmp->encodingStyle = sdl_deserialize_string(in);
                        WSDL_CACHE_GET_INT(n, in);
                        tmp->encode = encoders[n];
                        WSDL_CACHE_GET_INT(n, in);
@@ -1315,7 +1400,7 @@
                                if (*in != 0) {
                                  sdlSoapBindingPtr soap_binding = 
binding->bindingAttributes = emalloc(sizeof(sdlSoapBinding));
                                        
WSDL_CACHE_GET_1(soap_binding->style,sdlEncodingStyle,&in);
-                                       soap_binding->transport = 
sdl_deserialize_string(&in);
+                                       
WSDL_CACHE_GET_1(soap_binding->transport,sdlTransport,&in);
                                } else {
                                        WSDL_CACHE_SKIP(1,&in);
                                }
@@ -1329,7 +1414,7 @@
        zend_hash_init(&sdl->functions, num_func, NULL, delete_function, 0);
        functions = do_alloca(num_func*sizeof(sdlFunctionPtr));
        for (i = 0; i < num_func; i++) {
-               int binding_num;
+               int binding_num, num_faults;
                sdlFunctionPtr func = emalloc(sizeof(sdlFunction));
                sdl_deserialize_key(&sdl->functions, func, &in);
                func->functionName = sdl_deserialize_string(&in);
@@ -1352,11 +1437,44 @@
                                sdl_deserialize_soap_body(&binding->output, encoders, 
types, &in);
                        } else {
                                WSDL_CACHE_SKIP(1, &in);
+                               func->bindingAttributes = NULL;
                        }
                }
 
                func->requestParameters = sdl_deserialize_parameters(encoders, types, 
&in);
                func->responseParameters = sdl_deserialize_parameters(encoders, types, 
&in);
+
+               WSDL_CACHE_GET_INT(num_faults, &in);
+               if (num_faults > 0) {
+                 int j;
+
+                       func->faults = emalloc(sizeof(HashTable));
+                       zend_hash_init(func->faults, num_faults, NULL, delete_fault, 
0);
+
+                       for (j = 0; j < num_faults; j++) {
+                               sdlFaultPtr fault = emalloc(sizeof(sdlFault));
+
+                               sdl_deserialize_key(func->faults, fault, &in);
+                               fault->name =sdl_deserialize_string(&in);
+                               fault->details =sdl_deserialize_parameters(encoders, 
types, &in);
+                               if (*in != 0) {
+                                       sdlSoapBindingFunctionFaultPtr binding = 
fault->bindingAttributes = emalloc(sizeof(sdlSoapBindingFunctionFault));
+                                       memset(binding, 0, 
sizeof(sdlSoapBindingFunctionFault));
+                                       
WSDL_CACHE_GET_1(binding->use,sdlEncodingUse,&in);
+                                       if (binding->use == SOAP_ENCODED) {
+                                               
WSDL_CACHE_GET_1(binding->encodingStyle, sdlRpcEncodingStyle, &in);
+                                       } else {
+                                               binding->encodingStyle = 
SOAP_ENCODING_DEFAULT;
+                                       }
+                                       binding->ns = sdl_deserialize_string(&in);
+                               } else {
+                                       WSDL_CACHE_SKIP(1, &in);
+                                       fault->bindingAttributes = NULL;
+                               }
+                       }
+               } else {
+                       func->faults = NULL;
+               }
                functions[i] = func;
        }
 
@@ -1655,9 +1773,11 @@
        int i;
 
        WSDL_CACHE_PUT_1(body->use, out);
+       if (body->use == SOAP_ENCODED) {
+               WSDL_CACHE_PUT_1(body->encodingStyle, out);
+       }
        sdl_serialize_string(body->ns, out);
        sdl_serialize_string(body->parts, out);
-       sdl_serialize_string(body->encodingStyle, out);
        if (body->headers) {
                i = zend_hash_num_elements(body->headers);
        } else {
@@ -1670,9 +1790,11 @@
                while (zend_hash_get_current_data(body->headers, (void**)&tmp) == 
SUCCESS) {
                        sdl_serialize_key(body->headers, out);
                        WSDL_CACHE_PUT_1((*tmp)->use, out);
+                       if ((*tmp)->use == SOAP_ENCODED) {
+                               WSDL_CACHE_PUT_1((*tmp)->encodingStyle, out);
+                       }
                        sdl_serialize_string((*tmp)->name, out);
                        sdl_serialize_string((*tmp)->ns, out);
-                       sdl_serialize_string((*tmp)->encodingStyle, out);
                        sdl_serialize_encoder_ref((*tmp)->encode, tmp_encoders, out);
                        sdl_serialize_type_ref((*tmp)->element, tmp_types, out);
                        zend_hash_move_forward(body->headers);
@@ -1849,7 +1971,7 @@
                        if ((*tmp)->bindingType == BINDING_SOAP && 
(*tmp)->bindingAttributes != NULL) {
                                sdlSoapBindingPtr binding = 
(sdlSoapBindingPtr)(*tmp)->bindingAttributes;
                                WSDL_CACHE_PUT_1(binding->style, out);
-                               sdl_serialize_string(binding->transport, out);
+                               WSDL_CACHE_PUT_1(binding->transport, out);
                        } else {
                                WSDL_CACHE_PUT_1(0,out);
                        }
@@ -1893,6 +2015,32 @@
                        sdl_serialize_parameters((*tmp)->requestParameters, 
&tmp_encoders, &tmp_types, out);
                        sdl_serialize_parameters((*tmp)->responseParameters, 
&tmp_encoders, &tmp_types, out);
 
+                       if ((*tmp)->faults) {
+                               sdlFaultPtr *fault;
+
+                               
WSDL_CACHE_PUT_INT(zend_hash_num_elements((*tmp)->faults), out);
+
+                               zend_hash_internal_pointer_reset((*tmp)->faults);
+                               while (zend_hash_get_current_data((*tmp)->faults, 
(void**)&fault) == SUCCESS) {
+                                       sdl_serialize_key((*tmp)->faults, out);
+                                       sdl_serialize_string((*fault)->name, out);
+                                       sdl_serialize_parameters((*fault)->details, 
&tmp_encoders, &tmp_types, out);
+                                       if ((*tmp)->binding->bindingType == 
BINDING_SOAP && (*fault)->bindingAttributes != NULL) {
+                                               sdlSoapBindingFunctionFaultPtr binding 
= (sdlSoapBindingFunctionFaultPtr)(*fault)->bindingAttributes;
+                                               WSDL_CACHE_PUT_1(binding->use, out);
+                                               if (binding->use == SOAP_ENCODED) {
+                                                       
WSDL_CACHE_PUT_1(binding->encodingStyle, out);
+                                               }
+                                               sdl_serialize_string(binding->ns, out);
+                                       } else {
+                                               WSDL_CACHE_PUT_1(0, out);
+                                       }
+                                       zend_hash_move_forward((*tmp)->faults);
+                               }
+                       } else {
+                               WSDL_CACHE_PUT_INT(0, out);
+                       }
+
                        zend_hash_add(&tmp_functions, (char*)tmp, sizeof(*tmp), 
(void**)&function_num, sizeof(function_num), NULL);
                        function_num++;
                        zend_hash_move_forward(&sdl->functions);
@@ -1935,6 +2083,7 @@
        char* old_error_code = SOAP_GLOBAL(error_code);
 
        SOAP_GLOBAL(error_code) = "WSDL";
+
        if (SOAP_GLOBAL(cache_enabled)) {
                char  fn[MAXPATHLEN];
 
@@ -2028,10 +2177,9 @@
 
        if (binding->bindingType == BINDING_SOAP) {
                sdlSoapBindingPtr soapBind = binding->bindingAttributes;
-               if (soapBind && soapBind->transport) {
-                       efree(soapBind->transport);
+               if (soapBind) {
+                       efree(soapBind);
                }
-               efree(soapBind);
        }
        efree(binding);
 }
@@ -2044,9 +2192,6 @@
        if (body.parts) {
                efree(body.parts);
        }
-       if (body.encodingStyle) {
-               efree(body.encodingStyle);
-       }
        if (body.headers) {
                zend_hash_destroy(body.headers);
                efree(body.headers);
@@ -2074,6 +2219,10 @@
                zend_hash_destroy(function->responseParameters);
                efree(function->responseParameters);
        }
+       if (function->faults) {
+               zend_hash_destroy(function->faults);
+               efree(function->faults);
+       }
 
        if (function->bindingAttributes &&
            function->binding && function->binding->bindingType == BINDING_SOAP) {
@@ -2106,12 +2255,30 @@
        if (hdr->ns) {
                efree(hdr->ns);
        }
-       if (hdr->encodingStyle) {
-               efree(hdr->encodingStyle);
-       }
        efree(hdr);
 }
 
+static void delete_fault(void *data)
+{
+       sdlFaultPtr fault = *((sdlFaultPtr*)data);
+       if (fault->name) {
+               efree(fault->name);
+       }
+       if (fault->details) {
+               zend_hash_destroy(fault->details);
+               efree(fault->details);
+       }
+       if (fault->bindingAttributes) {
+               sdlSoapBindingFunctionFaultPtr binding = 
(sdlSoapBindingFunctionFaultPtr)fault->bindingAttributes;
+
+               if (binding->ns) {
+                       efree(binding->ns);
+               }
+               efree(fault->bindingAttributes);
+       }
+       efree(fault);
+}
+
 static void delete_document(void *doc_ptr)
 {
        xmlDocPtr doc = *((xmlDocPtr*)doc_ptr);
http://cvs.php.net/diff.php/php-src/ext/soap/php_sdl.h?r1=1.29&r2=1.30&ty=u
Index: php-src/ext/soap/php_sdl.h
diff -u php-src/ext/soap/php_sdl.h:1.29 php-src/ext/soap/php_sdl.h:1.30
--- php-src/ext/soap/php_sdl.h:1.29     Fri Feb 13 10:19:09 2004
+++ php-src/ext/soap/php_sdl.h  Thu Feb 19 03:21:13 2004
@@ -17,7 +17,7 @@
   |          Dmitry Stogov <[EMAIL PROTECTED]>                             |
   +----------------------------------------------------------------------+
 */
-/* $Id: php_sdl.h,v 1.29 2004/02/13 15:19:09 dmitry Exp $ */
+/* $Id: php_sdl.h,v 1.30 2004/02/19 08:21:13 dmitry Exp $ */
 
 #ifndef PHP_SDL_H
 #define PHP_SDL_H
@@ -32,15 +32,25 @@
 } sdlBindingType;
 
 typedef enum _sdlEncodingStyle {
-       SOAP_RPC = 1,
+       SOAP_RPC      = 1,
        SOAP_DOCUMENT = 2
 } sdlEncodingStyle;
 
+typedef enum _sdlRpcEncodingStyle {
+       SOAP_ENCODING_DEFAULT = 0,
+       SOAP_ENCODING_1_1     = 1,
+       SOAP_ENCODING_1_2     = 2
+} sdlRpcEncodingStyle;
+
 typedef enum _sdlEncodingUse {
        SOAP_ENCODED = 1,
        SOAP_LITERAL = 2
 } sdlEncodingUse;
 
+typedef enum _sdlTransport {
+       SOAP_TRANSPORT_HTTP = 1
+} sdlTransport;
+
 struct _sdl {
        HashTable  functions;        /* array of sdlFunction */
        HashTable *types;            /* array of sdlTypesPtr */
@@ -76,25 +86,31 @@
 
 /* Soap Binding Specfic stuff */
 struct _sdlSoapBinding {
-       char             *transport;
        sdlEncodingStyle  style;
+       sdlTransport      transport; /* not implemented yet */
 };
 
 typedef struct _sdlSoapBindingFunctionHeader {
-       char           *name;
-       char           *ns;
-       sdlEncodingUse  use;
-       sdlTypePtr      element;
-       encodePtr       encode;
-       char           *encodingStyle; /* not implemented yet */
+       char                *name;
+       char                *ns;
+       sdlEncodingUse       use;
+       sdlTypePtr           element;
+       encodePtr            encode;
+       sdlRpcEncodingStyle  encodingStyle; /* not implemented yet */
 } sdlSoapBindingFunctionHeader, *sdlSoapBindingFunctionHeaderPtr;
 
+typedef struct _sdlSoapBindingFunctionFault {
+       char                *ns;
+       sdlEncodingUse       use;
+       sdlRpcEncodingStyle  encodingStyle; /* not implemented yet */
+} sdlSoapBindingFunctionFault, *sdlSoapBindingFunctionFaultPtr;
+
 struct _sdlSoapBindingFunctionBody {
-       char           *ns;
-       sdlEncodingUse  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 */
+       sdlRpcEncodingStyle  encodingStyle;  /* not implemented yet */
+       HashTable           *headers;        /* array of 
sdlSoapBindingFunctionHeaderPtr */
 };
 
 struct _sdlSoapBindingFunction {
@@ -185,6 +201,12 @@
        char      *paramName;
 };
 
+typedef struct _sdlFault {
+       char      *name;
+       HashTable *details;            /* array of sdlParamPtr */
+       void      *bindingAttributes;  /* sdlSoapBindingFunctionFaultPtr */
+} sdlFault, *sdlFaultPtr;
+
 struct _sdlFunction {
        char               *functionName;
        char               *requestName;
@@ -193,6 +215,7 @@
        HashTable          *responseParameters; /* array of sdlParamPtr (this should 
only be one) */
        struct _sdlBinding *binding;
        void               *bindingAttributes;  /* sdlSoapBindingFunctionPtr */
+       HashTable          *faults;             /* array of sdlFaultPtr */
 };
 
 typedef enum _sdlUse {
http://cvs.php.net/diff.php/php-src/ext/soap/soap.c?r1=1.88&r2=1.89&ty=u
Index: php-src/ext/soap/soap.c
diff -u php-src/ext/soap/soap.c:1.88 php-src/ext/soap/soap.c:1.89
--- php-src/ext/soap/soap.c:1.88        Wed Feb 18 02:35:34 2004
+++ php-src/ext/soap/soap.c     Thu Feb 19 03:21:13 2004
@@ -17,7 +17,7 @@
   |          Dmitry Stogov <[EMAIL PROTECTED]>                             |
   +----------------------------------------------------------------------+
 */
-/* $Id: soap.c,v 1.88 2004/02/18 07:35:34 dmitry Exp $ */
+/* $Id: soap.c,v 1.89 2004/02/19 08:21:13 dmitry Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -48,9 +48,9 @@
 static void type_to_string(sdlTypePtr type, smart_str *buf, int level);
 
 static void clear_soap_fault(zval *obj TSRMLS_DC);
-static void set_soap_fault(zval *obj, char *fault_code, char *fault_string, char 
*fault_actor, zval *fault_detail TSRMLS_DC);
-static void soap_server_fault(char* code, char* string, char *actor, zval* details 
TSRMLS_DC);
-static void soap_server_fault_ex(zval* fault TSRMLS_DC);
+static void set_soap_fault(zval *obj, char *fault_code, char *fault_string, char 
*fault_actor, zval *fault_detail, char *name TSRMLS_DC);
+static void soap_server_fault(char* code, char* string, char *actor, zval* details, 
char *name TSRMLS_DC);
+static void soap_server_fault_ex(sdlFunctionPtr function, zval* fault TSRMLS_DC);
 
 static sdlParamPtr get_param(sdlFunctionPtr function, char *param_name, int index, 
int);
 static sdlFunctionPtr get_function(sdlPtr sdl, const char *function_name);
@@ -666,19 +666,20 @@
 /* SoapFault functions */
 PHP_METHOD(soapfault,soapfault)
 {
-       char *fault_string = NULL, *fault_code = NULL, *fault_actor = NULL;
-       int fault_string_len, fault_code_len, fault_actor_len;
+       char *fault_string = NULL, *fault_code = NULL, *fault_actor = NULL, *name = 
NULL;
+       int fault_string_len, fault_code_len, fault_actor_len, name_len;
        zval *details = NULL;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|s!z!",
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|s!z!s",
                &fault_code, &fault_code_len,
                &fault_string, &fault_string_len,
                &fault_actor, &fault_actor_len,
-               &details) == FAILURE) {
+               &details,
+               &name, &name_len) == FAILURE) {
                php_error(E_ERROR, "Invalid arguments to SoapFault constructor");
        }
 
-       set_soap_fault(this_ptr, fault_code, fault_string, fault_actor, details 
TSRMLS_CC);
+       set_soap_fault(this_ptr, fault_code, fault_string, fault_actor, details, name 
TSRMLS_CC);
 }
 
 #ifdef ZEND_ENGINE_2
@@ -1327,7 +1328,7 @@
                                if (EG(exception) &&
                                    Z_TYPE_P(EG(exception)) == IS_OBJECT &&
                                    Z_OBJCE_P(EG(exception)) == 
soap_fault_class_entry) {
-                                       soap_server_fault_ex(EG(exception) TSRMLS_CC);
+                                       soap_server_fault_ex(function, EG(exception) 
TSRMLS_CC);
                                }
 #endif
                                zval_dtor(&constructor);
@@ -1370,7 +1371,7 @@
                        header = header->next;
                        if (service->sdl && !h->function && !h->hdr) {
                                if (h->mustUnderstand) {
-                                       soap_server_fault("MustUnderstand","Header not 
understood", NULL, NULL TSRMLS_CC);
+                                       soap_server_fault("MustUnderstand","Header not 
understood", NULL, NULL, NULL TSRMLS_CC);
                                } else {
                                        continue;
                                }
@@ -1387,7 +1388,7 @@
                                        php_error(E_ERROR, "Function '%s' call 
failed", Z_STRVAL(function_name));
                                }
                        } else if (h->mustUnderstand) {
-                               soap_server_fault("MustUnderstand","Header not 
understood", NULL, NULL TSRMLS_CC);
+                               soap_server_fault("MustUnderstand","Header not 
understood", NULL, NULL, NULL TSRMLS_CC);
                        }
                        efree(fn_name);
                }
@@ -1412,7 +1413,7 @@
        if (EG(exception) &&
            Z_TYPE_P(EG(exception)) == IS_OBJECT &&
            Z_OBJCE_P(EG(exception)) == soap_fault_class_entry) {
-               soap_server_fault_ex(EG(exception) TSRMLS_CC);
+               soap_server_fault_ex(function, EG(exception) TSRMLS_CC);
        }
 #endif
        if (call_status == SUCCESS) {
@@ -1420,7 +1421,7 @@
 
                if (Z_TYPE(retval) == IS_OBJECT &&
                    Z_OBJCE(retval) == soap_fault_class_entry) {
-                       soap_server_fault_ex(&retval TSRMLS_CC);
+                       soap_server_fault_ex(function, &retval TSRMLS_CC);
                }
 
                if (function && function->responseName) {
@@ -1496,21 +1497,23 @@
 
 PHP_METHOD(soapserver, fault)
 {
-       char *code, *string, *actor=NULL;
-       int code_len, string_len, actor_len;
+       char *code, *string, *actor=NULL, *name=NULL;
+       int code_len, string_len, actor_len, name_len;
        zval* details = NULL;
 
        SOAP_SERVER_BEGIN_CODE();
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|sz",
-           &code, &code_len, &string, &string_len, &actor, &actor_len, &details) == 
FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|szs",
+           &code, &code_len, &string, &string_len, &actor, &actor_len, &details,
+           &name, &name_len) == FAILURE) {
                php_error(E_ERROR, "Invalid parameters passed to soapserver:fault");
        }
-       soap_server_fault(code, string, actor, details TSRMLS_CC);
+
+       soap_server_fault(code, string, actor, details, name TSRMLS_CC);
        SOAP_SERVER_END_CODE();
 }
 
-static void soap_server_fault_ex(zval* fault TSRMLS_DC)
+static void soap_server_fault_ex(sdlFunctionPtr function, zval* fault TSRMLS_DC)
 {
        int soap_version;
        xmlChar *buf, cont_len[30];
@@ -1519,7 +1522,7 @@
 
        soap_version = SOAP_GLOBAL(soap_version);
 
-       doc_return = serialize_response_call(NULL, NULL, NULL, fault, NULL, 
soap_version TSRMLS_CC);
+       doc_return = serialize_response_call(function, NULL, NULL, fault, NULL, 
soap_version TSRMLS_CC);
 
        xmlDocDumpMemory(doc_return, &buf, &size);
 
@@ -1542,14 +1545,15 @@
        zend_bailout();
 }
 
-static void soap_server_fault(char* code, char* string, char *actor, zval* details 
TSRMLS_DC)
+static void soap_server_fault(char* code, char* string, char *actor, zval* details, 
char* name TSRMLS_DC)
 {
        zval ret;
 
        INIT_ZVAL(ret);
 
-       set_soap_fault(&ret, code, string, actor, details TSRMLS_CC);
-       soap_server_fault_ex(&ret TSRMLS_CC);
+       set_soap_fault(&ret, code, string, actor, details, name TSRMLS_CC);
+       /* TODO: Which function */
+       soap_server_fault_ex(NULL, &ret TSRMLS_CC);
 }
 
 static void soap_error_handler(int error_num, const char *error_filename, const uint 
error_lineno, const char *format, va_list args)
@@ -1617,7 +1621,7 @@
                        }
                        php_end_ob_buffer(0, 0 TSRMLS_CC);
 
-                       soap_server_fault(code, buffer, NULL, &outbuf TSRMLS_CC);
+                       soap_server_fault(code, buffer, NULL, &outbuf, NULL TSRMLS_CC);
                }
        }
 }
@@ -2107,7 +2111,7 @@
 {
        zval *fault;
        MAKE_STD_ZVAL(fault);
-       set_soap_fault(fault, fault_code, fault_string, fault_actor, fault_detail 
TSRMLS_CC);
+       set_soap_fault(fault, fault_code, fault_string, fault_actor, fault_detail, 
NULL TSRMLS_CC);
 #ifdef ZEND_ENGINE_2
        fault->refcount--;  /*FIXME*/
 #endif
@@ -2115,7 +2119,7 @@
        return fault;
 }
 
-static void set_soap_fault(zval *obj, char *fault_code, char *fault_string, char 
*fault_actor, zval *fault_detail TSRMLS_DC)
+static void set_soap_fault(zval *obj, char *fault_code, char *fault_string, char 
*fault_actor, zval *fault_detail, char *name TSRMLS_DC)
 {
        if (Z_TYPE_P(obj) != IS_OBJECT) {
                object_init_ex(obj, soap_fault_class_entry);
@@ -2164,6 +2168,9 @@
        if (fault_detail != NULL) {
                add_property_zval(obj, "detail", fault_detail);
        }
+       if (name != NULL) {
+               add_property_string(obj, "_name", name, 1);
+       }
 }
 
 static void deserialize_parameters(xmlNodePtr params, sdlFunctionPtr function, int 
*num_params, zval ***parameters)
@@ -2245,7 +2252,7 @@
        }
        if (num_of_params > cur_param) {
                TSRMLS_FETCH();
-               soap_server_fault("Client","Missing parameter", NULL, NULL TSRMLS_CC);
+               soap_server_fault("Client","Missing parameter", NULL, NULL, NULL 
TSRMLS_CC);
        }
        (*parameters) = tmp_parameters;
        (*num_params) = num_of_params;
@@ -2301,7 +2308,7 @@
                                envelope_ns = SOAP_1_2_ENV_NAMESPACE;
                                SOAP_GLOBAL(soap_version) = SOAP_1_2;
                        } else {
-                               soap_server_fault("VersionMismatch","Wrong Version", 
NULL, NULL TSRMLS_CC);
+                               soap_server_fault("VersionMismatch","Wrong Version", 
NULL, NULL, NULL TSRMLS_CC);
                        }
                }
                trav = trav->next;
@@ -2393,18 +2400,18 @@
                if (*version == SOAP_1_1) {
                        attr = 
get_attribute_ex(func->properties,"encodingStyle",SOAP_1_1_ENV_NAMESPACE);
                        if (attr && 
strcmp(attr->children->content,SOAP_1_1_ENC_NAMESPACE) != 0) {
-                               soap_server_fault("Client","Unknown Data Encoding 
Style", NULL, NULL TSRMLS_CC);
+                               soap_server_fault("Client","Unknown Data Encoding 
Style", NULL, NULL, NULL TSRMLS_CC);
                        }
                } else {
                        attr = 
get_attribute_ex(func->properties,"encodingStyle",SOAP_1_2_ENV_NAMESPACE);
                        if (attr && 
strcmp(attr->children->content,SOAP_1_2_ENC_NAMESPACE) != 0) {
-                               soap_server_fault("DataEncodingUnknown","Unknown Data 
Encoding Style", NULL, NULL TSRMLS_CC);
+                               soap_server_fault("DataEncodingUnknown","Unknown Data 
Encoding Style", NULL, NULL, NULL TSRMLS_CC);
                        }
                }
                function = find_function(sdl, func, function_name);
                if (sdl != NULL && function == NULL) {
                        if (*version == SOAP_1_2) {
-                               soap_server_fault("rpc:ProcedureNotPresent","Procedure 
not present", NULL, NULL TSRMLS_CC);
+                               soap_server_fault("rpc:ProcedureNotPresent","Procedure 
not present", NULL, NULL, NULL TSRMLS_CC);
                        } else {
                                php_error(E_ERROR, "Procedure '%s' not present", 
func->name);
                        }
@@ -2438,7 +2445,7 @@
                                if (*version == SOAP_1_1) {
                                        attr = 
get_attribute_ex(hdr_func->properties,"encodingStyle",SOAP_1_1_ENV_NAMESPACE);
                                        if (attr && 
strcmp(attr->children->content,SOAP_1_1_ENC_NAMESPACE) != 0) {
-                                               soap_server_fault("Client","Unknown 
Data Encoding Style", NULL, NULL TSRMLS_CC);
+                                               soap_server_fault("Client","Unknown 
Data Encoding Style", NULL, NULL, NULL TSRMLS_CC);
                                        }
                                        attr = 
get_attribute_ex(hdr_func->properties,"actor",envelope_ns);
                                        if (attr != NULL) {
@@ -2450,7 +2457,7 @@
                                } else if (*version == SOAP_1_2) {
                                        attr = 
get_attribute_ex(hdr_func->properties,"encodingStyle",SOAP_1_2_ENV_NAMESPACE);
                                        if (attr && 
strcmp(attr->children->content,SOAP_1_2_ENC_NAMESPACE) != 0) {
-                                               
soap_server_fault("DataEncodingUnknown","Unknown Data Encoding Style", NULL, NULL 
TSRMLS_CC);
+                                               
soap_server_fault("DataEncodingUnknown","Unknown Data Encoding Style", NULL, NULL, 
NULL TSRMLS_CC);
                                        }
                                        attr = 
get_attribute_ex(hdr_func->properties,"role",envelope_ns);
                                        if (attr != NULL) {
@@ -2470,7 +2477,7 @@
                                                   
strcmp(attr->children->content,"false") == 0) {
                                                mustUnderstand = 0;
                                        } else {
-                                               
soap_server_fault("Client","mustUnderstand value is not boolean", NULL, NULL 
TSRMLS_CC);
+                                               
soap_server_fault("Client","mustUnderstand value is not boolean", NULL, NULL, NULL 
TSRMLS_CC);
                                        }
                                }
                                h = emalloc(sizeof(soapHeader));
@@ -2664,15 +2671,42 @@
        xmlDocSetRootElement(doc, envelope);
 
        if (Z_TYPE_P(ret) == IS_OBJECT &&
-               Z_OBJCE_P(ret) == soap_fault_class_entry) {
+           Z_OBJCE_P(ret) == soap_fault_class_entry) {
+         char *detail_name;
+               HashTable* prop;
+               zval **tmp;
+               sdlFaultPtr fault = NULL;
+
+               prop = Z_OBJPROP_P(ret);
                body = xmlNewChild(envelope, ns, "Body", NULL);
+               param = xmlNewChild(body, ns, "Fault", NULL);
+
                use = SOAP_LITERAL;
-               if (version == SOAP_1_1) {
-                       HashTable* prop;
-                       zval **tmp;
+               if (zend_hash_find(prop, "_name", sizeof("_name"), (void**)&tmp) == 
SUCCESS && Z_TYPE_PP(tmp) == IS_STRING) {
+                       sdlFaultPtr *tmp_fault;
+                       if (function && function->faults &&
+                           zend_hash_find(function->faults, Z_STRVAL_PP(tmp), 
Z_STRLEN_PP(tmp)+1, (void**)&tmp_fault) == SUCCESS) {
+                         fault = *tmp_fault;
+                               if (function->binding &&
+                                   function->binding->bindingType == BINDING_SOAP &&
+                                   fault->bindingAttributes) {
+                                       sdlSoapBindingFunctionFaultPtr fb = 
(sdlSoapBindingFunctionFaultPtr)fault->bindingAttributes;
+                                       use = fb->use;
+                               }
+                       }
+               } else if (function && function->faults &&
+                          zend_hash_num_elements(function->faults) == 1) {
+
+                 fault = *(sdlFaultPtr*)function->faults->pListHead->pData;
+                       if (function->binding &&
+                           function->binding->bindingType == BINDING_SOAP &&
+                           fault->bindingAttributes) {
+                               sdlSoapBindingFunctionFaultPtr fb = 
(sdlSoapBindingFunctionFaultPtr)fault->bindingAttributes;
+                               use = fb->use;
+                       }
+               }
 
-                       prop = Z_OBJPROP_P(ret);
-                       param = xmlNewChild(body, ns, "Fault", NULL);
+               if (version == SOAP_1_1) {
                        if (zend_hash_find(prop, "faultcode", sizeof("faultcode"), 
(void**)&tmp) == SUCCESS) {
                                int new_len;
                                xmlNodePtr node = xmlNewNode(NULL, "faultcode");
@@ -2697,17 +2731,8 @@
                                xmlNodeSetContentLen(node, str, new_len);
                                efree(str);
                        }
-                       if (zend_hash_find(prop, "detail", sizeof("detail"), 
(void**)&tmp) == SUCCESS &&
-                           Z_TYPE_PP(tmp) != IS_NULL) {
-                               /*FIXME: use = SOAP_ENCODED;*/
-                               serialize_zval(*tmp, NULL, "detail", use, param 
TSRMLS_CC);
-                       }
+                       detail_name = "detail";
                } else {
-                       HashTable* prop;
-                       zval **tmp;
-
-                       prop = Z_OBJPROP_P(ret);
-                       param = xmlNewChild(body, ns, "Fault", NULL);
                        if (zend_hash_find(prop, "faultcode", sizeof("faultcode"), 
(void**)&tmp) == SUCCESS) {
                                int new_len;
                                xmlNodePtr node = xmlNewChild(param, ns, "Code", NULL);
@@ -2724,10 +2749,51 @@
                                xmlNodeSetContentLen(node, str, new_len);
                                efree(str);
                        }
+                       detail_name = SOAP_1_2_ENV_NS_PREFIX":Detail";
+               }
+               if (fault && fault->details && zend_hash_num_elements(fault->details) 
== 1) {
+                       xmlNodePtr node;
+                 zval *detail = NULL;
+                       sdlParamPtr sparam;
+                       xmlNodePtr x;
+
                        if (zend_hash_find(prop, "detail", sizeof("detail"), 
(void**)&tmp) == SUCCESS &&
                            Z_TYPE_PP(tmp) != IS_NULL) {
-                               serialize_zval(*tmp, NULL, 
SOAP_1_2_ENV_NS_PREFIX":Detail", use, param TSRMLS_CC);
+                               detail = *tmp;
                        }
+                       node = xmlNewNode(NULL, detail_name);
+                       xmlAddChild(param, node);
+
+                       sparam = *(sdlParamPtr*)fault->details->pListHead->pData;
+                       x = serialize_parameter(sparam, detail, 1, NULL, use, node 
TSRMLS_CC);
+
+                       if (function &&
+                           function->binding &&
+                           function->binding->bindingType == BINDING_SOAP &&
+                           function->bindingAttributes) {
+                               sdlSoapBindingFunctionPtr fnb = 
(sdlSoapBindingFunctionPtr)function->bindingAttributes;
+                               if (fnb->style == SOAP_RPC) {
+                                 if (fault->bindingAttributes) {
+                                               sdlSoapBindingFunctionFaultPtr fb = 
(sdlSoapBindingFunctionFaultPtr)fault->bindingAttributes;
+                                               if (fb->ns) {
+                                                       xmlNsPtr ns = encode_add_ns(x, 
fb->ns);
+                                                       xmlSetNs(x, ns);
+                                               }
+                                       }
+                               } else {
+                                       if (sparam->element) {
+                                               xmlNsPtr ns = encode_add_ns(x, 
sparam->element->namens);
+                                               xmlNodeSetName(x, 
sparam->element->name);
+                                               xmlSetNs(x, ns);
+                                       }
+                               }
+                       }
+                       if (use == SOAP_ENCODED && version == SOAP_1_2) {
+                               xmlSetNsProp(x, envelope->ns, "encodingStyle", 
SOAP_1_2_ENC_NAMESPACE);
+                       }
+               } else if (zend_hash_find(prop, "detail", sizeof("detail"), 
(void**)&tmp) == SUCCESS &&
+                   Z_TYPE_PP(tmp) != IS_NULL) {
+                       serialize_zval(*tmp, NULL, detail_name, use, param TSRMLS_CC);
                }
        } else {
 
@@ -2917,7 +2983,7 @@
                        }
                }
        }
-       
+
        if (function && function->requestParameters) {
                int n = zend_hash_num_elements(function->requestParameters);
 

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to