Issues (4069)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

include/nusoap/class.soap_server.php (8 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/*
4
5
Modification information for LGPL compliance
6
7
r57813 - 2010-08-19 10:34:44 -0700 (Thu, 19 Aug 2010) - kjing - Author: John Mertic <[email protected]>
8
    Bug 39085 - When loading the opposite search panel via ajax on the ListViews, call the index action instead of the ListView action to avoid touching pre-MVC code by accident.
9
10
r56990 - 2010-06-16 13:05:36 -0700 (Wed, 16 Jun 2010) - kjing - snapshot "Mango" svn branch to a new one for GitHub sync
11
12
r56989 - 2010-06-16 13:01:33 -0700 (Wed, 16 Jun 2010) - kjing - defunt "Mango" svn dev branch before github cutover
13
14
r55980 - 2010-04-19 13:31:28 -0700 (Mon, 19 Apr 2010) - kjing - create Mango (6.1) based on windex
15
16
r51719 - 2009-10-22 10:18:00 -0700 (Thu, 22 Oct 2009) - mitani - Converted to Build 3  tags and updated the build system 
17
18
r51634 - 2009-10-19 13:32:22 -0700 (Mon, 19 Oct 2009) - mitani - Windex is the branch for Sugar Sales 1.0 development
19
20
r51443 - 2009-10-12 13:34:36 -0700 (Mon, 12 Oct 2009) - jmertic - Bug 33332 - Made application PHP 5.3 compliant with E_DEPRECATED warnings on by:
21
- Changing all ereg function to either preg or simple string based ones
22
- No more references to magic quotes.
23
- Change all the session_unregister() functions to just unset() the correct session variable instead.
24
25
r50375 - 2009-08-24 18:07:43 -0700 (Mon, 24 Aug 2009) - dwong - branch kobe2 from tokyo r50372
26
27
r42807 - 2008-12-29 11:16:59 -0800 (Mon, 29 Dec 2008) - dwong - Branch from trunk/sugarcrm r42806 to branches/tokyo/sugarcrm
28
29
r13782 - 2006-06-06 10:58:55 -0700 (Tue, 06 Jun 2006) - majed - changes entry point code
30
31
r11115 - 2006-01-17 14:54:45 -0800 (Tue, 17 Jan 2006) - majed - add entry point validation
32
33
r8846 - 2005-10-31 11:01:12 -0800 (Mon, 31 Oct 2005) - majed - new version of nusoap
34
35
r5462 - 2005-05-25 13:50:11 -0700 (Wed, 25 May 2005) - majed - upgraded nusoap to .6.9
36
37
r5104 - 2005-05-04 15:33:41 -0700 (Wed, 04 May 2005) - majed - gets rid of HTTP_GET_VARS and what not which has been deprecated
38
39
r573 - 2004-09-04 13:03:32 -0700 (Sat, 04 Sep 2004) - sugarclint - undoing copyrights added in inadvertantly.  --clint
40
41
r546 - 2004-09-03 11:49:38 -0700 (Fri, 03 Sep 2004) - sugarmsi - removed echo count
42
43
r354 - 2004-08-02 23:00:37 -0700 (Mon, 02 Aug 2004) - sugarjacob - Adding Soap
44
45
46
*/
47
48
49
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
50
51
52
53
54
/**
55
*
56
* nusoap_server allows the user to create a SOAP server
57
* that is capable of receiving messages and returning responses
58
*
59
* NOTE: WSDL functionality is experimental
60
*
61
* @author   Dietrich Ayala <[email protected]>
62
* @author   Scott Nichol <[email protected]>
63
64
* @access   public
65
*/
66
class nusoap_server extends nusoap_base {
67
	/**
68
	 * HTTP headers of request
69
	 * @var array
70
	 * @access private
71
	 */
72
	var $headers = array();
73
	/**
74
	 * HTTP request
75
	 * @var string
76
	 * @access private
77
	 */
78
	var $request = '';
79
	/**
80
	 * SOAP headers from request (incomplete namespace resolution; special characters not escaped) (text)
81
	 * @var string
82
	 * @access public
83
	 */
84
	var $requestHeaders = '';
85
	/**
86
	 * SOAP Headers from request (parsed)
87
	 * @var mixed
88
	 * @access public
89
	 */
90
	var $requestHeader = NULL;
91
	/**
92
	 * SOAP body request portion (incomplete namespace resolution; special characters not escaped) (text)
93
	 * @var string
94
	 * @access public
95
	 */
96
	var $document = '';
97
	/**
98
	 * SOAP payload for request (text)
99
	 * @var string
100
	 * @access public
101
	 */
102
	var $requestSOAP = '';
103
	/**
104
	 * requested method namespace URI
105
	 * @var string
106
	 * @access private
107
	 */
108
	var $methodURI = '';
109
	/**
110
	 * name of method requested
111
	 * @var string
112
	 * @access private
113
	 */
114
	var $methodname = '';
115
	/**
116
	 * method parameters from request
117
	 * @var array
118
	 * @access private
119
	 */
120
	var $methodparams = array();
121
	/**
122
	 * SOAP Action from request
123
	 * @var string
124
	 * @access private
125
	 */
126
	var $SOAPAction = '';
127
	/**
128
	 * character set encoding of incoming (request) messages
129
	 * @var string
130
	 * @access public
131
	 */
132
	var $xml_encoding = '';
133
	/**
134
	 * toggles whether the parser decodes element content w/ utf8_decode()
135
	 * @var boolean
136
	 * @access public
137
	 */
138
    var $decode_utf8 = true;
139
140
	/**
141
	 * HTTP headers of response
142
	 * @var array
143
	 * @access public
144
	 */
145
	var $outgoing_headers = array();
146
	/**
147
	 * HTTP response
148
	 * @var string
149
	 * @access private
150
	 */
151
	var $response = '';
152
	/**
153
	 * SOAP headers for response (text or array of soapval or associative array)
154
	 * @var mixed
155
	 * @access public
156
	 */
157
	var $responseHeaders = '';
158
	/**
159
	 * SOAP payload for response (text)
160
	 * @var string
161
	 * @access private
162
	 */
163
	var $responseSOAP = '';
164
	/**
165
	 * method return value to place in response
166
	 * @var mixed
167
	 * @access private
168
	 */
169
	var $methodreturn = false;
170
	/**
171
	 * whether $methodreturn is a string of literal XML
172
	 * @var boolean
173
	 * @access public
174
	 */
175
	var $methodreturnisliteralxml = false;
176
	/**
177
	 * SOAP fault for response (or false)
178
	 * @var mixed
179
	 * @access private
180
	 */
181
	var $fault = false;
182
	/**
183
	 * text indication of result (for debugging)
184
	 * @var string
185
	 * @access private
186
	 */
187
	var $result = 'successful';
188
189
	/**
190
	 * assoc array of operations => opData; operations are added by the register()
191
	 * method or by parsing an external WSDL definition
192
	 * @var array
193
	 * @access private
194
	 */
195
	var $operations = array();
196
	/**
197
	 * wsdl instance (if one)
198
	 * @var mixed
199
	 * @access private
200
	 */
201
	var $wsdl = false;
202
	/**
203
	 * URL for WSDL (if one)
204
	 * @var mixed
205
	 * @access private
206
	 */
207
	var $externalWSDLURL = false;
208
	/**
209
	 * whether to append debug to response as XML comment
210
	 * @var boolean
211
	 * @access public
212
	 */
213
	var $debug_flag = false;
214
215
216
	/**
217
	* constructor
218
    * the optional parameter is a path to a WSDL file that you'd like to bind the server instance to.
219
	*
220
    * @param mixed $wsdl file path or URL (string), or wsdl instance (object)
221
	* @access   public
222
	*/
223
	function nusoap_server($wsdl=false){
224
		parent::nusoap_base();
225
		// turn on debugging?
226
		global $debug;
227
		global $HTTP_SERVER_VARS;
228
229
		if (isset($_SERVER)) {
230
			$this->debug("_SERVER is defined:");
231
			$this->appendDebug($this->varDump($_SERVER));
232
		} elseif (isset($HTTP_SERVER_VARS)) {
233
			$this->debug("HTTP_SERVER_VARS is defined:");
234
			$this->appendDebug($this->varDump($HTTP_SERVER_VARS));
235
		} else {
236
			$this->debug("Neither _SERVER nor HTTP_SERVER_VARS is defined.");
237
		}
238
239
		if (isset($debug)) {
240
			$this->debug("In nusoap_server, set debug_flag=$debug based on global flag");
241
			$this->debug_flag = $debug;
242
		} elseif (isset($_SERVER['QUERY_STRING'])) {
243
			$qs = explode('&', $_SERVER['QUERY_STRING']);
244
			foreach ($qs as $v) {
245
				if (substr($v, 0, 6) == 'debug=') {
246
					$this->debug("In nusoap_server, set debug_flag=" . substr($v, 6) . " based on query string #1");
247
					$this->debug_flag = substr($v, 6);
0 ignored issues
show
Documentation Bug introduced by
The property $debug_flag was declared of type boolean, but substr($v, 6) is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
248
				}
249
			}
250
		} elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) {
251
			$qs = explode('&', $HTTP_SERVER_VARS['QUERY_STRING']);
252
			foreach ($qs as $v) {
253
				if (substr($v, 0, 6) == 'debug=') {
254
					$this->debug("In nusoap_server, set debug_flag=" . substr($v, 6) . " based on query string #2");
255
					$this->debug_flag = substr($v, 6);
256
				}
257
			}
258
		}
259
260
		// wsdl
261
		if($wsdl){
262
			$this->debug("In nusoap_server, WSDL is specified");
263
			if (is_object($wsdl) && (get_class($wsdl) == 'wsdl')) {
264
				$this->wsdl = $wsdl;
265
				$this->externalWSDLURL = $this->wsdl->wsdl;
266
				$this->debug('Use existing wsdl instance from ' . $this->externalWSDLURL);
267
			} else {
268
				$this->debug('Create wsdl from ' . $wsdl);
269
				$this->wsdl = new wsdl($wsdl);
270
				$this->externalWSDLURL = $wsdl;
271
			}
272
			$this->appendDebug($this->wsdl->getDebug());
273
			$this->wsdl->clearDebug();
274
			if($err = $this->wsdl->getError()){
275
				die('WSDL ERROR: '.$err);
276
			}
277
		}
278
	}
279
280
	/**
281
	* processes request and returns response
282
	*
283
	* @param    string $data usually is the value of $HTTP_RAW_POST_DATA
284
	* @access   public
285
	*/
286
	function service($data){
287
		global $HTTP_SERVER_VARS;
288
289
		if (isset($_SERVER['REQUEST_METHOD'])) {
290
			$rm = $_SERVER['REQUEST_METHOD'];
291
		} elseif (isset($HTTP_SERVER_VARS['REQUEST_METHOD'])) {
292
			$rm = $HTTP_SERVER_VARS['REQUEST_METHOD'];
293
		} else {
294
			$rm = '';
295
		}
296
297
		if (isset($_SERVER['QUERY_STRING'])) {
298
			$qs = $_SERVER['QUERY_STRING'];
299
		} elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) {
300
			$qs = $HTTP_SERVER_VARS['QUERY_STRING'];
301
		} else {
302
			$qs = '';
303
		}
304
		$this->debug("In service, request method=$rm query string=$qs strlen(\$data)=" . strlen($data));
305
306
		if ($rm == 'POST') {
307
			$this->debug("In service, invoke the request");
308
			$this->parse_request($data);
309
			if (! $this->fault) {
310
				$this->invoke_method();
311
			}
312
			if (! $this->fault) {
313
				$this->serialize_return();
314
			}
315
			$this->send_response();
316
		} elseif (preg_match('/wsdl/', $qs) ){
317
			$this->debug("In service, this is a request for WSDL");
318
			if ($this->externalWSDLURL){
319
              if (strpos($this->externalWSDLURL, "http://") !== false) { // assume URL
320
				$this->debug("In service, re-direct for WSDL");
321
				header('Location: '.$this->externalWSDLURL);
322
              } else { // assume file
323
				$this->debug("In service, use file passthru for WSDL");
324
                header("Content-Type: text/xml\r\n");
325
				$pos = strpos($this->externalWSDLURL, "file://");
326
				if ($pos === false) {
327
					$filename = $this->externalWSDLURL;
328
				} else {
329
					$filename = substr($this->externalWSDLURL, $pos + 7);
330
				}
331
                $fp = fopen($this->externalWSDLURL, 'r');
332
                fpassthru($fp);
333
              }
334
			} elseif ($this->wsdl) {
335
				$this->debug("In service, serialize WSDL");
336
				header("Content-Type: text/xml; charset=ISO-8859-1\r\n");
337
				print $this->wsdl->serialize($this->debug_flag);
338
				if ($this->debug_flag) {
339
					$this->debug('wsdl:');
340
					$this->appendDebug($this->varDump($this->wsdl));
341
					print $this->getDebugAsXMLComment();
342
				}
343
			} else {
344
				$this->debug("In service, there is no WSDL");
345
				header("Content-Type: text/html; charset=ISO-8859-1\r\n");
346
				print "This service does not provide WSDL";
347
			}
348
		} elseif ($this->wsdl) {
349
			$this->debug("In service, return Web description");
350
			print $this->wsdl->webDescription();
351
		} else {
352
			$this->debug("In service, no Web description");
353
			header("Content-Type: text/html; charset=ISO-8859-1\r\n");
354
			print "This service does not provide a Web description";
355
		}
356
	}
