00001 <?php 00002 00003 00004 00005 00016 class nusoap_server extends nusoap_base { 00022 var $headers = array(); 00028 var $request = ''; 00034 var $requestHeaders = ''; 00040 var $requestHeader = NULL; 00046 var $document = ''; 00052 var $requestSOAP = ''; 00058 var $methodURI = ''; 00064 var $methodname = ''; 00070 var $methodparams = array(); 00076 var $SOAPAction = ''; 00082 var $xml_encoding = ''; 00088 var $decode_utf8 = true; 00089 00095 var $outgoing_headers = array(); 00101 var $response = ''; 00107 var $responseHeaders = ''; 00113 var $responseSOAP = ''; 00119 var $methodreturn = false; 00125 var $methodreturnisliteralxml = false; 00131 var $fault = false; 00137 var $result = 'successful'; 00138 00145 var $operations = array(); 00151 var $wsdl = false; 00157 var $externalWSDLURL = false; 00163 var $debug_flag = false; 00164 00165 00173 function nusoap_server($wsdl=false){ 00174 parent::nusoap_base(); 00175 // turn on debugging? 00176 global $debug; 00177 global $HTTP_SERVER_VARS; 00178 00179 if (isset($_SERVER)) { 00180 $this->debug("_SERVER is defined:"); 00181 $this->appendDebug($this->varDump($_SERVER)); 00182 } elseif (isset($HTTP_SERVER_VARS)) { 00183 $this->debug("HTTP_SERVER_VARS is defined:"); 00184 $this->appendDebug($this->varDump($HTTP_SERVER_VARS)); 00185 } else { 00186 $this->debug("Neither _SERVER nor HTTP_SERVER_VARS is defined."); 00187 } 00188 00189 if (isset($debug)) { 00190 $this->debug("In nusoap_server, set debug_flag=$debug based on global flag"); 00191 $this->debug_flag = $debug; 00192 } elseif (isset($_SERVER['QUERY_STRING'])) { 00193 $qs = explode('&', $_SERVER['QUERY_STRING']); 00194 foreach ($qs as $v) { 00195 if (substr($v, 0, 6) == 'debug=') { 00196 $this->debug("In nusoap_server, set debug_flag=" . substr($v, 6) . " based on query string #1"); 00197 $this->debug_flag = substr($v, 6); 00198 } 00199 } 00200 } elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) { 00201 $qs = explode('&', $HTTP_SERVER_VARS['QUERY_STRING']); 00202 foreach ($qs as $v) { 00203 if (substr($v, 0, 6) == 'debug=') { 00204 $this->debug("In nusoap_server, set debug_flag=" . substr($v, 6) . " based on query string #2"); 00205 $this->debug_flag = substr($v, 6); 00206 } 00207 } 00208 } 00209 00210 // wsdl 00211 if($wsdl){ 00212 $this->debug("In nusoap_server, WSDL is specified"); 00213 if (is_object($wsdl) && (get_class($wsdl) == 'wsdl')) { 00214 $this->wsdl = $wsdl; 00215 $this->externalWSDLURL = $this->wsdl->wsdl; 00216 $this->debug('Use existing wsdl instance from ' . $this->externalWSDLURL); 00217 } else { 00218 $this->debug('Create wsdl from ' . $wsdl); 00219 $this->wsdl = new wsdl($wsdl); 00220 $this->externalWSDLURL = $wsdl; 00221 } 00222 $this->appendDebug($this->wsdl->getDebug()); 00223 $this->wsdl->clearDebug(); 00224 if($err = $this->wsdl->getError()){ 00225 die('WSDL ERROR: '.$err); 00226 } 00227 } 00228 } 00229 00236 function service($data){ 00237 global $HTTP_SERVER_VARS; 00238 00239 if (isset($_SERVER['REQUEST_METHOD'])) { 00240 $rm = $_SERVER['REQUEST_METHOD']; 00241 } elseif (isset($HTTP_SERVER_VARS['REQUEST_METHOD'])) { 00242 $rm = $HTTP_SERVER_VARS['REQUEST_METHOD']; 00243 } else { 00244 $rm = ''; 00245 } 00246 00247 if (isset($_SERVER['QUERY_STRING'])) { 00248 $qs = $_SERVER['QUERY_STRING']; 00249 } elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) { 00250 $qs = $HTTP_SERVER_VARS['QUERY_STRING']; 00251 } else { 00252 $qs = ''; 00253 } 00254 $this->debug("In service, request method=$rm query string=$qs strlen(\$data)=" . strlen($data)); 00255 00256 if ($rm == 'POST') { 00257 $this->debug("In service, invoke the request"); 00258 $this->parse_request($data); 00259 if (! $this->fault) { 00260 $this->invoke_method(); 00261 } 00262 if (! $this->fault) { 00263 $this->serialize_return(); 00264 } 00265 $this->send_response(); 00266 } elseif (ereg('wsdl', $qs) ){ 00267 $this->debug("In service, this is a request for WSDL"); 00268 if ($this->externalWSDLURL){ 00269 if (strpos($this->externalWSDLURL, "http://") !== false) { // assume URL 00270 $this->debug("In service, re-direct for WSDL"); 00271 header('Location: '.$this->externalWSDLURL); 00272 } else { // assume file 00273 $this->debug("In service, use file passthru for WSDL"); 00274 header("Content-Type: text/xml\r\n"); 00275 $pos = strpos($this->externalWSDLURL, "file://"); 00276 if ($pos === false) { 00277 $filename = $this->externalWSDLURL; 00278 } else { 00279 $filename = substr($this->externalWSDLURL, $pos + 7); 00280 } 00281 $fp = fopen($this->externalWSDLURL, 'r'); 00282 fpassthru($fp); 00283 } 00284 } elseif ($this->wsdl) { 00285 $this->debug("In service, serialize WSDL"); 00286 header("Content-Type: text/xml; charset=ISO-8859-1\r\n"); 00287 print $this->wsdl->serialize($this->debug_flag); 00288 if ($this->debug_flag) { 00289 $this->debug('wsdl:'); 00290 $this->appendDebug($this->varDump($this->wsdl)); 00291 print $this->getDebugAsXMLComment(); 00292 } 00293 } else { 00294 $this->debug("In service, there is no WSDL"); 00295 header("Content-Type: text/html; charset=ISO-8859-1\r\n"); 00296 print "This service does not provide WSDL"; 00297 } 00298 } elseif ($this->wsdl) { 00299 $this->debug("In service, return Web description"); 00300 print $this->wsdl->webDescription(); 00301 } else { 00302 $this->debug("In service, no Web description"); 00303 header("Content-Type: text/html; charset=ISO-8859-1\r\n"); 00304 print "This service does not provide a Web description"; 00305 } 00306 } 00307 00320 function parse_http_headers() { 00321 global $HTTP_SERVER_VARS; 00322 00323 $this->request = ''; 00324 $this->SOAPAction = ''; 00325 if(function_exists('getallheaders')){ 00326 $this->debug("In parse_http_headers, use getallheaders"); 00327 $headers = getallheaders(); 00328 foreach($headers as $k=>$v){ 00329 $k = strtolower($k); 00330 $this->headers[$k] = $v; 00331 $this->request .= "$k: $v\r\n"; 00332 $this->debug("$k: $v"); 00333 } 00334 // get SOAPAction header 00335 if(isset($this->headers['soapaction'])){ 00336 $this->SOAPAction = str_replace('"','',$this->headers['soapaction']); 00337 } 00338 // get the character encoding of the incoming request 00339 if(isset($this->headers['content-type']) && strpos($this->headers['content-type'],'=')){ 00340 $enc = str_replace('"','',substr(strstr($this->headers["content-type"],'='),1)); 00341 if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){ 00342 $this->xml_encoding = strtoupper($enc); 00343 } else { 00344 $this->xml_encoding = 'US-ASCII'; 00345 } 00346 } else { 00347 // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 00348 $this->xml_encoding = 'ISO-8859-1'; 00349 } 00350 } elseif(isset($_SERVER) && is_array($_SERVER)){ 00351 $this->debug("In parse_http_headers, use _SERVER"); 00352 foreach ($_SERVER as $k => $v) { 00353 if (substr($k, 0, 5) == 'HTTP_') { 00354 $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5)))); 00355 } else { 00356 $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k))); 00357 } 00358 if ($k == 'soapaction') { 00359 // get SOAPAction header 00360 $k = 'SOAPAction'; 00361 $v = str_replace('"', '', $v); 00362 $v = str_replace('\\', '', $v); 00363 $this->SOAPAction = $v; 00364 } else if ($k == 'content-type') { 00365 // get the character encoding of the incoming request 00366 if (strpos($v, '=')) { 00367 $enc = substr(strstr($v, '='), 1); 00368 $enc = str_replace('"', '', $enc); 00369 $enc = str_replace('\\', '', $enc); 00370 if (eregi('^(ISO-8859-1|US-ASCII|UTF-8)$', $enc)) { 00371 $this->xml_encoding = strtoupper($enc); 00372 } else { 00373 $this->xml_encoding = 'US-ASCII'; 00374 } 00375 } else { 00376 // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 00377 $this->xml_encoding = 'ISO-8859-1'; 00378 } 00379 } 00380 $this->headers[$k] = $v; 00381 $this->request .= "$k: $v\r\n"; 00382 $this->debug("$k: $v"); 00383 } 00384 } elseif (is_array($HTTP_SERVER_VARS)) { 00385 $this->debug("In parse_http_headers, use HTTP_SERVER_VARS"); 00386 foreach ($HTTP_SERVER_VARS as $k => $v) { 00387 if (substr($k, 0, 5) == 'HTTP_') { 00388 $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5)))); $k = strtolower(substr($k, 5)); 00389 } else { 00390 $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k))); $k = strtolower($k); 00391 } 00392 if ($k == 'soapaction') { 00393 // get SOAPAction header 00394 $k = 'SOAPAction'; 00395 $v = str_replace('"', '', $v); 00396 $v = str_replace('\\', '', $v); 00397 $this->SOAPAction = $v; 00398 } else if ($k == 'content-type') { 00399 // get the character encoding of the incoming request 00400 if (strpos($v, '=')) { 00401 $enc = substr(strstr($v, '='), 1); 00402 $enc = str_replace('"', '', $enc); 00403 $enc = str_replace('\\', '', $enc); 00404 if (eregi('^(ISO-8859-1|US-ASCII|UTF-8)$', $enc)) { 00405 $this->xml_encoding = strtoupper($enc); 00406 } else { 00407 $this->xml_encoding = 'US-ASCII'; 00408 } 00409 } else { 00410 // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 00411 $this->xml_encoding = 'ISO-8859-1'; 00412 } 00413 } 00414 $this->headers[$k] = $v; 00415 $this->request .= "$k: $v\r\n"; 00416 $this->debug("$k: $v"); 00417 } 00418 } else { 00419 $this->debug("In parse_http_headers, HTTP headers not accessible"); 00420 $this->setError("HTTP headers not accessible"); 00421 } 00422 } 00423 00446 function parse_request($data='') { 00447 $this->debug('entering parse_request()'); 00448 $this->parse_http_headers(); 00449 $this->debug('got character encoding: '.$this->xml_encoding); 00450 // uncompress if necessary 00451 if (isset($this->headers['content-encoding']) && $this->headers['content-encoding'] != '') { 00452 $this->debug('got content encoding: ' . $this->headers['content-encoding']); 00453 if ($this->headers['content-encoding'] == 'deflate' || $this->headers['content-encoding'] == 'gzip') { 00454 // if decoding works, use it. else assume data wasn't gzencoded 00455 if (function_exists('gzuncompress')) { 00456 if ($this->headers['content-encoding'] == 'deflate' && $degzdata = @gzuncompress($data)) { 00457 $data = $degzdata; 00458 } elseif ($this->headers['content-encoding'] == 'gzip' && $degzdata = gzinflate(substr($data, 10))) { 00459 $data = $degzdata; 00460 } else { 00461 $this->fault('SOAP-ENV:Client', 'Errors occurred when trying to decode the data'); 00462 return; 00463 } 00464 } else { 00465 $this->fault('SOAP-ENV:Client', 'This Server does not support compressed data'); 00466 return; 00467 } 00468 } 00469 } 00470 $this->request .= "\r\n".$data; 00471 $data = $this->parseRequest($this->headers, $data); 00472 $this->requestSOAP = $data; 00473 $this->debug('leaving parse_request'); 00474 } 00475 00493 function invoke_method() { 00494 $this->debug('in invoke_method, methodname=' . $this->methodname . ' methodURI=' . $this->methodURI . ' SOAPAction=' . $this->SOAPAction); 00495 00496 if ($this->wsdl) { 00497 if ($this->opData = $this->wsdl->getOperationData($this->methodname)) { 00498 $this->debug('in invoke_method, found WSDL operation=' . $this->methodname); 00499 $this->appendDebug('opData=' . $this->varDump($this->opData)); 00500 } elseif ($this->opData = $this->wsdl->getOperationDataForSoapAction($this->SOAPAction)) { 00501 // Note: hopefully this case will only be used for doc/lit, since rpc services should have wrapper element 00502 $this->debug('in invoke_method, found WSDL soapAction=' . $this->SOAPAction . ' for operation=' . $this->opData['name']); 00503 $this->appendDebug('opData=' . $this->varDump($this->opData)); 00504 $this->methodname = $this->opData['name']; 00505 } else { 00506 $this->debug('in invoke_method, no WSDL for operation=' . $this->methodname); 00507 $this->fault('SOAP-ENV:Client', "Operation '" . $this->methodname . "' is not defined in the WSDL for this service"); 00508 return; 00509 } 00510 } else { 00511 $this->debug('in invoke_method, no WSDL to validate method'); 00512 } 00513 00514 // if a . is present in $this->methodname, we see if there is a class in scope, 00515 // which could be referred to. We will also distinguish between two deliminators, 00516 // to allow methods to be called a the class or an instance 00517 $class = ''; 00518 $method = ''; 00519 if (strpos($this->methodname, '..') > 0) { 00520 $delim = '..'; 00521 } else if (strpos($this->methodname, '.') > 0) { 00522 $delim = '.'; 00523 } else { 00524 $delim = ''; 00525 } 00526 00527 if (strlen($delim) > 0 && substr_count($this->methodname, $delim) == 1 && 00528 class_exists(substr($this->methodname, 0, strpos($this->methodname, $delim)))) { 00529 // get the class and method name 00530 $class = substr($this->methodname, 0, strpos($this->methodname, $delim)); 00531 $method = substr($this->methodname, strpos($this->methodname, $delim) + strlen($delim)); 00532 $this->debug("in invoke_method, class=$class method=$method delim=$delim"); 00533 } 00534 00535 // does method exist? 00536 if ($class == '') { 00537 if (!function_exists($this->methodname)) { 00538 $this->debug("in invoke_method, function '$this->methodname' not found!"); 00539 $this->result = 'fault: method not found'; 00540 $this->fault('SOAP-ENV:Client',"method '$this->methodname' not defined in service"); 00541 return; 00542 } 00543 } else { 00544 $method_to_compare = (substr(phpversion(), 0, 2) == '4.') ? strtolower($method) : $method; 00545 if (!in_array($method_to_compare, get_class_methods($class))) { 00546 $this->debug("in invoke_method, method '$this->methodname' not found in class '$class'!"); 00547 $this->result = 'fault: method not found'; 00548 $this->fault('SOAP-ENV:Client',"method '$this->methodname' not defined in service"); 00549 return; 00550 } 00551 } 00552 00553 // evaluate message, getting back parameters 00554 // verify that request parameters match the method's signature 00555 if(! $this->verify_method($this->methodname,$this->methodparams)){ 00556 // debug 00557 $this->debug('ERROR: request not verified against method signature'); 00558 $this->result = 'fault: request failed validation against method signature'; 00559 // return fault 00560 $this->fault('SOAP-ENV:Client',"Operation '$this->methodname' not defined in service."); 00561 return; 00562 } 00563 00564 // if there are parameters to pass 00565 $this->debug('in invoke_method, params:'); 00566 $this->appendDebug($this->varDump($this->methodparams)); 00567 $this->debug("in invoke_method, calling '$this->methodname'"); 00568 if (!function_exists('call_user_func_array')) { 00569 if ($class == '') { 00570 $this->debug('in invoke_method, calling function using eval()'); 00571 $funcCall = "\$this->methodreturn = $this->methodname("; 00572 } else { 00573 if ($delim == '..') { 00574 $this->debug('in invoke_method, calling class method using eval()'); 00575 $funcCall = "\$this->methodreturn = ".$class."::".$method."("; 00576 } else { 00577 $this->debug('in invoke_method, calling instance method using eval()'); 00578 // generate unique instance name 00579 $instname = "\$inst_".time(); 00580 $funcCall = $instname." = new ".$class."(); "; 00581 $funcCall .= "\$this->methodreturn = ".$instname."->".$method."("; 00582 } 00583 } 00584 if ($this->methodparams) { 00585 foreach ($this->methodparams as $param) { 00586 if (is_array($param) || is_object($param)) { 00587 $this->fault('SOAP-ENV:Client', 'NuSOAP does not handle complexType parameters correctly when using eval; call_user_func_array must be available'); 00588 return; 00589 } 00590 $funcCall .= "\"$param\","; 00591 } 00592 $funcCall = substr($funcCall, 0, -1); 00593 } 00594 $funcCall .= ');'; 00595 $this->debug('in invoke_method, function call: '.$funcCall); 00596 @eval($funcCall); 00597 } else { 00598 if ($class == '') { 00599 $this->debug('in invoke_method, calling function using call_user_func_array()'); 00600 $call_arg = "$this->methodname"; // straight assignment changes $this->methodname to lower case after call_user_func_array() 00601 } elseif ($delim == '..') { 00602 $this->debug('in invoke_method, calling class method using call_user_func_array()'); 00603 $call_arg = array ($class, $method); 00604 } else { 00605 $this->debug('in invoke_method, calling instance method using call_user_func_array()'); 00606 $instance = new $class (); 00607 $call_arg = array(&$instance, $method); 00608 } 00609 if (is_array($this->methodparams)) { 00610 $this->methodreturn = call_user_func_array($call_arg, array_values($this->methodparams)); 00611 } else { 00612 $this->methodreturn = call_user_func_array($call_arg, array()); 00613 } 00614 } 00615 $this->debug('in invoke_method, methodreturn:'); 00616 $this->appendDebug($this->varDump($this->methodreturn)); 00617 $this->debug("in invoke_method, called method $this->methodname, received data of type ".gettype($this->methodreturn)); 00618 } 00619 00631 function serialize_return() { 00632 $this->debug('Entering serialize_return methodname: ' . $this->methodname . ' methodURI: ' . $this->methodURI); 00633 // if fault 00634 if (isset($this->methodreturn) && ((get_class($this->methodreturn) == 'soap_fault') || (get_class($this->methodreturn) == 'nusoap_fault'))) { 00635 $this->debug('got a fault object from method'); 00636 $this->fault = $this->methodreturn; 00637 return; 00638 } elseif ($this->methodreturnisliteralxml) { 00639 $return_val = $this->methodreturn; 00640 // returned value(s) 00641 } else { 00642 $this->debug('got a(n) '.gettype($this->methodreturn).' from method'); 00643 $this->debug('serializing return value'); 00644 if($this->wsdl){ 00645 if (sizeof($this->opData['output']['parts']) > 1) { 00646 $this->debug('more than one output part, so use the method return unchanged'); 00647 $opParams = $this->methodreturn; 00648 } elseif (sizeof($this->opData['output']['parts']) == 1) { 00649 $this->debug('exactly one output part, so wrap the method return in a simple array'); 00650 // TODO: verify that it is not already wrapped! 00651 //foreach ($this->opData['output']['parts'] as $name => $type) { 00652 // $this->debug('wrap in element named ' . $name); 00653 //} 00654 $opParams = array($this->methodreturn); 00655 } 00656 $return_val = $this->wsdl->serializeRPCParameters($this->methodname,'output',$opParams); 00657 $this->appendDebug($this->wsdl->getDebug()); 00658 $this->wsdl->clearDebug(); 00659 if($errstr = $this->wsdl->getError()){ 00660 $this->debug('got wsdl error: '.$errstr); 00661 $this->fault('SOAP-ENV:Server', 'unable to serialize result'); 00662 return; 00663 } 00664 } else { 00665 if (isset($this->methodreturn)) { 00666 $return_val = $this->serialize_val($this->methodreturn, 'return'); 00667 } else { 00668 $return_val = ''; 00669 $this->debug('in absence of WSDL, assume void return for backward compatibility'); 00670 } 00671 } 00672 } 00673 $this->debug('return value:'); 00674 $this->appendDebug($this->varDump($return_val)); 00675 00676 $this->debug('serializing response'); 00677 if ($this->wsdl) { 00678 $this->debug('have WSDL for serialization: style is ' . $this->opData['style']); 00679 if ($this->opData['style'] == 'rpc') { 00680 $this->debug('style is rpc for serialization: use is ' . $this->opData['output']['use']); 00681 if ($this->opData['output']['use'] == 'literal') { 00682 // 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 00683 if ($this->methodURI) { 00684 $payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>"; 00685 } else { 00686 $payload = '<'.$this->methodname.'Response>'.$return_val.'</'.$this->methodname.'Response>'; 00687 } 00688 } else { 00689 if ($this->methodURI) { 00690 $payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>"; 00691 } else { 00692 $payload = '<'.$this->methodname.'Response>'.$return_val.'</'.$this->methodname.'Response>'; 00693 } 00694 } 00695 } else { 00696 $this->debug('style is not rpc for serialization: assume document'); 00697 $payload = $return_val; 00698 } 00699 } else { 00700 $this->debug('do not have WSDL for serialization: assume rpc/encoded'); 00701 $payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>"; 00702 } 00703 $this->result = 'successful'; 00704 if($this->wsdl){ 00705 //if($this->debug_flag){ 00706 $this->appendDebug($this->wsdl->getDebug()); 00707 // } 00708 if (isset($opData['output']['encodingStyle'])) { 00709 $encodingStyle = $opData['output']['encodingStyle']; 00710 } else { 00711 $encodingStyle = ''; 00712 } 00713 // Added: In case we use a WSDL, return a serialized env. WITH the usedNamespaces. 00714 $this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders,$this->wsdl->usedNamespaces,$this->opData['style'],$this->opData['output']['use'],$encodingStyle); 00715 } else { 00716 $this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders); 00717 } 00718 $this->debug("Leaving serialize_return"); 00719 } 00720 00731 function send_response() { 00732 $this->debug('Enter send_response'); 00733 if ($this->fault) { 00734 $payload = $this->fault->serialize(); 00735 $this->outgoing_headers[] = "HTTP/1.0 500 Internal Server Error"; 00736 $this->outgoing_headers[] = "Status: 500 Internal Server Error"; 00737 } else { 00738 $payload = $this->responseSOAP; 00739 // Some combinations of PHP+Web server allow the Status 00740 // to come through as a header. Since OK is the default 00741 // just do nothing. 00742 // $this->outgoing_headers[] = "HTTP/1.0 200 OK"; 00743 // $this->outgoing_headers[] = "Status: 200 OK"; 00744 } 00745 // add debug data if in debug mode 00746 if(isset($this->debug_flag) && $this->debug_flag){ 00747 $payload .= $this->getDebugAsXMLComment(); 00748 } 00749 $this->outgoing_headers[] = "Server: $this->title Server v$this->version"; 00750 ereg('\$Revisio' . 'n: ([^ ]+)', $this->revision, $rev); 00751 $this->outgoing_headers[] = "X-SOAP-Server: $this->title/$this->version (".$rev[1].")"; 00752 // Let the Web server decide about this 00753 //$this->outgoing_headers[] = "Connection: Close\r\n"; 00754 $payload = $this->getHTTPBody($payload); 00755 $type = $this->getHTTPContentType(); 00756 $charset = $this->getHTTPContentTypeCharset(); 00757 $this->outgoing_headers[] = "Content-Type: $type" . ($charset ? '; charset=' . $charset : ''); 00758 //begin code to compress payload - by John 00759 // NOTE: there is no way to know whether the Web server will also compress 00760 // this data. 00761 if (strlen($payload) > 1024 && isset($this->headers) && isset($this->headers['accept-encoding'])) { 00762 if (strstr($this->headers['accept-encoding'], 'gzip')) { 00763 if (function_exists('gzencode')) { 00764 if (isset($this->debug_flag) && $this->debug_flag) { 00765 $payload .= "<!-- Content being gzipped -->"; 00766 } 00767 $this->outgoing_headers[] = "Content-Encoding: gzip"; 00768 $payload = gzencode($payload); 00769 } else { 00770 if (isset($this->debug_flag) && $this->debug_flag) { 00771 $payload .= "<!-- Content will not be gzipped: no gzencode -->"; 00772 } 00773 } 00774 } elseif (strstr($this->headers['accept-encoding'], 'deflate')) { 00775 // Note: MSIE requires gzdeflate output (no Zlib header and checksum), 00776 // instead of gzcompress output, 00777 // which conflicts with HTTP 1.1 spec (http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.5) 00778 if (function_exists('gzdeflate')) { 00779 if (isset($this->debug_flag) && $this->debug_flag) { 00780 $payload .= "<!-- Content being deflated -->"; 00781 } 00782 $this->outgoing_headers[] = "Content-Encoding: deflate"; 00783 $payload = gzdeflate($payload); 00784 } else { 00785 if (isset($this->debug_flag) && $this->debug_flag) { 00786 $payload .= "<!-- Content will not be deflated: no gzcompress -->"; 00787 } 00788 } 00789 } 00790 } 00791 //end code 00792 $this->outgoing_headers[] = "Content-Length: ".strlen($payload); 00793 reset($this->outgoing_headers); 00794 foreach($this->outgoing_headers as $hdr){ 00795 header($hdr, false); 00796 } 00797 print $payload; 00798 $this->response = join("\r\n",$this->outgoing_headers)."\r\n\r\n".$payload; 00799 } 00800 00810 function verify_method($operation,$request){ 00811 if(isset($this->wsdl) && is_object($this->wsdl)){ 00812 if($this->wsdl->getOperationData($operation)){ 00813 return true; 00814 } 00815 } elseif(isset($this->operations[$operation])){ 00816 return true; 00817 } 00818 return false; 00819 } 00820 00829 function parseRequest($headers, $data) { 00830 $this->debug('Entering parseRequest() for data of length ' . strlen($data) . ' headers:'); 00831 $this->appendDebug($this->varDump($headers)); 00832 if (!isset($headers['content-type'])) { 00833 $this->setError('Request not of type text/xml (no content-type header)'); 00834 return false; 00835 } 00836 if (!strstr($headers['content-type'], 'text/xml')) { 00837 $this->setError('Request not of type text/xml'); 00838 return false; 00839 } 00840 if (strpos($headers['content-type'], '=')) { 00841 $enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1)); 00842 $this->debug('Got response encoding: ' . $enc); 00843 if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){ 00844 $this->xml_encoding = strtoupper($enc); 00845 } else { 00846 $this->xml_encoding = 'US-ASCII'; 00847 } 00848 } else { 00849 // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1 00850 $this->xml_encoding = 'ISO-8859-1'; 00851 } 00852 $this->debug('Use encoding: ' . $this->xml_encoding . ' when creating nusoap_parser'); 00853 // parse response, get soap parser obj 00854 $parser = new nusoap_parser($data,$this->xml_encoding,'',$this->decode_utf8); 00855 // parser debug 00856 $this->debug("parser debug: \n".$parser->getDebug()); 00857 // if fault occurred during message parsing 00858 if($err = $parser->getError()){ 00859 $this->result = 'fault: error in msg parsing: '.$err; 00860 $this->fault('SOAP-ENV:Client',"error in msg parsing:\n".$err); 00861 // else successfully parsed request into soapval object 00862 } else { 00863 // get/set methodname 00864 $this->methodURI = $parser->root_struct_namespace; 00865 $this->methodname = $parser->root_struct_name; 00866 $this->debug('methodname: '.$this->methodname.' methodURI: '.$this->methodURI); 00867 $this->debug('calling parser->get_soapbody()'); 00868 $this->methodparams = $parser->get_soapbody(); 00869 // get SOAP headers 00870 $this->requestHeaders = $parser->getHeaders(); 00871 // get SOAP Header 00872 $this->requestHeader = $parser->get_soapheader(); 00873 // add document for doclit support 00874 $this->document = $parser->document; 00875 } 00876 } 00877 00885 function getHTTPBody($soapmsg) { 00886 return $soapmsg; 00887 } 00888 00897 function getHTTPContentType() { 00898 return 'text/xml'; 00899 } 00900 00910 function getHTTPContentTypeCharset() { 00911 return $this->soap_defencoding; 00912 } 00913 00923 function add_to_map($methodname,$in,$out){ 00924 $this->operations[$methodname] = array('name' => $methodname,'in' => $in,'out' => $out); 00925 } 00926 00941 function register($name,$in=array(),$out=array(),$namespace=false,$soapaction=false,$style=false,$use=false,$documentation='',$encodingStyle=''){ 00942 global $HTTP_SERVER_VARS; 00943 00944 if($this->externalWSDLURL){ 00945 die('You cannot bind to an external WSDL file, and register methods outside of it! Please choose either WSDL or no WSDL.'); 00946 } 00947 if (! $name) { 00948 die('You must specify a name when you register an operation'); 00949 } 00950 if (!is_array($in)) { 00951 die('You must provide an array for operation inputs'); 00952 } 00953 if (!is_array($out)) { 00954 die('You must provide an array for operation outputs'); 00955 } 00956 if(false == $namespace) { 00957 } 00958 if(false == $soapaction) { 00959 if (isset($_SERVER)) { 00960 $SERVER_NAME = $_SERVER['SERVER_NAME']; 00961 $SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME']; 00962 $HTTPS = isset($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] : (isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off'); 00963 } elseif (isset($HTTP_SERVER_VARS)) { 00964 $SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME']; 00965 $SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME']; 00966 $HTTPS = isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off'; 00967 } else { 00968 $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available"); 00969 } 00970 if ($HTTPS == '1' || $HTTPS == 'on') { 00971 $SCHEME = 'https'; 00972 } else { 00973 $SCHEME = 'http'; 00974 } 00975 $soapaction = "$SCHEME://$SERVER_NAME$SCRIPT_NAME/$name"; 00976 } 00977 if(false == $style) { 00978 $style = "rpc"; 00979 } 00980 if(false == $use) { 00981 $use = "encoded"; 00982 } 00983 if ($use == 'encoded' && $encodingStyle == '') { 00984 $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/'; 00985 } 00986 00987 $this->operations[$name] = array( 00988 'name' => $name, 00989 'in' => $in, 00990 'out' => $out, 00991 'namespace' => $namespace, 00992 'soapaction' => $soapaction, 00993 'style' => $style); 00994 if($this->wsdl){ 00995 $this->wsdl->addOperation($name,$in,$out,$namespace,$soapaction,$style,$use,$documentation,$encodingStyle); 00996 } 00997 return true; 00998 } 00999 01010 function fault($faultcode,$faultstring,$faultactor='',$faultdetail=''){ 01011 if ($faultdetail == '' && $this->debug_flag) { 01012 $faultdetail = $this->getDebug(); 01013 } 01014 $this->fault = new nusoap_fault($faultcode,$faultactor,$faultstring,$faultdetail); 01015 $this->fault->soap_defencoding = $this->soap_defencoding; 01016 } 01017 01029 function configureWSDL($serviceName,$namespace = false,$endpoint = false,$style='rpc', $transport = 'http://schemas.xmlsoap.org/soap/http', $schemaTargetNamespace = false) 01030 { 01031 global $HTTP_SERVER_VARS; 01032 01033 if (isset($_SERVER)) { 01034 $SERVER_NAME = $_SERVER['SERVER_NAME']; 01035 $SERVER_PORT = $_SERVER['SERVER_PORT']; 01036 $SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME']; 01037 $HTTPS = isset($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] : (isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off'); 01038 } elseif (isset($HTTP_SERVER_VARS)) { 01039 $SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME']; 01040 $SERVER_PORT = $HTTP_SERVER_VARS['SERVER_PORT']; 01041 $SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME']; 01042 $HTTPS = isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off'; 01043 } else { 01044 $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available"); 01045 } 01046 // If server name has port number attached then strip it (else port number gets duplicated in WSDL output) (occurred using lighttpd and FastCGI) 01047 $colon = strpos($SERVER_NAME,":"); 01048 if ($colon) { 01049 $SERVER_NAME = substr($SERVER_NAME, 0, $colon); 01050 } 01051 if ($SERVER_PORT == 80) { 01052 $SERVER_PORT = ''; 01053 } else { 01054 $SERVER_PORT = ':' . $SERVER_PORT; 01055 } 01056 if(false == $namespace) { 01057 $namespace = "http://$SERVER_NAME/soap/$serviceName"; 01058 } 01059 01060 if(false == $endpoint) { 01061 if ($HTTPS == '1' || $HTTPS == 'on') { 01062 $SCHEME = 'https'; 01063 } else { 01064 $SCHEME = 'http'; 01065 } 01066 $endpoint = "$SCHEME://$SERVER_NAME$SERVER_PORT$SCRIPT_NAME"; 01067 } 01068 01069 if(false == $schemaTargetNamespace) { 01070 $schemaTargetNamespace = $namespace; 01071 } 01072 01073 $this->wsdl = new wsdl; 01074 $this->wsdl->serviceName = $serviceName; 01075 $this->wsdl->endpoint = $endpoint; 01076 $this->wsdl->namespaces['tns'] = $namespace; 01077 $this->wsdl->namespaces['soap'] = 'http://schemas.xmlsoap.org/wsdl/soap/'; 01078 $this->wsdl->namespaces['wsdl'] = 'http://schemas.xmlsoap.org/wsdl/'; 01079 if ($schemaTargetNamespace != $namespace) { 01080 $this->wsdl->namespaces['types'] = $schemaTargetNamespace; 01081 } 01082 $this->wsdl->schemas[$schemaTargetNamespace][0] = new nusoap_xmlschema('', '', $this->wsdl->namespaces); 01083 if ($style == 'document') { 01084 $this->wsdl->schemas[$schemaTargetNamespace][0]->schemaInfo['elementFormDefault'] = 'qualified'; 01085 } 01086 $this->wsdl->schemas[$schemaTargetNamespace][0]->schemaTargetNamespace = $schemaTargetNamespace; 01087 $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/soap/encoding/'][0] = array('location' => '', 'loaded' => true); 01088 $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/wsdl/'][0] = array('location' => '', 'loaded' => true); 01089 $this->wsdl->bindings[$serviceName.'Binding'] = array( 01090 'name'=>$serviceName.'Binding', 01091 'style'=>$style, 01092 'transport'=>$transport, 01093 'portType'=>$serviceName.'PortType'); 01094 $this->wsdl->ports[$serviceName.'Port'] = array( 01095 'binding'=>$serviceName.'Binding', 01096 'location'=>$endpoint, 01097 'bindingType'=>'http://schemas.xmlsoap.org/wsdl/soap/'); 01098 } 01099 } 01100 01104 class soap_server extends nusoap_server { 01105 } 01106 01107 01108 ?>
Copyright © 2003 - 2009 MyOOS [Shopsystem]. All rights reserved. MyOOS [Shopsystem] is Free Software released under the GNU/GPL License. Webmaster: info@r23.de (Impressum) |
|