PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - soap - php_packet_soap.c
Test: PHP Code Coverage
Date: 2009-11-23 Instrumented lines: 251
Code covered: 58.6 % Executed lines: 147
Legend: not executed executed

       1                 : /*
       2                 :   +----------------------------------------------------------------------+
       3                 :   | PHP Version 6                                                        |
       4                 :   +----------------------------------------------------------------------+
       5                 :   | Copyright (c) 1997-2009 The PHP Group                                |
       6                 :   +----------------------------------------------------------------------+
       7                 :   | This source file is subject to version 3.01 of the PHP license,      |
       8                 :   | that is bundled with this package in the file LICENSE, and is        |
       9                 :   | available through the world-wide-web at the following url:           |
      10                 :   | http://www.php.net/license/3_01.txt                                  |
      11                 :   | If you did not receive a copy of the PHP license and are unable to   |
      12                 :   | obtain it through the world-wide-web, please send a note to          |
      13                 :   | license@php.net so we can mail you a copy immediately.               |
      14                 :   +----------------------------------------------------------------------+
      15                 :   | Authors: Brad Lafountain <rodif_bl@yahoo.com>                        |
      16                 :   |          Shane Caraveo <shane@caraveo.com>                           |
      17                 :   |          Dmitry Stogov <dmitry@zend.com>                             |
      18                 :   +----------------------------------------------------------------------+
      19                 : */
      20                 : /* $Id: php_packet_soap.c 278112 2009-04-01 09:38:41Z kalle $ */
      21                 : 
      22                 : #include "php_soap.h"
      23                 : 
      24                 : /* SOAP client calls this function to parse response from SOAP server */
      25                 : int parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctionPtr fn, char *fn_name, zval *return_value, zval *soap_headers TSRMLS_DC)
      26              67 : {
      27              67 :         char* envelope_ns = NULL;
      28                 :         xmlDocPtr response;
      29                 :         xmlNodePtr trav, env, head, body, resp, cur, fault;
      30                 :         xmlAttrPtr attr;
      31              67 :         int param_count = 0;
      32              67 :         int soap_version = SOAP_1_1;
      33              67 :         HashTable *hdrs = NULL;
      34                 : 
      35              67 :         ZVAL_NULL(return_value);
      36                 : 
      37                 :         /* Response for one-way opearation */
      38              67 :         if (buffer_size == 0) {
      39               1 :                 return TRUE;
      40                 :         }
      41                 : 
      42                 :         /* Parse XML packet */
      43              66 :         response = soap_xmlParseMemory(buffer, buffer_size);
      44                 : 
      45              66 :         if (!response) {
      46               1 :                 add_soap_fault(this_ptr, "Client", "looks like we got no XML document", NULL, NULL TSRMLS_CC);
      47               1 :                 return FALSE;
      48                 :         }
      49              65 :         if (xmlGetIntSubset(response) != NULL) {
      50               0 :                 add_soap_fault(this_ptr, "Client", "DTD are not supported by SOAP", NULL, NULL TSRMLS_CC);
      51               0 :                 xmlFreeDoc(response);
      52               0 :                 return FALSE;
      53                 :         }
      54                 : 
      55                 :         /* Get <Envelope> element */
      56              65 :         env = NULL;
      57              65 :         trav = response->children;
      58             195 :         while (trav != NULL) {
      59              65 :                 if (trav->type == XML_ELEMENT_NODE) {
      60             130 :                         if (env == NULL && node_is_equal_ex(trav,"Envelope",SOAP_1_1_ENV_NAMESPACE)) {
      61              65 :                                 env = trav;
      62              65 :                                 envelope_ns = SOAP_1_1_ENV_NAMESPACE;
      63              65 :                                 soap_version = SOAP_1_1;
      64               0 :                         } else if (env == NULL && node_is_equal_ex(trav,"Envelope",SOAP_1_2_ENV_NAMESPACE)) {
      65               0 :                                 env = trav;
      66               0 :                                 envelope_ns = SOAP_1_2_ENV_NAMESPACE;
      67               0 :                                 soap_version = SOAP_1_2;
      68                 :                         } else {
      69               0 :                                 add_soap_fault(this_ptr, "VersionMismatch", "Wrong Version", NULL, NULL TSRMLS_CC);
      70               0 :                                 xmlFreeDoc(response);
      71               0 :                                 return FALSE;
      72                 :                         }
      73                 :                 }
      74              65 :                 trav = trav->next;
      75                 :         }
      76              65 :         if (env == NULL) {
      77               0 :                 add_soap_fault(this_ptr, "Client", "looks like we got XML without \"Envelope\" element", NULL, NULL TSRMLS_CC);
      78               0 :                 xmlFreeDoc(response);
      79               0 :                 return FALSE;
      80                 :         }
      81                 : 
      82              65 :         attr = env->properties;
      83             173 :         while (attr != NULL) {
      84              43 :                 if (attr->ns == NULL) {
      85               0 :                         add_soap_fault(this_ptr, "Client", "A SOAP Envelope element cannot have non Namespace qualified attributes", NULL, NULL TSRMLS_CC);
      86               0 :                         xmlFreeDoc(response);
      87               0 :                         return FALSE;
      88              43 :                 } else if (attr_is_equal_ex(attr,"encodingStyle",SOAP_1_2_ENV_NAMESPACE)) {
      89               0 :                         if (soap_version == SOAP_1_2) {
      90               0 :                                 add_soap_fault(this_ptr, "Client", "encodingStyle cannot be specified on the Envelope", NULL, NULL TSRMLS_CC);
      91               0 :                                 xmlFreeDoc(response);
      92               0 :                                 return FALSE;
      93               0 :                         } else if (strcmp((char*)attr->children->content, SOAP_1_1_ENC_NAMESPACE) != 0) {
      94               0 :                                 add_soap_fault(this_ptr, "Client", "Unknown data encoding style", NULL, NULL TSRMLS_CC);
      95               0 :                                 xmlFreeDoc(response);
      96               0 :                                 return FALSE;
      97                 :                         }
      98                 :                 }
      99              43 :                 attr = attr->next;
     100                 :         }
     101                 : 
     102                 :         /* Get <Header> element */
     103              65 :         head = NULL;
     104              65 :         trav = env->children;
     105             130 :         while (trav != NULL && trav->type != XML_ELEMENT_NODE) {
     106               0 :                 trav = trav->next;
     107                 :         }
     108              65 :         if (trav != NULL && node_is_equal_ex(trav,"Header",envelope_ns)) {
     109               0 :                 head = trav;
     110               0 :                 trav = trav->next;
     111                 :         }
     112                 : 
     113                 :         /* Get <Body> element */
     114              65 :         body = NULL;
     115             130 :         while (trav != NULL && trav->type != XML_ELEMENT_NODE) {
     116               0 :                 trav = trav->next;
     117                 :         }
     118              65 :         if (trav != NULL && node_is_equal_ex(trav,"Body",envelope_ns)) {
     119              65 :                 body = trav;
     120              65 :                 trav = trav->next;
     121                 :         }
     122             130 :         while (trav != NULL && trav->type != XML_ELEMENT_NODE) {
     123               0 :                 trav = trav->next;
     124                 :         }
     125              65 :         if (body == NULL) {
     126               0 :                 add_soap_fault(this_ptr, "Client", "Body must be present in a SOAP envelope", NULL, NULL TSRMLS_CC);
     127               0 :                 xmlFreeDoc(response);
     128               0 :                 return FALSE;
     129                 :         }
     130              65 :         attr = body->properties;
     131             133 :         while (attr != NULL) {
     132               3 :                 if (attr->ns == NULL) {
     133               2 :                         if (soap_version == SOAP_1_2) {
     134               0 :                                 add_soap_fault(this_ptr, "Client", "A SOAP Body element cannot have non Namespace qualified attributes", NULL, NULL TSRMLS_CC);
     135               0 :                                 xmlFreeDoc(response);
     136               0 :                                 return FALSE;
     137                 :                         }
     138               1 :                 } else if (attr_is_equal_ex(attr,"encodingStyle",SOAP_1_2_ENV_NAMESPACE)) {
     139               0 :                         if (soap_version == SOAP_1_2) {
     140               0 :                                 add_soap_fault(this_ptr, "Client", "encodingStyle cannot be specified on the Body", NULL, NULL TSRMLS_CC);
     141               0 :                                 xmlFreeDoc(response);
     142               0 :                                 return FALSE;
     143               0 :                         } else if (strcmp((char*)attr->children->content, SOAP_1_1_ENC_NAMESPACE) != 0) {
     144               0 :                                 add_soap_fault(this_ptr, "Client", "Unknown data encoding style", NULL, NULL TSRMLS_CC);
     145               0 :                                 xmlFreeDoc(response);
     146               0 :                                 return FALSE;
     147                 :                         }
     148                 :                 }
     149               3 :                 attr = attr->next;
     150                 :         }
     151              65 :         if (trav != NULL && soap_version == SOAP_1_2) {
     152               0 :                 add_soap_fault(this_ptr, "Client", "A SOAP 1.2 envelope can contain only Header and Body", NULL, NULL TSRMLS_CC);
     153               0 :                 xmlFreeDoc(response);
     154               0 :                 return FALSE;
     155                 :         }
     156                 : 
     157              65 :         if (head != NULL) {
     158               0 :                 attr = head->properties;
     159               0 :                 while (attr != NULL) {
     160               0 :                         if (attr->ns == NULL) {
     161               0 :                                 add_soap_fault(this_ptr, "Client", "A SOAP Header element cannot have non Namespace qualified attributes", NULL, NULL TSRMLS_CC);
     162               0 :                                 xmlFreeDoc(response);
     163               0 :                                 return FALSE;
     164               0 :                         } else if (attr_is_equal_ex(attr,"encodingStyle",SOAP_1_2_ENV_NAMESPACE)) {
     165               0 :                                 if (soap_version == SOAP_1_2) {
     166               0 :                                         add_soap_fault(this_ptr, "Client", "encodingStyle cannot be specified on the Header", NULL, NULL TSRMLS_CC);
     167               0 :                                         xmlFreeDoc(response);
     168               0 :                                         return FALSE;
     169               0 :                                 } else if (strcmp((char*)attr->children->content, SOAP_1_1_ENC_NAMESPACE) != 0) {
     170               0 :                                         add_soap_fault(this_ptr, "Client", "Unknown data encoding style", NULL, NULL TSRMLS_CC);
     171               0 :                                         xmlFreeDoc(response);
     172               0 :                                         return FALSE;
     173                 :                                 }
     174                 :                         }
     175               0 :                         attr = attr->next;
     176                 :                 }
     177                 :         }
     178                 : 
     179                 :         /* Check if <Body> contains <Fault> element */
     180              65 :         fault = get_node_ex(body->children,"Fault",envelope_ns);
     181              65 :         if (fault != NULL) {
     182               2 :                 char *faultcode = NULL, *faultstring = NULL, *faultactor = NULL;
     183               2 :                 zval *details = NULL;
     184                 :                 xmlNodePtr tmp;
     185                 : 
     186               2 :                 if (soap_version == SOAP_1_1) {
     187               2 :                         tmp = get_node(fault->children, "faultcode");
     188               2 :                         if (tmp != NULL && tmp->children != NULL) {
     189               2 :                                 faultcode = (char*)tmp->children->content;
     190                 :                         }
     191                 : 
     192               2 :                         tmp = get_node(fault->children, "faultstring");
     193               2 :                         if (tmp != NULL && tmp->children != NULL) {
     194               2 :                                 faultstring = (char*)tmp->children->content;
     195                 :                         }
     196                 : 
     197               2 :                         tmp = get_node(fault->children, "faultactor");
     198               2 :                         if (tmp != NULL && tmp->children != NULL) {
     199               0 :                                 faultactor = (char*)tmp->children->content;
     200                 :                         }
     201                 : 
     202               2 :                         tmp = get_node(fault->children, "detail");
     203               2 :                         if (tmp != NULL) {
     204               2 :                                 details = master_to_zval(NULL, tmp);
     205                 :                         }
     206                 :                 } else {
     207               0 :                         tmp = get_node(fault->children, "Code");
     208               0 :                         if (tmp != NULL && tmp->children != NULL) {
     209               0 :                                 tmp = get_node(tmp->children, "Value");
     210               0 :                                 if (tmp != NULL && tmp->children != NULL) {
     211               0 :                                         faultcode = (char*)tmp->children->content;
     212                 :                                 }
     213                 :                         }
     214                 : 
     215               0 :                         tmp = get_node(fault->children,"Reason");
     216               0 :                         if (tmp != NULL && tmp->children != NULL) {
     217                 :                                 /* TODO: lang attribute */
     218               0 :                                 tmp = get_node(tmp->children,"Text");
     219               0 :                                 if (tmp != NULL && tmp->children != NULL) {
     220               0 :                                         faultstring = (char*)tmp->children->content;
     221                 :                                 }
     222                 :                         }
     223                 : 
     224               0 :                         tmp = get_node(fault->children,"Detail");
     225               0 :                         if (tmp != NULL) {
     226               0 :                                 details = master_to_zval(NULL, tmp);
     227                 :                         }
     228                 :                 }
     229               2 :                 add_soap_fault(this_ptr, faultcode, faultstring, faultactor, details TSRMLS_CC);
     230               2 :                 if (details) {
     231               2 :                         Z_DELREF_P(details);
     232                 :                 }
     233               2 :                 xmlFreeDoc(response);
     234               2 :                 return FALSE;
     235                 :         }
     236                 : 
     237                 :         /* Parse content of <Body> element */
     238              63 :         array_init(return_value);
     239              63 :         resp = body->children;
     240             126 :         while (resp != NULL && resp->type != XML_ELEMENT_NODE) {
     241               0 :                 resp = resp->next;
     242                 :         }
     243              63 :         if (resp != NULL) {
     244             106 :                 if (fn != NULL && fn->binding && fn->binding->bindingType == BINDING_SOAP) {
     245                 :                   /* Function has WSDL description */
     246              43 :                         sdlParamPtr *h_param, param = NULL;
     247              43 :                         xmlNodePtr val = NULL;
     248              43 :                         char *name, *ns = NULL;
     249                 :                         zval* tmp;
     250              43 :                         sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)fn->bindingAttributes;
     251                 :                         int res_count;
     252                 : 
     253              43 :                         hdrs = fnb->output.headers;
     254                 : 
     255              43 :                         if (fn->responseParameters) {
     256              43 :                           res_count = zend_hash_num_elements(fn->responseParameters);
     257              43 :                                 zend_hash_internal_pointer_reset(fn->responseParameters);
     258             131 :                                 while (zend_hash_get_current_data(fn->responseParameters, (void **)&h_param) == SUCCESS) {
     259              45 :                                         UErrorCode status = U_ZERO_ERROR;
     260                 :                                         zstr u_name;
     261                 :                                         int u_name_len;
     262                 : 
     263              45 :                                         param = (*h_param);
     264              45 :                                         if (fnb->style == SOAP_DOCUMENT) {
     265              11 :                                                 if (param->element) {
     266               5 :                                                         name = param->element->name;
     267               5 :                                                         ns = param->element->namens;
     268                 : /*
     269                 :                                                         name = param->encode->details.type_str;
     270                 :                                                         ns = param->encode->details.ns;
     271                 : */
     272                 :                                                 } else {
     273               6 :                                                         name = param->paramName;
     274                 :                                                 }
     275                 :                                         } else {
     276              34 :                                                 name = fn->responseName;
     277                 :                                                 /* ns = ? */
     278                 :                                         }
     279                 : 
     280                 :                                         /* Get value of parameter */
     281              45 :                                         cur = get_node_ex(resp, name, ns);
     282              45 :                                         if (!cur) {
     283               4 :                                                 cur = get_node(resp, name);
     284                 :                                                 /* TODO: produce warning invalid ns */
     285                 :                                         }
     286              45 :                                         if (!cur && fnb->style == SOAP_RPC) {
     287               4 :                                           cur = resp;
     288                 :                                         }
     289              45 :                                         if (cur) {
     290              45 :                                                 if (fnb->style == SOAP_DOCUMENT) {
     291              11 :                                                         val = cur;
     292                 :                                                 } else {
     293              34 :                                                         val = get_node(cur->children, param->paramName);
     294              34 :                                                         if (res_count == 1) {
     295              31 :                                                                 if (val == NULL) {
     296               1 :                                                                         val = get_node(cur->children, "return");
     297                 :                                                                 }
     298              31 :                                                                 if (val == NULL) {
     299               1 :                                                                         val = get_node(cur->children, "result");
     300                 :                                                                 }
     301              31 :                                                                 if (val == NULL && cur->children && cur->children->next == NULL) {
     302               1 :                                                                         val = cur->children;                                                           
     303                 :                                                                 }
     304                 :                                                         }
     305                 :                                                 }
     306                 :                                         }
     307                 : 
     308              45 :                                         if (!val) {
     309                 :                                                 /* TODO: may be "nil" is not OK? */
     310               0 :                                                 MAKE_STD_ZVAL(tmp);
     311               0 :                                                 ZVAL_NULL(tmp);
     312                 : /*
     313                 :                                                 add_soap_fault(this_ptr, "Client", "Can't find response data", NULL, NULL TSRMLS_CC);
     314                 :                                                 xmlFreeDoc(response);
     315                 :                                                 return FALSE;
     316                 : */
     317                 :                                         } else {
     318                 :                                                 /* Decoding value of parameter */
     319              45 :                                                 if (param != NULL) {
     320              45 :                                                         tmp = master_to_zval(param->encode, val);
     321                 :                                                 } else {
     322               0 :                                                         tmp = master_to_zval(NULL, val);
     323                 :                                                 }
     324                 :                                         }
     325              45 :                                         zend_string_to_unicode_ex(UG(utf8_conv), &u_name.u, &u_name_len, param->paramName, strlen(param->paramName), &status);
     326              45 :                                         add_u_assoc_zval_ex(return_value, IS_UNICODE, u_name, u_name_len+1, tmp);
     327              45 :                                         efree(u_name.u);
     328                 : 
     329              45 :                                         param_count++;
     330                 : 
     331              45 :                                         zend_hash_move_forward(fn->responseParameters);
     332                 :                                 }
     333                 :                         }
     334                 :                 } else {
     335                 :                   /* Function hasn't WSDL description */
     336                 :                         xmlNodePtr val;
     337              20 :                         val = resp->children;
     338              63 :                         while (val != NULL) {
     339              46 :                                 while (val && val->type != XML_ELEMENT_NODE) {
     340               0 :                                         val = val->next;
     341                 :                                 }
     342              23 :                                 if (val != NULL) {
     343              23 :                                         if (!node_is_equal_ex(val,"result",RPC_SOAP12_NAMESPACE)) {
     344                 :                                                 zval *tmp;
     345                 :                                                 zval **arr;
     346                 : 
     347              23 :                                                 tmp = master_to_zval(NULL, val);
     348              23 :                                                 if (val->name) {
     349              23 :                                                         UErrorCode status = U_ZERO_ERROR;
     350                 :                                                         zstr u_name;
     351                 :                                                         int u_name_len;
     352              23 :                                                         zend_string_to_unicode_ex(UG(utf8_conv), &u_name.u, &u_name_len, (char*)val->name, strlen((char*)val->name), &status);
     353              23 :                                                         if (zend_u_hash_find(Z_ARRVAL_P(return_value), IS_UNICODE, u_name, u_name_len+1, (void**)&arr) == SUCCESS) {
     354               3 :                                                                 add_next_index_zval(*arr, tmp);
     355              21 :                                                         } else if (val->next && get_node(val->next, (char*)val->name)) {
     356                 :                                                                 zval *arr;
     357                 : 
     358               1 :                                                                 MAKE_STD_ZVAL(arr);
     359               1 :                                                                 array_init(arr);
     360               1 :                                                                 add_next_index_zval(arr, tmp);
     361               1 :                                                                 add_u_assoc_zval_ex(return_value, IS_UNICODE, u_name, u_name_len+1, arr);
     362                 :                                                         } else {
     363              19 :                                                                 add_u_assoc_zval_ex(return_value, IS_UNICODE, u_name, u_name_len+1, tmp);
     364                 :                                                         }
     365              23 :                                                         efree(u_name.u);
     366                 :                                                 } else {
     367               0 :                                                         add_next_index_zval(return_value, tmp);
     368                 :                                                 }
     369              23 :                                                 ++param_count;
     370                 :                                         }
     371              23 :                                         val = val->next;
     372                 :                                 }
     373                 :                         }
     374                 :                 }
     375                 :         }
     376                 : 
     377              63 :         if (Z_TYPE_P(return_value) == IS_ARRAY) {
     378              63 :                 if (param_count == 0) {
     379               0 :                         zval_dtor(return_value);
     380               0 :                         ZVAL_NULL(return_value);
     381              63 :                 } else if (param_count == 1) {
     382                 :                         zval *tmp;
     383                 : 
     384              61 :                         zend_hash_internal_pointer_reset(Z_ARRVAL_P(return_value));
     385              61 :                         zend_hash_get_current_data(Z_ARRVAL_P(return_value), (void**)&tmp);
     386              61 :                         tmp = *(zval**)tmp;
     387              61 :                         Z_ADDREF_P(tmp);
     388              61 :                         zval_dtor(return_value);
     389              61 :                         *return_value = *tmp;
     390              61 :                         FREE_ZVAL(tmp);
     391                 :                 }
     392                 :         }
     393                 : 
     394              63 :         if (soap_headers && head) {
     395               0 :                 trav = head->children;
     396               0 :                 while (trav != NULL) {
     397               0 :                         if (trav->type == XML_ELEMENT_NODE) {
     398               0 :                                 encodePtr enc = NULL;
     399                 :                                 zval* val;
     400               0 :                                 UErrorCode status = U_ZERO_ERROR;
     401                 :                                 zstr u_name;
     402                 :                                 int u_name_len;
     403                 : 
     404               0 :                                 if (hdrs) {
     405               0 :                                         smart_str key = {0};
     406                 :                                         sdlSoapBindingFunctionHeaderPtr *hdr;
     407                 : 
     408               0 :                                         if (trav->ns) {
     409               0 :                                                 smart_str_appends(&key, (char*)trav->ns->href);
     410               0 :                                                 smart_str_appendc(&key,':');
     411                 :                                         }
     412               0 :                                         smart_str_appends(&key, (char*)trav->name);
     413               0 :                                         smart_str_0(&key);
     414               0 :                                         if (zend_hash_find(hdrs, key.c, key.len+1, (void**)&hdr) == SUCCESS) {
     415               0 :                                                 enc = (*hdr)->encode;
     416                 :                                         }
     417               0 :                                         smart_str_free(&key);
     418                 :                                 }
     419               0 :                                 val = master_to_zval(enc, trav);
     420               0 :                                 zend_string_to_unicode_ex(UG(utf8_conv), &u_name.u, &u_name_len, (char*)trav->name, strlen((char*)trav->name), &status);
     421               0 :                                 add_u_assoc_zval_ex(soap_headers, IS_UNICODE, u_name, u_name_len+1, val);
     422               0 :                                 efree(u_name.u);
     423                 :                         }
     424               0 :                         trav = trav->next;
     425                 :                 }
     426                 :         }
     427                 : 
     428              63 :         xmlFreeDoc(response);
     429              63 :         return TRUE;
     430                 : }

Generated by: LTP GCOV extension version 1.5

Generated at Mon, 23 Nov 2009 17:39:38 +0000 (33 hours ago)

Copyright © 2005-2009 The PHP Group
All rights reserved.