357
358
	/**
359
	* parses HTTP request headers.
360
	*
361
	* The following fields are set by this function (when successful)
362
	*
363
	* headers
364
	* request
365
	* xml_encoding
366
	* SOAPAction
367
	*
368
	* @access   private
369
	*/
370
	function parse_http_headers() {
371
		global $HTTP_SERVER_VARS;
372
373
		$this->request = '';
374
		$this->SOAPAction = '';
375
		if(function_exists('getallheaders')){
376
			$this->debug("In parse_http_headers, use getallheaders");
377
			$headers = getallheaders();
378
			foreach($headers as $k=>$v){
379
				$k = strtolower($k);
380
				$this->headers[$k] = $v;
381
				$this->request .= "$k: $v\r\n";
382
				$this->debug("$k: $v");
383
			}
384
			// get SOAPAction header
385
			if(isset($this->headers['soapaction'])){
386
				$this->SOAPAction = str_replace('"','',$this->headers['soapaction']);
387
			}
388
			// get the character encoding of the incoming request
389
			if(isset($this->headers['content-type']) && strpos($this->headers['content-type'],'=')){
390
				$enc = str_replace('"','',substr(strstr($this->headers["content-type"],'='),1));
391
				if(preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)){
392
					$this->xml_encoding = strtoupper($enc);
393
				} else {
394
					$this->xml_encoding = 'US-ASCII';
395
				}
396
			} else {
397
				// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
398
				$this->xml_encoding = 'ISO-8859-1';
399
			}
400
		} elseif(isset($_SERVER) && is_array($_SERVER)){
401
			$this->debug("In parse_http_headers, use _SERVER");
402
			foreach ($_SERVER as $k => $v) {
403
				if (substr($k, 0, 5) == 'HTTP_') {
404
					$k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5))));
