dmitry          Tue Feb 24 10:06:43 2004 EDT

  Added files:                 
    /php-src/ext/soap/tests/soap12      T63.phpt 

  Modified files:              
    /php-src/ext/soap   TODO php_sdl.c php_sdl.h soap.c 
    /php-src/ext/soap/tests/soap12      soap12-test.inc soap12-test.wsdl 
  Log:
  WSDL support for <soap:headerfault> was implemented
  
  
http://cvs.php.net/diff.php/php-src/ext/soap/TODO?r1=1.46&r2=1.47&ty=u
Index: php-src/ext/soap/TODO
diff -u php-src/ext/soap/TODO:1.46 php-src/ext/soap/TODO:1.47
--- php-src/ext/soap/TODO:1.46  Tue Feb 24 04:02:33 2004
+++ php-src/ext/soap/TODO       Tue Feb 24 10:06:41 2004
@@ -50,7 +50,7 @@
 ----
 ? server part support for "document" style encoding
 ? support for <fault>, <soap:fault>
-- <soap:headerfault>
+? <soap:headerfault>
 - <soap:body> parts attribute (with MIME/DIME binding)
 - MIME binding
 - DIME binding
@@ -59,6 +59,7 @@
 - function/method overloading/redeclaration (test(int); test(string))
 - wsdl auto generation
 - HTTP GET/POST binding
+- SOAP security extension
 
 Schema
 ------
http://cvs.php.net/diff.php/php-src/ext/soap/php_sdl.c?r1=1.65&r2=1.66&ty=u
Index: php-src/ext/soap/php_sdl.c
diff -u php-src/ext/soap/php_sdl.c:1.65 php-src/ext/soap/php_sdl.c:1.66
--- php-src/ext/soap/php_sdl.c:1.65     Thu Feb 19 13:49:50 2004
+++ php-src/ext/soap/php_sdl.c  Tue Feb 24 10:06:41 2004
@@ -17,7 +17,7 @@
   |          Dmitry Stogov <[EMAIL PROTECTED]>                             |
   +----------------------------------------------------------------------+
 */
-/* $Id: php_sdl.c,v 1.65 2004/02/19 18:49:50 dmitry Exp $ */
+/* $Id: php_sdl.c,v 1.66 2004/02/24 15:06:41 dmitry Exp $ */
 
 #include "php_soap.h"
 #include "libxml/uri.h"
@@ -315,9 +315,117 @@
        }
 }
 
