----
? 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
- function/method overloading/redeclaration (test(int); test(string))
- wsdl auto generation
- HTTP GET/POST binding
+- SOAP security extension
Schema
------
}
}
+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;
}
}
} 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);
++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;
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;
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) {
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) {
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;
+ }
+ }
}
}
}
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) {
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);
}
}
if (hdr->ns) {
efree(hdr->ns);
}
+ if (hdr->headerfaults) {
+ zend_hash_destroy(hdr->headerfaults);
+ efree(hdr->headerfaults);
+ }
efree(hdr);
}
sdlTypePtr element;
encodePtr encode;
sdlRpcEncodingStyle encodingStyle; /* not implemented yet */
+ HashTable *headerfaults; /* array of sdlSoapBindingFunctionHeaderPtr */
} sdlSoapBindingFunctionHeader, *sdlSoapBindingFunctionHeaderPtr;
typedef struct _sdlSoapBindingFunctionFault {
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);
{
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
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);
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);
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) {
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) {
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];
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);
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)
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);
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 {
} else {
ht = function->responseParameters;
}
-
+
if (ht == NULL) {
return NULL;
}
--- /dev/null
+--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>
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"));
<!-- 3.2.9 validateCountryCode -->\r
<element name="validateCountryCode" type="xsd:string"/>\r
\r
+ <element name="validateCountryCodeResponse" type="xsd:string"/>\r
+\r
<!-- 3.2.10 validateCountryCodeFault -->\r
<element name="validateCountryCodeFault" type="xsd:string"/>\r
\r
<part name="Unknown" type="types:UnknownType" />\r
</message>\r
\r
+ <message name="validateCountryCodeRequest">\r
+ <part name="validateCountryCode" element="test:validateCountryCode" />\r
+ </message>\r
+ <message name="validateCountryCodeFault">\r
+ <part name="validateCountryCodeFault" element="test:validateCountryCodeFault" />\r
+ </message>\r
+ <message name="validateCountryCodeResponse">\r
+ <part name="validateCountryCodeResponse" element="test:validateCountryCodeResponse" />\r
+ </message>\r
+\r
+\r
<portType name="Soap12TestPortTypeDoc">\r
<operation name="emptyBody">\r
<input message="tns:emptyBodyRequest" />\r
<input>\r
<soap12:body use="literal" />\r
<soap12:header message="tns:echoOkRequest" part="echoOk" use="literal" />\r
- <soap12:header message="tns:UnknownHdrBlockLit" part="Unknown" use="literal" />\r
-\r
+ <soap12:header message="tns:UnknownHdrBlockLit" part="Unknown" use="literal" />\r
+ <soap12:header message="tns:validateCountryCodeRequest" part="validateCountryCode" use="literal">\r
+ <soap12:headerfault message="tns:validateCountryCodeFault" part="validateCountryCodeFault" use="literal"/>\r
+ </soap12:header>\r
</input>\r
<output>\r
<soap12:body use="literal" />\r
<soap12:header message="tns:echoOkResponse" part="responseOk" use="literal" />\r
-\r
+ <soap12:header message="tns:validateCountryCodeResponse" part="validateCountryCodeResponse" use="literal"/>\r
</output>\r
</operation>\r
<operation name="echoOk">\r