405
				} else {
406
					$k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k)));
407
				}
408
				if ($k == 'soapaction') {
409
					// get SOAPAction header
410
					$k = 'SOAPAction';
411
					$v = str_replace('"', '', $v);
412
					$v = str_replace('\\', '', $v);
413
					$this->SOAPAction = $v;
414
				} else if ($k == 'content-type') {
415
					// get the character encoding of the incoming request
416
					if (strpos($v, '=')) {
417
						$enc = substr(strstr($v, '='), 1);
418
						$enc = str_replace('"', '', $enc);
419
						$enc = str_replace('\\', '', $enc);
420
						if (preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)) {
421
							$this->xml_encoding = strtoupper($enc);
422
						} else {
423
							$this->xml_encoding = 'US-ASCII';
424
						}
425
					} else {
426
						// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
427
						$this->xml_encoding = 'ISO-8859-1';
428
					}
429
				}
430
				$this->headers[$k] = $v;
431
				$this->request .= "$k: $v\r\n";
432
				$this->debug("$k: $v");
433
			}
434
		} elseif (is_array($HTTP_SERVER_VARS)) {
435
			$this->debug("In parse_http_headers, use HTTP_SERVER_VARS");
436
			foreach ($HTTP_SERVER_VARS as $k => $v) {
437
				if (substr($k, 0, 5) == 'HTTP_') {
438
					$k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5)))); 	                                         $k = strtolower(substr($k, 5));
439
				} else {
440
					$k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k))); 	                                         $k = strtolower($k);
441
				}
442
				if ($k == 'soapaction') {
443
					// get SOAPAction header
444
					$k = 'SOAPAction';
445
					$v = str_replace('"', '', $v);
446
					$v = str_replace('\\', '', $v);
447
					$this->SOAPAction = $v;
448
				} else if ($k == 'content-type') {
449
					// get the character encoding of the incoming request
450
					if (strpos($v, '=')) {
451
						$enc = substr(strstr($v, '='), 1);
452
						$enc = str_replace('"', '', $enc);
453
						$enc = str_replace('\\', '', $enc);
454
						if (preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)) {
455
							$this->xml_encoding = strtoupper($enc);
456
						} else {
457
							$this->xml_encoding = 'US-ASCII';
458
						}
459
					} else {
460
						// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
461
						$this->xml_encoding = 'ISO-8859-1';
462
					}
463
				}
464
				$this->headers[$k] = $v;
465
				$this->request .= "$k: $v\r\n";
466
				$this->debug("$k: $v");
467
			}
468
		} else {
469
			$this->debug("In parse_http_headers, HTTP headers not accessible");
470
			$this->setError("HTTP headers not accessible");
471
		}
472
	}
473
474
	/**
475
	* parses a request
476
	*
477
	* The following fields are set by this function (when successful)
478
	*
479
	* headers
480
	* request
481
	* xml_encoding
482
	* SOAPAction
483
	* request
484
	* requestSOAP
485
	* methodURI
486
	* methodname
487
	* methodparams
488
	* requestHeaders
489
	* document
490
	*
491
	* This sets the fault field on error
492
	*
493
	* @param    string $data XML string
494
	* @access   private
495
	*/