+static sdlSoapBindingFunctionHeaderPtr wsdl_soap_binding_header(sdlCtx* ctx, 
xmlNodePtr header, char* wsdl_soap_namespace, int fault)
+{
+       xmlAttrPtr tmp;
+       xmlNodePtr *message, part;
+       char *ctype;
+       sdlSoapBindingFunctionHeaderPtr h;
+
+       tmp = get_attribute(header->properties, "message");
+       if (!tmp) {
+               php_error(E_ERROR, "SOAP-ERROR: Parsing WSDL: Missing message 
attribute for <header>");
+       }
+
+       ctype = strrchr(tmp->children->content,':');
+       if (ctype == NULL) {
+               ctype = tmp->children->content;
+       } else {
+               ++ctype;
+       }
+       if (zend_hash_find(&ctx->messages, ctype, strlen(ctype)+1, (void**)&message) 
!= SUCCESS) {
+               php_error(E_ERROR, "SOAP-ERROR: Parsing WSDL: Missing <message> with 
name '%s'", tmp->children->content);
+       }
+
+       tmp = get_attribute(header->properties, "part");
+       if (!tmp) {
+               php_error(E_ERROR, "SOAP-ERROR: Parsing WSDL: Missing part attribute 
for <header>");
+       }
+       part = get_node_with_attribute_ex((*message)->children, "part", 
WSDL_NAMESPACE, "name", tmp->children->content, NULL);
+       if (!part) {
+               php_error(E_ERROR, "SOAP-ERROR: Parsing WSDL: Missing part '%s' in 
<message>",tmp->children->content);
+       }
+
+       h = emalloc(sizeof(sdlSoapBindingFunctionHeader));
+       memset(h, 0, sizeof(sdlSoapBindingFunctionHeader));
+       h->name = estrdup(tmp->children->content);
+
+       tmp = get_attribute(header->properties, "use");
+       if (tmp && !strncmp(tmp->children->content, "encoded", sizeof("encoded"))) {
+               h->use = SOAP_ENCODED;
+       } else {
+               h->use = SOAP_LITERAL;
+       }
+
+       tmp = get_attribute(header->properties, "namespace");
+       if (tmp) {
+               h->ns = estrdup(tmp->children->content);
+       }
+
+       if (h->use == SOAP_ENCODED) {
+               tmp = get_attribute(header->properties, "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 {
+                       php_error(E_ERROR, "SOAP-ERROR: Parsing WSDL: Unspecified 
encodingStyle");
+               }
+       }
+
+       tmp = get_attribute(part->properties, "type");
+       if (tmp != NULL) {
+               h->encode = get_encoder_from_prefix(ctx->sdl, part, 
tmp->children->content);
+       } else {
+               tmp = get_attribute(part->properties, "element");
+               if (tmp != NULL) {
+                       h->element = get_element(ctx->sdl, part, 
tmp->children->content);
+                       if (h->element) {
+                               h->encode = h->element->encode;
+                               if (!h->ns && h->element->namens) {
+                                       h->ns = estrdup(h->element->namens);
+                               }
+                       }
+               }
+       }
+       if (!fault) {
+               xmlNodePtr trav = header->children;
+               while (trav != NULL) {
+                       if (node_is_equal_ex(trav, "headerfault", 
wsdl_soap_namespace)) {
+                               sdlSoapBindingFunctionHeaderPtr hf = 
wsdl_soap_binding_header(ctx, trav, wsdl_soap_namespace, 1);
+                               smart_str key = {0};
+
+                               if (h->headerfaults == NULL) {
+                                       h->headerfaults = emalloc(sizeof(HashTable));
+                                       zend_hash_init(h->headerfaults, 0, NULL, 
delete_header, 0);
+                               }
+
+                               if (hf->ns) {
+                                       smart_str_appends(&key,hf->ns);
+                                       smart_str_appendc(&key,':');
+                               }
+                               smart_str_appends(&key,hf->name);
+                               smart_str_0(&key);
+                               if (zend_hash_add(h->headerfaults, key.c, key.len+1, 
(void**)&hf, sizeof(sdlSoapBindingFunctionHeaderPtr), NULL) != SUCCESS) {
+                                       delete_header((void**)&hf);
+                               }
+                               smart_str_free(&key);
+                       } 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;
+               }
+       }
+       return h;
+}
+
 static void wsdl_soap_binding_body(sdlCtx* ctx, xmlNodePtr node, char* 
wsdl_soap_namespace, sdlSoapBindingFunctionBody *binding, HashTable* params)
 {
-       xmlNodePtr body, trav, header;
+       xmlNodePtr body, trav;
        xmlAttrPtr tmp;
 
        trav = node->children;
@@ -358,84 +466,9 @@
                                }
                        }
                } else if (node_is_equal_ex(trav, "header", wsdl_soap_namespace)) {
-                       xmlAttrPtr tmp;
-                       xmlNodePtr *message, part;
-                       char *ctype;
-                       sdlSoapBindingFunctionHeaderPtr h;
+                       sdlSoapBindingFunctionHeaderPtr h = 
wsdl_soap_binding_header(ctx, trav, wsdl_soap_namespace, 0);
                        smart_str key = {0};
 
-                       header = trav;
-                       tmp = get_attribute(header->properties, "message");
-                       if (!tmp) {
-                               php_error(E_ERROR, "SOAP-ERROR: Parsing WSDL: Missing 
message attribute for <header>");
-                       }
-
-                       ctype = strrchr(tmp->children->content,':');
-                       if (ctype == NULL) {
-                               ctype = tmp->children->content;
-                       } else {
-                               ++ctype;
-                       }
-                       if (zend_hash_find(&ctx->messages, ctype, strlen(ctype)+1, 
(void**)&message) != SUCCESS) {
-                               php_error(E_ERROR, "SOAP-ERROR: Parsing WSDL: Missing 
<message> with name '%s'", tmp->children->content);
-                       }
-
-                       tmp = get_attribute(header->properties, "part");
-                       if (!tmp) {
-                               php_error(E_ERROR, "SOAP-ERROR: Parsing WSDL: Missing 
part attribute for <header>");
-                       }
-                       part = get_node_with_attribute_ex((*message)->children, 
"part", WSDL_NAMESPACE, "name", tmp->children->content, NULL);
-                       if (!part) {
-                               php_error(E_ERROR, "SOAP-ERROR: Parsing WSDL: Missing 
part '%s' in <message>",tmp->children->content);
-                       }
-
-                       h = emalloc(sizeof(sdlSoapBindingFunctionHeader));
-                       memset(h, 0, sizeof(sdlSoapBindingFunctionHeader));
-                       h->name = estrdup(tmp->children->content);
-
-                       tmp = get_attribute(header->properties, "use");
-                       if (tmp && !strncmp(tmp->children->content, "encoded", 
sizeof("encoded"))) {
-                               h->use = SOAP_ENCODED;
-                       } else {
-                               h->use = SOAP_LITERAL;
-                       }
-
-                       tmp = get_attribute(header->properties, "namespace");
-                       if (tmp) {
-                               h->ns = estrdup(tmp->children->content);
-                       }
-
-                       if (h->use == SOAP_ENCODED) {
-                               tmp = get_attribute(header->properties, 
"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 {
-                                       php_error(E_ERROR, "SOAP-ERROR: Parsing WSDL: 
Unspecified encodingStyle");
-                               }
-                       }
-
-                       tmp = get_attribute(part->properties, "type");
-                       if (tmp != NULL) {
-                               h->encode = get_encoder_from_prefix(ctx->sdl, part, 
tmp->children->content);
-                       } else {
-                               tmp = get_attribute(part->properties, "element");
-                               if (tmp != NULL) {
-                                       h->element = get_element(ctx->sdl, part, 
tmp->children->content);
-                                       if (h->element) {
-                                               h->encode = h->element->encode;
-                                               if (!h->ns && h->element->namens) {
-                                                       h->ns = 
estrdup(h->element->namens);
-                                               }
-                                       }
-                               }
-                       }
-
                        if (binding->headers == NULL) {
                                binding->headers = emalloc(sizeof(HashTable));
                                zend_hash_init(binding->headers, 0, NULL, 
delete_header, 0);
@@ -471,7 +504,7 @@
                ++ctype;
        }
        if (zend_hash_find(&ctx->messages, ctype, strlen(ctype)+1, (void**)&tmp) != 
SUCCESS) {
-               php_error(E_ERROR, "SOAP-ERROR: Parsing WSDL: Missing <message> with 
name '%s'", message->children->content);
+               php_error(E_ERROR, "SOAP-ERROR: Parsing WSDL: Missing <message> with 
name '%s'", message_name);
        }
        message = *tmp;
 
@@ -960,7 +993,7 @@
        return ctx.sdl;
 }
 
-#define WSDL_CACHE_VERSION 0x08
+#define WSDL_CACHE_VERSION 0x09
 
 #define WSDL_CACHE_GET(ret,type,buf)   memcpy(&ret,*buf,sizeof(type)); *buf += 
sizeof(type);
 #define WSDL_CACHE_GET_INT(ret,buf)    ret = ((unsigned char)(*buf)[0])|((unsigned 
char)(*buf)[1]<<8)|((unsigned char)(*buf)[2]<<16)|((int)(*buf)[3]<<24); *buf += 4;
@@ -1198,7 +1231,7 @@
 
 static void sdl_deserialize_soap_body(sdlSoapBindingFunctionBodyPtr body, encodePtr 
*encoders, sdlTypePtr *types, char **in)
 {
-       int i, n;
+       int i, j, n;
 
        WSDL_CACHE_GET_1(body->use, sdlEncodingUse, in);
        if (body->use == SOAP_ENCODED) {
@@ -1214,6 +1247,7 @@
                zend_hash_init(body->headers, i, NULL, delete_header, 0);
                while (i > 0) {
                        sdlSoapBindingFunctionHeaderPtr tmp = 
emalloc(sizeof(sdlSoapBindingFunctionHeader));
+                       memset(tmp, 0, sizeof(sdlSoapBindingFunctionHeader));
                        sdl_deserialize_key(body->headers, tmp, in);
                        WSDL_CACHE_GET_1(tmp->use, sdlEncodingUse, in);
                        if (tmp->use == SOAP_ENCODED) {
@@ -1228,6 +1262,29 @@
                        WSDL_CACHE_GET_INT(n, in);
                        tmp->element = types[n];
                        --i;
+                       WSDL_CACHE_GET_INT(j, in);
+                       if (j > 0) {
+                               tmp->headerfaults = emalloc(sizeof(HashTable));
+                               zend_hash_init(tmp->headerfaults, i, NULL, 
delete_header, 0);
+                               while (j > 0) {
+                                       sdlSoapBindingFunctionHeaderPtr tmp2 = 
emalloc(sizeof(sdlSoapBindingFunctionHeader));
+                                       memset(tmp2, 0, 
sizeof(sdlSoapBindingFunctionHeader));
+                                       sdl_deserialize_key(tmp->headerfaults, tmp2, 
in);
+                                       WSDL_CACHE_GET_1(tmp2->use, sdlEncodingUse, 
in);
+                                       if (tmp2->use == SOAP_ENCODED) {
+                                               WSDL_CACHE_GET_1(tmp2->encodingStyle, 
sdlRpcEncodingStyle, in);
+                                       } else {
+                                               tmp2->encodingStyle = 
SOAP_ENCODING_DEFAULT;
+                                       }
+                                       tmp2->name = sdl_deserialize_string(in);
+                                       tmp2->ns = sdl_deserialize_string(in);
+                                       WSDL_CACHE_GET_INT(n, in);
+                                       tmp->encode = encoders[n];
+                                       WSDL_CACHE_GET_INT(n, in);
+                                       tmp->element = types[n];
+                                       --j;
+                               }
+                       }
                }
        }
 }
@@ -1776,7 +1833,7 @@
 
 static void sdl_serialize_soap_body(sdlSoapBindingFunctionBodyPtr body, HashTable 
*tmp_encoders, HashTable *tmp_types, smart_str *out)
 {
-       int i;
+       int i, j;
 
        WSDL_CACHE_PUT_1(body->use, out);
        if (body->use == SOAP_ENCODED) {
@@ -1803,6 +1860,28 @@
                        sdl_serialize_string((*tmp)->ns, out);
                        sdl_serialize_encoder_ref((*tmp)->encode, tmp_encoders, out);
                        sdl_serialize_type_ref((*tmp)->element, tmp_types, out);
+                       if ((*tmp)->headerfaults) {
+                               j = zend_hash_num_elements((*tmp)->headerfaults);
+                       } else {
+                               j = 0;
+                       }
+                       WSDL_CACHE_PUT_INT(j, out);
+                       if (j > 0) {
+                               sdlSoapBindingFunctionHeaderPtr *tmp2;
+                               zend_hash_internal_pointer_reset((*tmp)->headerfaults);
+                               while 
(zend_hash_get_current_data((*tmp)->headerfaults, (void**)&tmp2) == SUCCESS) {
+                                       sdl_serialize_key((*tmp)->headerfaults, out);
+                                       WSDL_CACHE_PUT_1((*tmp2)->use, out);
+                                       if ((*tmp2)->use == SOAP_ENCODED) {
+                                               
WSDL_CACHE_PUT_1((*tmp2)->encodingStyle, out);
+                                       }
+                                       sdl_serialize_string((*tmp2)->name, out);
+                                       sdl_serialize_string((*tmp2)->ns, out);
+                                       sdl_serialize_encoder_ref((*tmp2)->encode, 
tmp_encoders, out);
+                                       sdl_serialize_type_ref((*tmp2)->element, 
tmp_types, out);
+                                       zend_hash_move_forward((*tmp)->headerfaults);
+                               }
+                       }
                        zend_hash_move_forward(body->headers);
                }
        }
@@ -2261,6 +2340,10 @@
        if (hdr->ns) {
                efree(hdr->ns);
        }
+       if (hdr->headerfaults) {
+               zend_hash_destroy(hdr->headerfaults);
+               efree(hdr->headerfaults);
+       }
        efree(hdr);
 }
 
http://cvs.php.net/diff.php/php-src/ext/soap/php_sdl.h?r1=1.30&r2=1.31&ty=u
Index: php-src/ext/soap/php_sdl.h
diff -u php-src/ext/soap/php_sdl.h:1.30 php-src/ext/soap/php_sdl.h:1.31
--- php-src/ext/soap/php_sdl.h:1.30     Thu Feb 19 03:21:13 2004
+++ php-src/ext/soap/php_sdl.h  Tue Feb 24 10:06:41 2004
@@ -17,7 +17,7 @@
   |          Dmitry Stogov <[EMAIL PROTECTED]>                             |
   +----------------------------------------------------------------------+
 */
-/* $Id: php_sdl.h,v 1.30 2004/02/19 08:21:13 dmitry Exp $ */
+/* $Id: php_sdl.h,v 1.31 2004/02/24 15:06:41 dmitry Exp $ */
 
 #ifndef PHP_SDL_H
 #define PHP_SDL_H
@@ -97,6 +97,7 @@
        sdlTypePtr           element;
        encodePtr            encode;
        sdlRpcEncodingStyle  encodingStyle; /* not implemented yet */
+       HashTable           *headerfaults;  /* array of 
sdlSoapBindingFunctionHeaderPtr */
 } sdlSoapBindingFunctionHeader, *sdlSoapBindingFunctionHeaderPtr;
 
 typedef struct _sdlSoapBindingFunctionFault {
http://cvs.php.net/diff.php/php-src/ext/soap/soap.c?r1=1.90&r2=1.91&ty=u
Index: php-src/ext/soap/soap.c
diff -u php-src/ext/soap/soap.c:1.90 php-src/ext/soap/soap.c:1.91
--- php-src/ext/soap/soap.c:1.90        Thu Feb 19 11:45:25 2004
+++ php-src/ext/soap/soap.c     Tue Feb 24 10:06:41 2004
@@ -17,7 +17,7 @@
   |          Dmitry Stogov <[EMAIL PROTECTED]>                             |
   +----------------------------------------------------------------------+
 */
-/* $Id: soap.c,v 1.90 2004/02/19 16:45:25 dmitry Exp $ */
+/* $Id: soap.c,v 1.91 2004/02/24 15:06:41 dmitry Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -50,7 +50,7 @@
 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, 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 void soap_server_fault_ex(sdlFunctionPtr function, zval* fault, soapHeader* 
hdr TSRMLS_DC);
 
 static sdlParamPtr get_param(sdlFunctionPtr function, char *param_name, int index, 
int);
 static sdlFunctionPtr get_function(sdlPtr sdl, const char *function_name);
@@ -668,18 +668,20 @@
 {
        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;
+       zval *details = NULL, *headerfault = NULL;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|s!z!s",
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|s!z!s!z",
                &fault_code, &fault_code_len,
                &fault_string, &fault_string_len,
                &fault_actor, &fault_actor_len,
-               &details,
-               &name, &name_len) == FAILURE) {
+               &details, &name, &name_len, &headerfault) == FAILURE) {
                php_error(E_ERROR, "Invalid arguments to SoapFault constructor");
        }
 
        set_soap_fault(this_ptr, fault_code, fault_string, fault_actor, details, name 
TSRMLS_CC);
+       if (headerfault != NULL) {
+               add_property_zval(this_ptr, "headerfault", headerfault);
+       }
 }
 
 #ifdef ZEND_ENGINE_2
@@ -1328,7 +1330,7 @@
                                if (EG(exception) &&
                                    Z_TYPE_P(EG(exception)) == IS_OBJECT &&
                                    Z_OBJCE_P(EG(exception)) == 
soap_fault_class_entry) {
-                                       soap_server_fault_ex(function, EG(exception) 
TSRMLS_CC);
+                                       soap_server_fault_ex(function, EG(exception), 
NULL TSRMLS_CC);
                                }
 #endif
                                zval_dtor(&constructor);
@@ -1385,7 +1387,29 @@
                                        call_status = 
call_user_function(EG(function_table), NULL, &h->function_name, &h->retval, 
h->num_params, h->parameters TSRMLS_CC);
                                }
                                if (call_status != SUCCESS) {
-                                       php_error(E_ERROR, "Function '%s' call 
failed", Z_STRVAL(function_name));
+                                       php_error(E_ERROR, "Function '%s' call 
failed", Z_STRVAL(h->function_name));
+                               }
+                               if (Z_TYPE(h->retval) == IS_OBJECT &&
+                                   Z_OBJCE(h->retval) == soap_fault_class_entry) {
+                                 zval *headerfault = NULL, **tmp;
+
+                                       if (zend_hash_find(Z_OBJPROP(h->retval), 
"headerfault", sizeof("headerfault"), (void**)&tmp) == SUCCESS &&
+                                           Z_TYPE_PP(tmp) != IS_NULL) {
+                                               headerfault = *tmp;
+                                       }
+                                       soap_server_fault_ex(function, &h->retval, h 
TSRMLS_CC);
+#ifdef ZEND_ENGINE_2
+                               } else if (EG(exception) &&
+                                          Z_TYPE_P(EG(exception)) == IS_OBJECT &&
+                                          Z_OBJCE_P(EG(exception)) == 
soap_fault_class_entry) {
+                                 zval *headerfault = NULL, **tmp;
+
+                                       if (zend_hash_find(Z_OBJPROP_P(EG(exception)), 
"headerfault", sizeof("headerfault"), (void**)&tmp) == SUCCESS &&
+                                           Z_TYPE_PP(tmp) != IS_NULL) {
+                                               headerfault = *tmp;
+                                       }
+                                       soap_server_fault_ex(function, EG(exception), 
h TSRMLS_CC);
+#endif
                                }
                        } else if (h->mustUnderstand) {
                                soap_server_fault("MustUnderstand","Header not 
understood", NULL, NULL, NULL TSRMLS_CC);
@@ -1413,7 +1437,7 @@
        if (EG(exception) &&
            Z_TYPE_P(EG(exception)) == IS_OBJECT &&
            Z_OBJCE_P(EG(exception)) == soap_fault_class_entry) {
-               soap_server_fault_ex(function, EG(exception) TSRMLS_CC);
+               soap_server_fault_ex(function, EG(exception), NULL TSRMLS_CC);
        }
 #endif
        if (call_status == SUCCESS) {
@@ -1421,7 +1445,7 @@
 
                if (Z_TYPE(retval) == IS_OBJECT &&
                    Z_OBJCE(retval) == soap_fault_class_entry) {
-                       soap_server_fault_ex(function, &retval TSRMLS_CC);
+                       soap_server_fault_ex(function, &retval, NULL TSRMLS_CC);
                }
 
                if (function && function->responseName) {
@@ -1513,7 +1537,7 @@
        SOAP_SERVER_END_CODE();
 }
 
-static void soap_server_fault_ex(sdlFunctionPtr function, zval* fault TSRMLS_DC)
+static void soap_server_fault_ex(sdlFunctionPtr function, zval* fault, soapHeader 
*hdr TSRMLS_DC)
 {
        int soap_version;
        xmlChar *buf, cont_len[30];
@@ -1522,7 +1546,7 @@
 
        soap_version = SOAP_GLOBAL(soap_version);
 
-       doc_return = serialize_response_call(function, NULL, NULL, fault, NULL, 
soap_version TSRMLS_CC);
+       doc_return = serialize_response_call(function, NULL, NULL, fault, hdr, 
soap_version TSRMLS_CC);
 
        xmlDocDumpMemory(doc_return, &buf, &size);
 
@@ -1553,7 +1577,7 @@
 
        set_soap_fault(&ret, code, string, actor, details, name TSRMLS_CC);
        /* TODO: Which function */
-       soap_server_fault_ex(NULL, &ret TSRMLS_CC);
+       soap_server_fault_ex(NULL, &ret, NULL TSRMLS_CC);
 }
 
 static void soap_error_handler(int error_num, const char *error_filename, const uint 
error_lineno, const char *format, va_list args)
@@ -2678,6 +2702,65 @@
                sdlFaultPtr fault = NULL;
 
                prop = Z_OBJPROP_P(ret);
+
+               if (headers &&
+                   zend_hash_find(prop, "headerfault", sizeof("headerfault"), 
(void**)&tmp) == SUCCESS) {
+                       xmlNodePtr head;
+                       encodePtr hdr_enc = NULL;
+                       int hdr_use = SOAP_LITERAL;
+                       zval *hdr_ret  = *tmp;
+                       char *hdr_ns   = headers->hdr?headers->hdr->ns:NULL;
+                       char *hdr_name = Z_STRVAL(headers->function_name);
+
+                       head = xmlNewChild(envelope, ns, "Header", NULL);
+                       if (Z_TYPE_P(hdr_ret) == IS_OBJECT &&
+                           Z_OBJCE_P(hdr_ret) == soap_header_class_entry) {
+                               HashTable* ht = Z_OBJPROP_P(hdr_ret);
+                               zval **tmp;
+                               sdlSoapBindingFunctionHeaderPtr *hdr;
+                               smart_str key = {0};
+
+                               if (zend_hash_find(ht, "namespace", 
sizeof("namespace"), (void**)&tmp) == SUCCESS &&
+                             Z_TYPE_PP(tmp) == IS_STRING) {
+                                       smart_str_appendl(&key, Z_STRVAL_PP(tmp), 
Z_STRLEN_PP(tmp));
+                                       smart_str_appendc(&key, ':');
+                                       hdr_ns = Z_STRVAL_PP(tmp);
+                               }
+                               if (zend_hash_find(ht, "name", sizeof("name"), 
(void**)&tmp) == SUCCESS &&
+                                   Z_TYPE_PP(tmp) == IS_STRING) {
+                                       smart_str_appendl(&key, Z_STRVAL_PP(tmp), 
Z_STRLEN_PP(tmp));
+                                       hdr_name = Z_STRVAL_PP(tmp);
+                               }
+                               smart_str_0(&key);
+                               if (headers->hdr && headers->hdr->headerfaults &&
+                                   zend_hash_find(headers->hdr->headerfaults, key.c, 
key.len+1, (void**)&hdr) == SUCCESS) {
+                                       hdr_enc = (*hdr)->encode;
+                                       hdr_use = (*hdr)->use;
+                               }
+                               smart_str_free(&key);
+                               if (zend_hash_find(ht, "data", sizeof("data"), 
(void**)&tmp) == SUCCESS) {
+                                       hdr_ret = *tmp;
+                               } else {
+                                       hdr_ret = NULL;
+                               }
+                       }
+
+                       if (headers->function) {
+                               if (serialize_response_call2(head, headers->function, 
Z_STRVAL(headers->function_name), uri, hdr_ret, version, 0 TSRMLS_CC) == SOAP_ENCODED) 
{
+                                       use = SOAP_ENCODED;
+                               }
+                       } else {
+                               xmlNodePtr xmlHdr = master_to_xml(hdr_enc, hdr_ret, 
hdr_use, head);
+                               if (hdr_name) {
+                                       xmlNodeSetName(xmlHdr,hdr_name);
+                               }
+                               if (hdr_ns) {
+                                       xmlNsPtr nsptr = encode_add_ns(xmlHdr,hdr_ns);
+                                       xmlSetNs(xmlHdr, nsptr);
+                               }
+                       }
+               }
+
                body = xmlNewChild(envelope, ns, "Body", NULL);
                param = xmlNewChild(body, ns, "Fault", NULL);
 
@@ -2816,33 +2899,31 @@
                                            Z_OBJCE(h->retval) == 
soap_header_class_entry) {
                                                HashTable* ht = Z_OBJPROP(h->retval);
                                                zval **tmp;
+                                               sdlSoapBindingFunctionHeaderPtr *hdr;
+                                               smart_str key = {0};
 
+                                               if (zend_hash_find(ht, "namespace", 
sizeof("namespace"), (void**)&tmp) == SUCCESS &&
+                                             Z_TYPE_PP(tmp) == IS_STRING) {
+                                                       smart_str_appendl(&key, 
Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
+                                                       smart_str_appendc(&key, ':');
+                                                       hdr_ns = Z_STRVAL_PP(tmp);
+                                               }
+                                               if (zend_hash_find(ht, "name", 
sizeof("name"), (void**)&tmp) == SUCCESS &&
+                                                   Z_TYPE_PP(tmp) == IS_STRING) {
+                                                       smart_str_appendl(&key, 
Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
+                                                       hdr_name = Z_STRVAL_PP(tmp);
+                                               }
+                                               smart_str_0(&key);
                                                if (function && function->binding && 
function->binding->bindingType == BINDING_SOAP) {
                                                        sdlSoapBindingFunctionPtr fnb 
= (sdlSoapBindingFunctionPtr)function->bindingAttributes;
 
-                                                       if (fnb->output.headers) {
-                                                               
sdlSoapBindingFunctionHeaderPtr *hdr;
-                                                               smart_str key = {0};
-
-                                                               if (zend_hash_find(ht, 
"namespace", sizeof("namespace"), (void**)&tmp) == SUCCESS &&
-                                                             Z_TYPE_PP(tmp) == 
IS_STRING) {
-                                                                       
smart_str_appendl(&key, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
-                                                                       
smart_str_appendc(&key, ':');
-                                                                       hdr_ns = 
Z_STRVAL_PP(tmp);
-                                                               }
-                                                               if (zend_hash_find(ht, 
"name", sizeof("name"), (void**)&tmp) == SUCCESS &&
-                                                                   Z_TYPE_PP(tmp) == 
IS_STRING) {
-                                                                       
smart_str_appendl(&key, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
-                                                                       hdr_name = 
Z_STRVAL_PP(tmp);
-                                                               }
-                                                               smart_str_0(&key);
-                                                               if 
(zend_hash_find(fnb->output.headers, key.c, key.len+1, (void**)&hdr) == SUCCESS) {
-                                                                       hdr_enc = 
(*hdr)->encode;
-                                                                       hdr_use = 
(*hdr)->use;
-                                                               }
-                                                               smart_str_free(&key);
+                                                       if (fnb->output.headers &&
+                                                           
zend_hash_find(fnb->output.headers, key.c, key.len+1, (void**)&hdr) == SUCCESS) {
+                                                               hdr_enc = 
(*hdr)->encode;
+                                                               hdr_use = (*hdr)->use;
                                                        }
                                                }
+                                               smart_str_free(&key);
                                                if (zend_hash_find(ht, "data", 
sizeof("data"), (void**)&tmp) == SUCCESS) {
                                                        hdr_ret = *tmp;
                                                } else {
@@ -3172,7 +3253,7 @@
        } else {
                ht = function->responseParameters;
        }
-       
+
        if (ht == NULL) {
          return NULL;
        }
http://cvs.php.net/diff.php/php-src/ext/soap/tests/soap12/soap12-test.inc?r1=1.7&r2=1.8&ty=u
Index: php-src/ext/soap/tests/soap12/soap12-test.inc
diff -u php-src/ext/soap/tests/soap12/soap12-test.inc:1.7 
php-src/ext/soap/tests/soap12/soap12-test.inc:1.8
--- php-src/ext/soap/tests/soap12/soap12-test.inc:1.7   Thu Feb  5 15:26:05 2004
+++ php-src/ext/soap/tests/soap12/soap12-test.inc       Tue Feb 24 10:06:42 2004
@@ -111,6 +111,15 @@
        function echoResolvedRef($ref) {
          return $ref->RelativeReference->base.$ref->RelativeReference->href;
        }
+
+       function validateCountryCode($code) {
+               if (strlen($code) != 2) {
+                 return new SoapFault("Client", "Not a valid country code", NULL, 
NULL, NULL, new SoapHeader("http://example.org/ts-tests";, "validateCountryCodeFault", 
"Country code must be 2 letters."));
+               } else {
+                       return "OK";
+               }
+       }
+
 }
 
 $server = new soapserver(dirname(__FILE__)."/soap12-test.wsdl", 
array('soap_version'=>SOAP_1_2,'actor'=>"http://example.org/ts-tests/C";));
http://cvs.php.net/diff.php/php-src/ext/soap/tests/soap12/soap12-test.wsdl?r1=1.3&r2=1.4&ty=u
Index: php-src/ext/soap/tests/soap12/soap12-test.wsdl
diff -u php-src/ext/soap/tests/soap12/soap12-test.wsdl:1.3 
php-src/ext/soap/tests/soap12/soap12-test.wsdl:1.4
--- php-src/ext/soap/tests/soap12/soap12-test.wsdl:1.3  Mon Feb  2 12:39:10 2004
+++ php-src/ext/soap/tests/soap12/soap12-test.wsdl      Tue Feb 24 10:06:42 2004
@@ -125,6 +125,8 @@
                        <!-- 3.2.9 validateCountryCode -->
                        <element name="validateCountryCode" type="xsd:string"/>
 
+                       <element name="validateCountryCodeResponse" type="xsd:string"/>
+
                        <!-- 3.2.10 validateCountryCodeFault -->
                        <element name="validateCountryCodeFault" type="xsd:string"/>
 
@@ -346,6 +348,17 @@
                <part name="Unknown" type="types:UnknownType" />
        </message>
 
+       <message name="validateCountryCodeRequest">
+               <part name="validateCountryCode" element="test:validateCountryCode" />
+       </message>
+       <message name="validateCountryCodeFault">
+               <part name="validateCountryCodeFault" 
element="test:validateCountryCodeFault" />
+       </message>
+       <message name="validateCountryCodeResponse">
+               <part name="validateCountryCodeResponse" 
element="test:validateCountryCodeResponse" />
+       </message>
+
+
        <portType name="Soap12TestPortTypeDoc">
                <operation name="emptyBody">
                        <input message="tns:emptyBodyRequest" />
@@ -487,13 +500,15 @@
                        <input>
                                <soap12:body use="literal" />
                                <soap12:header message="tns:echoOkRequest" 
part="echoOk" use="literal" />
-                               <soap12:header message="tns:UnknownHdrBlockLit" 
part="Unknown" use="literal" />
-
+                               <soap12:header message="tns:UnknownHdrBlockLit" 
part="Unknown" use="literal" />
+                               <soap12:header 
message="tns:validateCountryCodeRequest" part="validateCountryCode" use="literal">
+                                 <soap12:headerfault 
message="tns:validateCountryCodeFault" part="validateCountryCodeFault" use="literal"/>
+                               </soap12:header>
                        </input>
                        <output>
                                <soap12:body use="literal" />
                                <soap12:header message="tns:echoOkResponse" 
part="responseOk" use="literal" />
-
+                               <soap12:header 
message="tns:validateCountryCodeResponse" part="validateCountryCodeResponse" 
use="literal"/>
                        </output>
                </operation>
                <operation name="echoOk">

http://cvs.php.net/co.php/php-src/ext/soap/tests/soap12/T63.phpt?r=1.1&p=1
Index: php-src/ext/soap/tests/soap12/T63.phpt
+++ php-src/ext/soap/tests/soap12/T63.phpt
--TEST--
SOAP 1.2: T63 validateCountryCode
--SKIPIF--
<?php require_once('skipif.inc'); ?>
--FILE--
<?php
$HTTP_RAW_POST_DATA = <<<EOF
<?xml version='1.0' ?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope";> 
  <env:Header>
    <test:validateCountryCode xmlns:test="http://example.org/ts-tests";
          env:role="http://example.org/ts-tests/C";
          env:mustUnderstand="1">ABCD</test:validateCountryCode>
  </env:Header>
  <env:Body>
  </env:Body>
</env:Envelope>

EOF;
include "soap12-test.inc";
?>
--EXPECT--
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope"; 
xmlns:ns1="http://example.org/ts-tests";><env:Header><ns1:validateCountryCodeFault>Country
 code must be 2 
letters.</ns1:validateCountryCodeFault></env:Header><env:Body><env:Fault><env:Code><env:Value>env:Sender</env:Value></env:Code><env:Reason><env:Text>Not
 a valid country code</env:Text></env:Reason></env:Fault></env:Body></env:Envelope>

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

Reply via email to