2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 | Copyright (c) 1997-2010 The PHP Group |
7 +----------------------------------------------------------------------+
8 | This source file is subject to version 3.01 of the PHP license, |
9 | that is bundled with this package in the file LICENSE, and is |
10 | available through the world-wide-web at the following url: |
11 | http://www.php.net/license/3_01.txt |
12 | If you did not receive a copy of the PHP license and are unable to |
13 | obtain it through the world-wide-web, please send a note to |
14 | license@php.net so we can mail you a copy immediately. |
15 +----------------------------------------------------------------------+
18 #include "hphp/runtime/ext/soap/xml.h"
19 #include "hphp/runtime/ext/std/ext_std_file.h"
20 #include "hphp/runtime/ext/stream/ext_stream.h"
21 #include "hphp/runtime/ext/apc/ext_apc.h"
23 #include "hphp/runtime/base/array-init.h"
24 #include "hphp/runtime/base/comparisons.h"
25 #include "hphp/runtime/base/file.h"
28 ///////////////////////////////////////////////////////////////////////////////
30 static bool is_blank(const xmlChar
* str
) {
31 while (*str
!= '\0') {
32 if (*str
!= ' ' && *str
!= 0x9 && *str
!= 0xa && *str
!= 0xd) {
40 /* removes all empty text, comments and other insignoficant nodes */
41 static void cleanup_xml_node(xmlNodePtr node
) {
43 xmlNodePtr del
= nullptr;
45 trav
= node
->children
;
46 while (trav
!= nullptr) {
52 if (trav
->type
== XML_TEXT_NODE
) {
53 if (is_blank(trav
->content
)) {
56 } else if ((trav
->type
!= XML_ELEMENT_NODE
) &&
57 (trav
->type
!= XML_CDATA_SECTION_NODE
)) {
59 } else if (trav
->children
!= nullptr) {
60 cleanup_xml_node(trav
);
71 soap_ignorableWhitespace(void* /*ctx*/, const xmlChar
* /*ch*/, int /*len*/) {}
73 static void soap_Comment(void* /*ctx*/, const xmlChar
* /*value*/) {}
79 xmlDocPtr
soap_xmlParseFile(const char *filename
) {
80 String
cache_key("HPHP.SOAP.WSDL.");
81 cache_key
+= filename
;
83 auto content
= Variant::attach(HHVM_FN(apc_fetch
)(cache_key
));
84 if (same(content
, false)) {
85 Variant cxt
= HHVM_FN(stream_context_create
)(make_map_array(
86 s_http
, make_map_array(s_timeout
, 1000)));
87 auto file
= File::Open(filename
, "rb", 0, cast_or_null
<StreamContext
>(cxt
));
89 content
= HHVM_FN(stream_get_contents
)(Resource(file
));
90 if (!same(content
, false)) {
91 HHVM_FN(apc_store
)(cache_key
, content
);
96 if (!same(content
, false)) {
97 String scontent
= content
.toString();
98 xmlDocPtr ret
= soap_xmlParseMemory(scontent
.data(), scontent
.size(),
101 ret
->URL
= xmlCharStrdup(filename
);
108 xmlDocPtr
soap_xmlParseMemory(const void *buf
, size_t buf_size
,
109 bool skip_clean
/*= true */) {
110 xmlParserCtxtPtr ctxt
= nullptr;
116 ctxt
= xmlCreateMemoryParserCtxt((const char *)buf
, buf_size
);
118 ctxt
->keepBlanks
= 0;
119 ctxt
->sax
->ignorableWhitespace
= soap_ignorableWhitespace
;
120 ctxt
->sax
->comment
= soap_Comment
;
121 ctxt
->sax
->warning
= nullptr;
122 ctxt
->sax
->error
= nullptr;
123 /*ctxt->sax->fatalError = nullptr;*/
124 auto old
= HHVM_FN(libxml_disable_entity_loader
)(true);
125 xmlParseDocument(ctxt
);
126 HHVM_FN(libxml_disable_entity_loader
)(old
);
127 if (ctxt
->wellFormed
) {
129 if (ret
->URL
== nullptr && ctxt
->directory
!= nullptr) {
130 ret
->URL
= xmlCharStrdup(ctxt
->directory
);
134 xmlFreeDoc(ctxt
->myDoc
);
135 ctxt
->myDoc
= nullptr;
137 xmlFreeParserCtxt(ctxt
);
146 if (!skip_clean
&& ret
) {
147 cleanup_xml_node((xmlNodePtr
)ret
);
152 xmlNsPtr
attr_find_ns(xmlAttrPtr node
) {
155 } else if (node
->parent
->ns
) {
156 return node
->parent
->ns
;
158 return xmlSearchNs(node
->doc
, node
->parent
, nullptr);
162 xmlNsPtr
node_find_ns(xmlNodePtr node
) {
166 return xmlSearchNs(node
->doc
, node
, nullptr);
170 bool attr_is_equal_ex(xmlAttrPtr node
, char *name
, char *ns
) {
171 if (name
== nullptr || strcmp((char*)node
->name
, name
) == 0) {
173 xmlNsPtr nsPtr
= attr_find_ns(node
);
175 return (strcmp((char*)nsPtr
->href
, ns
) == 0);
185 bool node_is_equal_ex(xmlNodePtr node
, char *name
, char *ns
) {
186 if (name
== nullptr || strcmp((char*)node
->name
, name
) == 0) {
188 xmlNsPtr nsPtr
= node_find_ns(node
);
190 return (strcmp((char*)nsPtr
->href
, ns
) == 0);
201 xmlAttrPtr
get_attribute_ex(xmlAttrPtr node
, char *name
, char *ns
) {
202 while (node
!=nullptr) {
203 if (attr_is_equal_ex(node
, name
, ns
)) {
211 xmlNodePtr
get_node_ex(xmlNodePtr node
, char *name
, char *ns
) {
212 while (node
!=nullptr) {
213 if (node_is_equal_ex(node
, name
, ns
)) {
221 xmlNodePtr
get_node_recurisve_ex(xmlNodePtr node
, char *name
, char *ns
) {
222 while (node
!= nullptr) {
223 if (node_is_equal_ex(node
, name
, ns
)) {
225 } else if (node
->children
!= nullptr) {
226 xmlNodePtr tmp
= get_node_recurisve_ex(node
->children
, name
, ns
);
236 xmlNodePtr
get_node_with_attribute_ex(xmlNodePtr node
, char *name
,
237 char *name_ns
, char *attribute
,
238 char *value
, char *attr_ns
) {
240 while (node
!= nullptr) {
241 if (name
!= nullptr) {
242 node
= get_node_ex(node
, name
, name_ns
);
248 attr
= get_attribute_ex(node
->properties
, attribute
, attr_ns
);
249 if (attr
!= nullptr && strcmp((char*)attr
->children
->content
, value
) == 0) {
257 xmlNodePtr get_node_with_attribute_recursive_ex
258 (xmlNodePtr node
, char *name
, char *name_ns
, char *attribute
, char *value
,
260 while (node
!= nullptr) {
261 if (node_is_equal_ex(node
, name
, name_ns
)) {
262 xmlAttrPtr attr
= get_attribute_ex(node
->properties
, attribute
, attr_ns
);
263 if (attr
!= nullptr && !strcmp((char*)attr
->children
->content
, value
)) {
267 if (node
->children
!= nullptr) {
268 xmlNodePtr tmp
= get_node_with_attribute_recursive_ex
269 (node
->children
, name
, name_ns
, attribute
, value
, attr_ns
);
279 void parse_namespace(const xmlChar
*inval
, std::string
&value
,
281 char *found
= strrchr((char*)inval
, ':');
283 if (found
&& found
!= (char*)inval
) {
284 ns
= std::string((char*)inval
, found
- (char*)inval
);
287 value
= (char*)inval
;
292 ///////////////////////////////////////////////////////////////////////////////