496
	function parse_request($data='') {
497
		$this->debug('entering parse_request()');
498
		$this->parse_http_headers();
499
		$this->debug('got character encoding: '.$this->xml_encoding);
500
		// uncompress if necessary
501
		if (isset($this->headers['content-encoding']) && $this->headers['content-encoding'] != '') {
502
			$this->debug('got content encoding: ' . $this->headers['content-encoding']);
503
			if ($this->headers['content-encoding'] == 'deflate' || $this->headers['content-encoding'] == 'gzip') {
504
		    	// if decoding works, use it. else assume data wasn't gzencoded
505
				if (function_exists('gzuncompress')) {
506
					if ($this->headers['content-encoding'] == 'deflate' && $degzdata = @gzuncompress($data)) {
507
						$data = $degzdata;
508
					} elseif ($this->headers['content-encoding'] == 'gzip' && $degzdata = gzinflate(substr($data, 10))) {
509
						$data = $degzdata;
510
					} else {
511
						$this->fault('SOAP-ENV:Client', 'Errors occurred when trying to decode the data');
512
						return;
513
					}
514
				} else {
515
					$this->fault('SOAP-ENV:Client', 'This Server does not support compressed data');
516
					return;
517
				}
518
			}
519
		}
520
		$this->request .= "\r\n".$data;
521
		$data = $this->parseRequest($this->headers, $data);
522
		$this->requestSOAP = $data;
0 ignored issues
show
Documentation Bug introduced by
It seems like $data can also be of type false. However, the property $requestSOAP is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
523
		$this->debug('leaving parse_request');
524
	}
525
526
	/**
527
	* invokes a PHP function for the requested SOAP method
528
	*
529
	* The following fields are set by this function (when successful)
530
	*
531
	* methodreturn
532
	*
533
	* Note that the PHP function that is called may also set the following
534
	* fields to affect the response sent to the client
535
	*
536
	* responseHeaders
537
	* outgoing_headers
538
	*
539
	* This sets the fault field on error
540
	*
541
	* @access   private
542
	*/
543
	function invoke_method() {
544
		$this->debug('in invoke_method, methodname=' . $this->methodname . ' methodURI=' . $this->methodURI . ' SOAPAction=' . $this->SOAPAction);
545
546
		//
547
		// if you are debugging in this area of the code, your service uses a class to implement methods,
548
		// you use SOAP RPC, and the client is .NET, please be aware of the following...
549
		// when the .NET wsdl.exe utility generates a proxy, it will remove the '.' or '..' from the
550
		// method name.  that is fine for naming the .NET methods.  it is not fine for properly constructing
551
		// the XML request and reading the XML response.  you need to add the RequestElementName and
552
		// ResponseElementName to the System.Web.Services.Protocols.SoapRpcMethodAttribute that wsdl.exe
553
		// generates for the method.  these parameters are used to specify the correct XML element names
554
		// for .NET to use, i.e. the names with the '.' in them.
555
		//
556
		$orig_methodname = $this->methodname;
557
		if ($this->wsdl) {
558
			if ($this->opData = $this->wsdl->getOperationData($this->methodname)) {
559
				$this->debug('in invoke_method, found WSDL operation=' . $this->methodname);
560
				$this->appendDebug('opData=' . $this->varDump($this->opData));
561
			} elseif ($this->opData = $this->wsdl->getOperationDataForSoapAction($this->SOAPAction)) {
562
				// Note: hopefully this case will only be used for doc/lit, since rpc services should have wrapper element
563
				$this->debug('in invoke_method, found WSDL soapAction=' . $this->SOAPAction . ' for operation=' . $this->opData['name']);
564
				$this->appendDebug('opData=' . $this->varDump($this->opData));
565
				$this->methodname = $this->opData['name'];
566
			} else {
567
				$this->debug('in invoke_method, no WSDL for operation=' . $this->methodname);
568
				$this->fault('SOAP-ENV:Client', "Operation '" . $this->methodname . "' is not defined in the WSDL for this service");
569
				return;
570
			}
571
		} else {
572
			$this->debug('in invoke_method, no WSDL to validate method');
573
		}
574
575
		// if a . is present in $this->methodname, we see if there is a class in scope,
576
		// which could be referred to. We will also distinguish between two deliminators,
577
		// to allow methods to be called a the class or an instance
578
		if (strpos($this->methodname, '..') > 0) {
579
			$delim = '..';
580
		} else if (strpos($this->methodname, '.') > 0) {
581
			$delim = '.';
582
		} else {
583
			$delim = '';
584
		}
585
		$this->debug("in invoke_method, delim=$delim");
586
587
		$class = '';
588
		$method = '';
589
		if (strlen($delim) > 0 && substr_count($this->methodname, $delim) == 1) {
590
			$try_class = substr($this->methodname, 0, strpos($this->methodname, $delim));
591
			if (class_exists($try_class)) {
592
				// get the class and method name
593
				$class = $try_class;
594
				$method = substr($this->methodname, strpos($this->methodname, $delim) + strlen($delim));
595
				$this->debug("in invoke_method, class=$class method=$method delim=$delim");
596
			} else {
597
				$this->debug("in invoke_method, class=$try_class not found");
598
			}
599
		} else {
600
			$try_class = '';
601
			$this->debug("in invoke_method, no class to try");
602
		}
603
604
		// does method exist?
605
		if ($class == '') {
606
			if (!function_exists($this->methodname)) {
607
				$this->debug("in invoke_method, function '$this->methodname' not found!");
608
				$this->result = 'fault: method not found';
609
				$this->fault('SOAP-ENV:Client',"method '$this->methodname'('$orig_methodname') not defined in service('$try_class' '$delim')");
610
				return;
611
			}
612
		} else {
613
			$method_to_compare = (substr(phpversion(), 0, 2) == '4.') ? strtolower($method) : $method;
614
			if (!in_array($method_to_compare, get_class_methods($class))) {
615
				$this->debug("in invoke_method, method '$this->methodname' not found in class '$class'!");
616
				$this->result = 'fault: method not found';
617
				$this->fault('SOAP-ENV:Client',"method '$this->methodname'/'$method_to_compare'('$orig_methodname') not defined in service/'$class'('$try_class' '$delim')");
618
				return;
619
			}
620
		}
621
622
		// evaluate message, getting back parameters
623
		// verify that request parameters match the method's signature
624
		if(! $this->verify_method($this->methodname,$this->methodparams)){
625
			// debug
626
			$this->debug('ERROR: request not verified against method signature');
627
			$this->result = 'fault: request failed validation against method signature';
628
			// return fault
629
			$this->fault('SOAP-ENV:Client',"Operation '$this->methodname' not defined in service.");
630
			return;
631
		}
632
633
		// if there are parameters to pass
634
		$this->debug('in invoke_method, params:');
635
		$this->appendDebug($this->varDump($this->methodparams));
636
		$this->debug("in invoke_method, calling '$this->methodname'");
637
		if (!function_exists('call_user_func_array')) {
638
			if ($class == '') {
639
				$this->debug('in invoke_method, calling function using eval()');
640
				$funcCall = "\$this->methodreturn = $this->methodname(";
641
			} else {
642
				if ($delim == '..') {
643
					$this->debug('in invoke_method, calling class method using eval()');
644
					$funcCall = "\$this->methodreturn = ".$class."::".$method."(";
645
				} else {
646
					$this->debug('in invoke_method, calling instance method using eval()');
647
					// generate unique instance name
648
					$instname = "\$inst_".time();
649
					$funcCall = $instname." = new ".$class."(); ";
650
					$funcCall .= "\$this->methodreturn = ".$instname."->".$method."(";
651
				}
652
			}
653
			if ($this->methodparams) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->methodparams of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
654
				foreach ($this->methodparams as $param) {
655
					if (is_array($param) || is_object($param)) {
656
						$this->fault('SOAP-ENV:Client', 'NuSOAP does not handle complexType parameters correctly when using eval; call_user_func_array must be available');
657
						return;
658
					}
659
					$funcCall .= "\"$param\",";
660
				}
661
				$funcCall = substr($funcCall, 0, -1);
662
			}
663
			$funcCall .= ');';
664
			$this->debug('in invoke_method, function call: '.$funcCall);
665
			@eval($funcCall);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
It is generally not recommended to use eval unless absolutely required.

On one hand, eval might be exploited by malicious users if they somehow manage to inject dynamic content. On the other hand, with the emergence of faster PHP runtimes like the HHVM, eval prevents some optimization that they perform.

Loading history...
666
		} else {
667
			if ($class == '') {
668
				$this->debug('in invoke_method, calling function using call_user_func_array()');
669
				$call_arg = "$this->methodname";	// straight assignment changes $this->methodname to lower case after call_user_func_array()
670
			} elseif ($delim == '..') {
671
				$this->debug('in invoke_method, calling class method using call_user_func_array()');
672
				$call_arg = array ($class, $method);
673
			} else {
674
				$this->debug('in invoke_method, calling instance method using call_user_func_array()');
675
				$instance = new $class ();
676
				$call_arg = array(&$instance, $method);
677
			}
678
			if (is_array($this->methodparams)) {
679
				$this->methodreturn = call_user_func_array($call_arg, array_values($this->methodparams));
680
			} else {
681
				$this->methodreturn = call_user_func_array($call_arg, array());
682
			}
683
		}
684
        $this->debug('in invoke_method, methodreturn:');
685
        $this->appendDebug($this->varDump($this->methodreturn));
686
		$this->debug("in invoke_method, called method $this->methodname, received data of type ".gettype($this->methodreturn));
687
	}
688
689
	/**
690
	* serializes the return value from a PHP function into a full SOAP Envelope
691
	*
692
	* The following fields are set by this function (when successful)
693
	*
694
	* responseSOAP
695
	*
696
	* This sets the fault field on error
697
	*
698
	* @access   private
699
	*/
700
	function serialize_return() {
701
		$this->debug('Entering serialize_return methodname: ' . $this->methodname . ' methodURI: ' . $this->methodURI);
702
		// if fault
703
		if (isset($this->methodreturn) && is_object($this->methodreturn) && ((get_class($this->methodreturn) == 'soap_fault') || (get_class($this->methodreturn) == 'nusoap_fault'))) {
704
			$this->debug('got a fault object from method');
705
			$this->fault = $this->methodreturn;
706
			return;
707
		} elseif ($this->methodreturnisliteralxml) {
708
			$return_val = $this->methodreturn;
709
		// returned value(s)
710
		} else {
711
			$this->debug('got a(n) '.gettype($this->methodreturn).' from method');
712
			$this->debug('serializing return value');
713
			if($this->wsdl){
714
				if (sizeof($this->opData['output']['parts']) > 1) {
715
					$this->debug('more than one output part, so use the method return unchanged');
716
			    	$opParams = $this->methodreturn;
717
			    } elseif (sizeof($this->opData['output']['parts']) == 1) {
718
					$this->debug('exactly one output part, so wrap the method return in a simple array');
719
					// TODO: verify that it is not already wrapped!
720
			    	//foreach ($this->opData['output']['parts'] as $name => $type) {
721
					//	$this->debug('wrap in element named ' . $name);
722
			    	//}
723
			    	$opParams = array($this->methodreturn);
724
			    }
725
			    $return_val = $this->wsdl->serializeRPCParameters($this->methodname,'output',$opParams);
726
			    $this->appendDebug($this->wsdl->getDebug());
727
			    $this->wsdl->clearDebug();
728
				if($errstr = $this->wsdl->getError()){
729
					$this->debug('got wsdl error: '.$errstr);
730
					$this->fault('SOAP-ENV:Server', 'unable to serialize result');
731
					return;
732
				}
733
			} else {
734
				if (isset($this->methodreturn)) {
735
					$return_val = $this->serialize_val($this->methodreturn, 'return');
736
				} else {
737
					$return_val = '';
738
					$this->debug('in absence of WSDL, assume void return for backward compatibility');
739
				}
740
			}
741
		}
742
		$this->debug('return value:');
743
		$this->appendDebug($this->varDump($return_val));
744
745
		$this->debug('serializing response');
746
		if ($this->wsdl) {
747
			$this->debug('have WSDL for serialization: style is ' . $this->opData['style']);
748
			if ($this->opData['style'] == 'rpc') {
749
				$this->debug('style is rpc for serialization: use is ' . $this->opData['output']['use']);
750
				if ($this->opData['output']['use'] == 'literal') {
751
					// http://www.ws-i.org/Profiles/BasicProfile-1.1-2004-08-24.html R2735 says rpc/literal accessor elements should not be in a namespace
752
					if ($this->methodURI) {
753
						$payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>";
754
					} else {
755
						$payload = '<'.$this->methodname.'Response>'.$return_val.'</'.$this->methodname.'Response>';
756
					}
757
				} else {
758
					if ($this->methodURI) {
759
						$payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>";
760
					} else {
761
						$payload = '<'.$this->methodname.'Response>'.$return_val.'</'.$this->methodname.'Response>';
762
					}
763
				}
764
			} else {
765
				$this->debug('style is not rpc for serialization: assume document');
766
				$payload = $return_val;
767
			}
768
		} else {
769
			$this->debug('do not have WSDL for serialization: assume rpc/encoded');
770
			$payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>";
771
		}
772
		$this->result = 'successful';
773
		if($this->wsdl){
774
			//if($this->debug_flag){
775
            	$this->appendDebug($this->wsdl->getDebug());
776
            //	}
777
			if (isset($this->opData['output']['encodingStyle'])) {
778
				$encodingStyle = $this->opData['output']['encodingStyle'];
779
			} else {
780
				$encodingStyle = '';
781
			}
782
			// Added: In case we use a WSDL, return a serialized env. WITH the usedNamespaces.
783
			$this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders,$this->wsdl->usedNamespaces,$this->opData['style'],$this->opData['output']['use'],$encodingStyle);
784
		} else {
785
			$this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders);
786
		}
787
		$this->debug("Leaving serialize_return");
788
	}
789
790
	/**
791
	* sends an HTTP response
792
	*
793
	* The following fields are set by this function (when successful)
794
	*
795
	* outgoing_headers
796
	* response
797
	*
798
	* @access   private
799
	*/
800
	function send_response() {
801
		$this->debug('Enter send_response');
802
		if ($this->fault) {
803
			$payload = $this->fault->serialize();
804
			$this->outgoing_headers[] = "HTTP/1.0 500 Internal Server Error";
805
			$this->outgoing_headers[] = "Status: 500 Internal Server Error";
806
		} else {
807
			$payload = $this->responseSOAP;
808
			// Some combinations of PHP+Web server allow the Status
809
			// to come through as a header.  Since OK is the default
810
			// just do nothing.
811
			// $this->outgoing_headers[] = "HTTP/1.0 200 OK";
812
			// $this->outgoing_headers[] = "Status: 200 OK";
813
		}
814
        // add debug data if in debug mode
815
		if(isset($this->debug_flag) && $this->debug_flag){
816
        	$payload .= $this->getDebugAsXMLComment();
817
        }
818
		$this->outgoing_headers[] = "Server: $this->title Server v$this->version";
819
		preg_match('/\$Revisio' . 'n: ([^ ]+)/', $this->revision, $rev);
820
		$this->outgoing_headers[] = "X-SOAP-Server: $this->title/$this->version (".$rev[1].")";
821
		// Let the Web server decide about this
822
		//$this->outgoing_headers[] = "Connection: Close\r\n";
823
		$payload = $this->getHTTPBody($payload);
824
		$type = $this->getHTTPContentType();
825
		$charset = $this->getHTTPContentTypeCharset();
826
		$this->outgoing_headers[] = "Content-Type: $type" . ($charset ? '; charset=' . $charset : '');
827
		//begin code to compress payload - by John
828
		// NOTE: there is no way to know whether the Web server will also compress
829
		// this data.
830
		if (strlen($payload) > 1024 && isset($this->headers) && isset($this->headers['accept-encoding'])) {	
831
			if (strstr($this->headers['accept-encoding'], 'gzip')) {
832
				if (function_exists('gzencode')) {
833
					if (isset($this->debug_flag) && $this->debug_flag) {
834
						$payload .= "<!-- Content being gzipped -->";
835
					}
836
					$this->outgoing_headers[] = "Content-Encoding: gzip";
837
					$payload = gzencode($payload);
838
				} else {
839
					if (isset($this->debug_flag) && $this->debug_flag) {
840
						$payload .= "<!-- Content will not be gzipped: no gzencode -->";
841
					}
842
				}
843
			} elseif (strstr($this->headers['accept-encoding'], 'deflate')) {
844
				// Note: MSIE requires gzdeflate output (no Zlib header and checksum),
845
				// instead of gzcompress output,
846
				// which conflicts with HTTP 1.1 spec (http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.5)
847
				if (function_exists('gzdeflate')) {
848
					if (isset($this->debug_flag) && $this->debug_flag) {
849
						$payload .= "<!-- Content being deflated -->";
850
					}
851
					$this->outgoing_headers[] = "Content-Encoding: deflate";
852
					$payload = gzdeflate($payload);
853
				} else {
854
					if (isset($this->debug_flag) && $this->debug_flag) {
855
						$payload .= "<!-- Content will not be deflated: no gzcompress -->";
856
					}
857
				}
858
			}
859
		}
860
		//end code
861
		$this->outgoing_headers[] = "Content-Length: ".strlen($payload);
862
		reset($this->outgoing_headers);
863
		foreach($this->outgoing_headers as $hdr){
864
			header($hdr, false);
865
		}
866
		print $payload;
867
		$this->response = join("\r\n",$this->outgoing_headers)."\r\n\r\n".$payload;
868
	}
869
870
	/**
871
	* takes the value that was created by parsing the request
872
	* and compares to the method's signature, if available.
873
	*
874
	* @param	string	$operation	The operation to be invoked
875
	* @param	array	$request	The array of parameter values
876
	* @return	boolean	Whether the operation was found
877
	* @access   private
878
	*/
879
	function verify_method($operation,$request){
880
		if(isset($this->wsdl) && is_object($this->wsdl)){
881
			if($this->wsdl->getOperationData($operation)){
882
				return true;
883
			}
884
	    } elseif(isset($this->operations[$operation])){
885
			return true;
886
		}
887
		return false;
888
	}
889
890
	/**
891
	* processes SOAP message received from client
892
	*
893
	* @param	array	$headers	The HTTP headers
894
	* @param	string	$data		unprocessed request data from client
895
	* @return	mixed	value of the message, decoded into a PHP type
896
	* @access   private
897
	*/
898
    function parseRequest($headers, $data) {
899
		$this->debug('Entering parseRequest() for data of length ' . strlen($data) . ' headers:');
900
		$this->appendDebug($this->varDump($headers));
901
    	if (!isset($headers['content-type'])) {
902
			$this->setError('Request not of type text/xml (no content-type header)');
903
			return false;
904
    	}
905
		if (!strstr($headers['content-type'], 'text/xml')) {
906
			$this->setError('Request not of type text/xml');
907
			return false;
908
		}
909
		if (strpos($headers['content-type'], '=')) {
910
			$enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1));
911
			$this->debug('Got response encoding: ' . $enc);
912
			if(preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)){
913
				$this->xml_encoding = strtoupper($enc);
914
			} else {
915
				$this->xml_encoding = 'US-ASCII';
916
			}
917
		} else {
918
			// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
919
			$this->xml_encoding = 'ISO-8859-1';
920
		}
921
		$this->debug('Use encoding: ' . $this->xml_encoding . ' when creating nusoap_parser');
922
		// parse response, get soap parser obj
923
		$parser = new nusoap_parser($data,$this->xml_encoding,'',$this->decode_utf8);
924
		// parser debug
925
		$this->debug("parser debug: \n".$parser->getDebug());
926
		// if fault occurred during message parsing
927
		if($err = $parser->getError()){
928
			$this->result = 'fault: error in msg parsing: '.$err;
929
			$this->fault('SOAP-ENV:Client',"error in msg parsing:\n".$err);
930
		// else successfully parsed request into soapval object
931
		} else {
932
			// get/set methodname
933
			$this->methodURI = $parser->root_struct_namespace;
934
			$this->methodname = $parser->root_struct_name;
935
			$this->debug('methodname: '.$this->methodname.' methodURI: '.$this->methodURI);
936
			$this->debug('calling parser->get_soapbody()');
937
			$this->methodparams = $parser->get_soapbody();
938
			// get SOAP headers
939
			$this->requestHeaders = $parser->getHeaders();
940
			// get SOAP Header
941
			$this->requestHeader = $parser->get_soapheader();
942
            // add document for doclit support
943
            $this->document = $parser->document;
944
		}
945
	 }
946
947
	/**
948
	* gets the HTTP body for the current response.
949
	*
950
	* @param string $soapmsg The SOAP payload
951
	* @return string The HTTP body, which includes the SOAP payload
952
	* @access private
953
	*/
954
	function getHTTPBody($soapmsg) {
955
		return $soapmsg;
956
	}
957
	
958
	/**
959
	* gets the HTTP content type for the current response.
960
	*
961
	* Note: getHTTPBody must be called before this.
962
	*
963
	* @return string the HTTP content type for the current response.
964
	* @access private
965
	*/
966
	function getHTTPContentType() {
967
		return 'text/xml';
968
	}
969
	
970
	/**
971
	* gets the HTTP content type charset for the current response.
972
	* returns false for non-text content types.
973
	*
974
	* Note: getHTTPBody must be called before this.
975
	*
976
	* @return string the HTTP content type charset for the current response.
977
	* @access private
978
	*/
979
	function getHTTPContentTypeCharset() {
980
		return $this->soap_defencoding;
981
	}
982
983
	/**
984
	* add a method to the dispatch map (this has been replaced by the register method)
985
	*
986
	* @param    string $methodname
987
	* @param    string $in array of input values
988
	* @param    string $out array of output values
989
	* @access   public
990
	* @deprecated
991
	*/
992
	function add_to_map($methodname,$in,$out){
993
			$this->operations[$methodname] = array('name' => $methodname,'in' => $in,'out' => $out);
994
	}
995
996
	/**
997
	* register a service function with the server
998
	*
999
	* @param    string $name the name of the PHP function, class.method or class..method
1000
	* @param    array $in assoc array of input values: key = param name, value = param type
1001
	* @param    array $out assoc array of output values: key = param name, value = param type
1002
	* @param	mixed $namespace the element namespace for the method or false
1003
	* @param	mixed $soapaction the soapaction for the method or false
1004
	* @param	mixed $style optional (rpc|document) or false Note: when 'document' is specified, parameter and return wrappers are created for you automatically
1005
	* @param	mixed $use optional (encoded|literal) or false
1006
	* @param	string $documentation optional Description to include in WSDL
1007
	* @param	string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded)
1008
	* @access   public
1009
	*/
1010
	function register($name,$in=array(),$out=array(),$namespace=false,$soapaction=false,$style=false,$use=false,$documentation='',$encodingStyle=''){
1011
		global $HTTP_SERVER_VARS;
1012
1013
		if($this->externalWSDLURL){
1014
			die('You cannot bind to an external WSDL file, and register methods outside of it! Please choose either WSDL or no WSDL.');
1015
		}
1016
		if (! $name) {
1017
			die('You must specify a name when you register an operation');
1018
		}
1019
		if (!is_array($in)) {
1020
			die('You must provide an array for operation inputs');
1021
		}
1022
		if (!is_array($out)) {
1023
			die('You must provide an array for operation outputs');
1024
		}
1025
		if(false == $namespace) {
0 ignored issues
show
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
1026
		}
1027
		if(false == $soapaction) {
1028
			if (isset($_SERVER)) {
1029
				$SERVER_NAME = $_SERVER['SERVER_NAME'];
1030
				$SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
1031
				$HTTPS = isset($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] : (isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off');
1032
			} elseif (isset($HTTP_SERVER_VARS)) {
1033
				$SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME'];
1034
				$SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME'];
1035
				$HTTPS = isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off';
1036
			} else {
1037
				$this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
1038
			}
1039
        	if ($HTTPS == '1' || $HTTPS == 'on') {
1040
        		$SCHEME = 'https';
1041
        	} else {
1042
        		$SCHEME = 'http';
1043
        	}
1044
			$soapaction = "$SCHEME://$SERVER_NAME$SCRIPT_NAME/$name";
1045
		}
1046
		if(false == $style) {
1047
			$style = "rpc";
1048
		}
1049
		if(false == $use) {
1050
			$use = "encoded";
1051
		}
1052
		if ($use == 'encoded' && $encodingStyle == '') {
1053
			$encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
1054
		}
1055
1056
		$this->operations[$name] = array(
1057
	    'name' => $name,
1058
	    'in' => $in,
1059
	    'out' => $out,
1060
	    'namespace' => $namespace,
1061
	    'soapaction' => $soapaction,
1062
	    'style' => $style);
1063
        if($this->wsdl){
1064
        	$this->wsdl->addOperation($name,$in,$out,$namespace,$soapaction,$style,$use,$documentation,$encodingStyle);
1065
	    }
1066
		return true;
1067
	}
1068
1069
	/**
1070
	* Specify a fault to be returned to the client.
1071
	* This also acts as a flag to the server that a fault has occured.
1072
	*
1073
	* @param	string $faultcode
1074
	* @param	string $faultstring
1075
	* @param	string $faultactor
1076
	* @param	string $faultdetail
1077
	* @access   public
1078
	*/
1079
	function fault($faultcode,$faultstring,$faultactor='',$faultdetail=''){
1080
		if ($faultdetail == '' && $this->debug_flag) {
1081
			$faultdetail = $this->getDebug();
1082
		}
1083
		$this->fault = new nusoap_fault($faultcode,$faultactor,$faultstring,$faultdetail);
1084
		$this->fault->soap_defencoding = $this->soap_defencoding;
1085
	}
1086
1087
    /**
1088
    * Sets up wsdl object.
1089
    * Acts as a flag to enable internal WSDL generation
1090
    *
1091
    * @param string $serviceName, name of the service
0 ignored issues
show
There is no parameter named $serviceName,. Did you maybe mean $serviceName?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
1092
    * @param mixed $namespace optional 'tns' service namespace or false
1093
    * @param mixed $endpoint optional URL of service endpoint or false
1094
    * @param string $style optional (rpc|document) WSDL style (also specified by operation)
1095
    * @param string $transport optional SOAP transport
1096
    * @param mixed $schemaTargetNamespace optional 'types' targetNamespace for service schema or false
1097
    */
1098
    function configureWSDL($serviceName,$namespace = false,$endpoint = false,$style='rpc', $transport = 'http://schemas.xmlsoap.org/soap/http', $schemaTargetNamespace = false)
1099
    {
1100
    	global $HTTP_SERVER_VARS;
1101
1102
		if (isset($_SERVER)) {
1103
			$SERVER_NAME = $_SERVER['SERVER_NAME'];
1104
			$SERVER_PORT = $_SERVER['SERVER_PORT'];
1105
			$SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
1106
			$HTTPS = isset($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] : (isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off');
1107
		} elseif (isset($HTTP_SERVER_VARS)) {
1108
			$SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME'];
1109
			$SERVER_PORT = $HTTP_SERVER_VARS['SERVER_PORT'];
1110
			$SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME'];
1111
			$HTTPS = isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off';
1112
		} else {
1113
			$this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
1114
		}
1115
		// If server name has port number attached then strip it (else port number gets duplicated in WSDL output) (occurred using lighttpd and FastCGI)
1116
		$colon = strpos($SERVER_NAME,":");
1117
		if ($colon) {
1118
		    $SERVER_NAME = substr($SERVER_NAME, 0, $colon);
1119
		}
1120
		if ($SERVER_PORT == 80) {
1121
			$SERVER_PORT = '';
1122
		} else {
1123
			$SERVER_PORT = ':' . $SERVER_PORT;
1124
		}
1125
        if(false == $namespace) {
1126
            $namespace = "http://$SERVER_NAME/soap/$serviceName";
1127
        }
1128
        
1129
        if(false == $endpoint) {
1130
        	if ($HTTPS == '1' || $HTTPS == 'on') {
1131
        		$SCHEME = 'https';
1132
        	} else {
1133
        		$SCHEME = 'http';
1134
        	}
1135
            $endpoint = "$SCHEME://$SERVER_NAME$SERVER_PORT$SCRIPT_NAME";
1136
        }
1137
        
1138
        if(false == $schemaTargetNamespace) {
1139
            $schemaTargetNamespace = $namespace;
1140
        }
1141
        
1142
		$this->wsdl = new wsdl;
1143
		$this->wsdl->serviceName = $serviceName;
1144
        $this->wsdl->endpoint = $endpoint;
1145
		$this->wsdl->namespaces['tns'] = $namespace;
1146
		$this->wsdl->namespaces['soap'] = 'http://schemas.xmlsoap.org/wsdl/soap/';
1147
		$this->wsdl->namespaces['wsdl'] = 'http://schemas.xmlsoap.org/wsdl/';
1148
		if ($schemaTargetNamespace != $namespace) {
1149
			$this->wsdl->namespaces['types'] = $schemaTargetNamespace;
1150
		}
1151
        $this->wsdl->schemas[$schemaTargetNamespace][0] = new nusoap_xmlschema('', '', $this->wsdl->namespaces);
1152
        if ($style == 'document') {
1153
	        $this->wsdl->schemas[$schemaTargetNamespace][0]->schemaInfo['elementFormDefault'] = 'qualified';
1154
        }
1155
        $this->wsdl->schemas[$schemaTargetNamespace][0]->schemaTargetNamespace = $schemaTargetNamespace;
1156
        $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/soap/encoding/'][0] = array('location' => '', 'loaded' => true);
1157
        $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/wsdl/'][0] = array('location' => '', 'loaded' => true);
1158
        $this->wsdl->bindings[$serviceName.'Binding'] = array(
1159
        	'name'=>$serviceName.'Binding',
1160
            'style'=>$style,
1161
            'transport'=>$transport,
1162
            'portType'=>$serviceName.'PortType');
1163
        $this->wsdl->ports[$serviceName.'Port'] = array(
1164
        	'binding'=>$serviceName.'Binding',
1165
            'location'=>$endpoint,
1166
            'bindingType'=>'http://schemas.xmlsoap.org/wsdl/soap/');
1167
    }
1168
}
1169
1170
/**
1171
 * Backward compatibility
1172
 */
1173
class soap_server extends nusoap_server {
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
1174
}
1175
1176
1177
?>