[ Index ] |
|
Code source de eGroupWare 1.2.106-2 |
1 <?php 2 // SOAP server class 3 4 // for example usage, see the test_server.php file. 5 6 class soap_server 7 { 8 function soap_server($data='',$serviceNow=False) 9 { 10 // create empty dispatch map 11 $this->dispatch_map = array(); 12 $this->debug_flag = True; 13 $this->debug_str = ''; 14 $this->headers = ''; 15 $this->request = ''; 16 $this->result = 'successful'; 17 $this->fault = false; 18 $this->fault_code = ''; 19 $this->fault_str = ''; 20 $this->fault_actor = ''; 21 22 if($serviceNow == 1) 23 { 24 $this->service($data); 25 } 26 } 27 28 // parses request and posts response 29 function service($data) 30 { 31 // $response is a soap_msg object 32 $response = get_class($data) == 'soapmsg' ? $date : $this->parseRequest($data); 33 $this->debug("parsed request and got an object of this class '".get_class($response)."'"); 34 $this->debug("server sending..."); 35 // pass along the debug string 36 if($this->debug_flag) 37 { 38 $response->debug($this->debug_str); 39 } 40 $payload = $response->serialize(); 41 // print headers 42 if($this->fault) 43 { 44 $header[] = "HTTP/1.0 500 Internal Server Error\r\n"; 45 } 46 else 47 { 48 $header[] = "HTTP/1.0 200 OK\r\n"; 49 $header[] = "Status: 200\r\n"; 50 } 51 $header[] = "Server: SOAPx4 Server v0.344359s\r\n"; 52 $header[] = "Connection: Close\r\n"; 53 $header[] = "Content-Type: text/xml; charset=UTF-8\r\n"; 54 $header[] = "Content-Length: ".strlen($payload)."\r\n\r\n"; 55 reset($header); 56 foreach($header as $hdr) 57 { 58 header($hdr); 59 } 60 print $payload; 61 } 62 63 function parseRequest($data="") 64 { 65 global $HTTP_SERVER_VARS; 66 67 $this->debug("entering parseRequest() on ".date("H:i Y-m-d")); 68 $request_uri = $HTTP_SERVER_VARS["REQUEST_URI"]; 69 $this->debug("request uri: $request_uri"); 70 // get headers 71 $headers_array = getallheaders(); 72 foreach($headers_array as $k=>$v) 73 { 74 $dump .= "$k: $v\r\n"; 75 } 76 $dump .= "\r\n\r\n".$data; 77 $this->headers = $headers_array; 78 $this->request = $dump; 79 80 // get SOAPAction header -> methodname 81 if($headers_array["SOAPAction"]) 82 { 83 $action = str_replace('"','',$headers_array["SOAPAction"]); 84 if(ereg("^urn:",$action)) 85 { 86 $this->service = substr($action,4); 87 } 88 elseif(ereg(".php",$action)) 89 { 90 $this->service = ereg_replace('"|/','',substr(strrchr($action,".php"),4,strlen(strrchr($action,"/")))); 91 } 92 $this->debug("got service: $this->service"); 93 } 94 else 95 { 96 // throw a fault if no soapaction 97 $this->debug("ERROR: no SOAPAction header found"); 98 } 99 // NOTE:::: throw a fault for no/bad soapaction here? 100 101 // parse response, get soap parser obj 102 $parser = CreateObject('phpgwapi.soap_parser',$data); 103 // get/set methodname 104 $this->methodname = $parser->root_struct_name; 105 $this->debug("method name: $this->methodname"); 106 107 // does method exist? 108 $test = ereg_replace("\.",'_',$this->methodname); 109 if(function_exists($test)) 110 { 111 $method = $this->methodname = $test; 112 $this->debug("method '$this->methodname' exists"); 113 } 114 else 115 { 116 /* egroupware customization - createobject based on methodname */ 117 list($app,$class,$method) = explode('.',$this->methodname); 118 if(ereg("^service",$app)) 119 { 120 $args = $class; 121 $class = 'service'; 122 $app = 'phpgwapi'; 123 $obj = CreateObject(sprintf('%s.%s',$app,$class),$args); 124 unset($args); 125 } 126 else 127 { 128 $obj = CreateObject(sprintf('%s.%s',$app,$class)); 129 } 130 $this->debug('app: ' . $app . ', class: ' . $class . ', method: ' . $method); 131 /* 132 // "method not found" fault here 133 $this->debug("method '$obj->method' not found!"); 134 $this->result = "fault: method not found"; 135 $this->make_fault("Server","method '$obj->method' not defined in service '$this->service'"); 136 return $this->fault(); 137 */ 138 } 139 140 // if fault occurred during message parsing 141 if($parser->fault()) 142 { 143 // parser debug 144 $this->debug($parser->debug_str); 145 $this->result = "fault: error in msg parsing or eval"; 146 $this->make_fault("Server","error in msg parsing or eval:\n".$parser->get_response()); 147 // return soapresp 148 return $this->fault(); 149 // else successfully parsed request into soapval object 150 } 151 else 152 { 153 // get eval_str 154 $this->debug("calling parser->get_response()"); 155 // evaluate it, getting back a soapval object 156 if(!$request_val = $parser->get_response()) 157 { 158 return $this->fault(); 159 } 160 // parser debug 161 $this->debug($parser->debug_str); 162 if(get_class($request_val) == "soapval") 163 { 164 if (is_object($obj)) 165 { 166 /* Add the function to the server map */ 167 $in = "array('" . implode("','",$obj->soap_functions[$method]['in']) . "')"; 168 $out = "array('" . implode("','",$obj->soap_functions[$method]['out']) . "')"; 169 $evalmap = "\$this->add_to_map(\$this->methodname,$in,$out);"; 170 eval($evalmap); 171 } 172 /* verify that soapval objects in request match the methods signature */ 173 if($this->verify_method($request_val)) 174 { 175 $this->debug("request data - name: $request_val->name, type: $request_val->type, value: $request_val->value"); 176 if($this->input_value) 177 { 178 /* decode the soapval object, and pass resulting values to the requested method */ 179 if(!$request_data = $request_val->decode()) 180 { 181 $this->make_fault("Server","Unable to decode response from soapval object into native php type."); 182 return $this->fault(); 183 } 184 $this->debug("request data: $request_data"); 185 } 186 187 /* if there are return values */ 188 if($this->return_type = $this->get_return_type()) 189 { 190 $this->debug("got return type: '$this->return_type'"); 191 /* if there are parameters to pass */ 192 if($request_data) 193 { 194 if (is_object($obj)) 195 { 196 $code = "\$method_response = call_user_method($method,$obj,"; 197 $this->debug("about to call object method '$class\-\>$method' with args"); 198 } 199 else 200 { 201 $code = '$method_response = ' . $this->methodname . "('"; 202 $args = implode("','",$request_data['return']); 203 $this->debug("about to call method '$this->methodname' with args: $args"); 204 } 205 /* call method with parameters */ 206 $code .= implode("','",$request_data['return']); 207 /* 208 while(list($x,$y) = each($request_data)) 209 { 210 $code .= "\$request_data[$x]" . ','; 211 } 212 $code = substr($code,0,-1) .");"; 213 */ 214 $code .= "');"; 215 $this->debug('CODE: ' . $code); 216 if(eval($code)) 217 { 218 if (is_object($obj)) 219 { 220 $this->make_fault("Server","Object method call failed for '$class\-\>$method' with params: ".join(',',$request_data)); 221 } 222 else 223 { 224 $this->make_fault("Server","Method call failed for '$this->methodname' with params: ".join(',',$request_data)); 225 } 226 return $this->fault(); 227 } 228 $this->debug('Response: ' . $method_response); 229 // _debug_array($method_response); 230 } 231 else 232 { 233 /* call method w/ no parameters */ 234 if (is_object($obj)) 235 { 236 $this->debug("about to call object method '$obj\-\>$method'"); 237 if(!$method_response = call_user_method($method,$obj)) 238 { 239 $this->make_fault("Server","Method call failed for '$obj->method' with no params"); 240 return $this->fault(); 241 } 242 } 243 else 244 { 245 $this->debug("about to call method '$this->methodname'"); 246 if(!$method_response = call_user_func($this->methodname)) 247 { 248 $this->make_fault("Server","Method call failed for '$this->methodname' with no params"); 249 return $this->fault(); 250 } 251 } 252 } 253 /* no return values */ 254 } 255 else 256 { 257 if($request_data) 258 { 259 /* call method with parameters */ 260 $code = "\$method_response = call_user_method(\$method,\$obj,"; 261 while(list($x,$y) = each($request_data)) 262 { 263 $code .= "\$request_data[$x]" . ','; 264 } 265 $code = substr($code,0,-1) .");"; 266 $this->debug("about to call object method '$obj\-\>$method'"); 267 eval($code); 268 } 269 else 270 { 271 /* call method w/ no parameters */ 272 if(is_object($obj)) 273 { 274 $this->debug("about to call object method '$obj\-\>$method'"); 275 call_user_method($method,$obj); 276 } 277 else 278 { 279 $this->debug("about to call method '$method'"); 280 call_user_func($method); 281 } 282 } 283 } 284 285 /* create soap_val object w/ return values from method, use method signature to determine type */ 286 if(get_class($method_response) != 'soapval') 287 { 288 $return_val = CreateObject('phpgwapi.soapval',$method,$this->return_type,$method_response); 289 } 290 else 291 { 292 $return_val = $method_response; 293 } 294 $this->debug($return_val->debug_str); 295 /* response object is a soap_msg object */ 296 $return_msg = CreateObject('phpgwapi.soapmsg',$method.'Response',array($return_val),$this->service); 297 if($this->debug_flag) 298 { 299 $return_msg->debug_flag = true; 300 } 301 $this->result = "successful"; 302 return $return_msg; 303 } 304 else 305 { 306 // debug 307 $this->debug("ERROR: request not verified against method signature"); 308 $this->result = "fault: request failed validation against method signature"; 309 // return soapresp 310 return $this->fault(); 311 } 312 } 313 else 314 { 315 // debug 316 $this->debug("ERROR: parser did not return soapval object: $request_val ".get_class($request_val)); 317 $this->result = "fault: parser did not return soapval object: $request_val"; 318 // return fault 319 $this->make_fault("Server","parser did not return soapval object: $request_val"); 320 return $this->fault(); 321 } 322 } 323 } 324 325 function verify_method($request) 326 { 327 //return true; 328 $this->debug("entered verify_method() w/ request name: ".$request->name); 329 $params = $request->value; 330 // if there are input parameters required... 331 if($sig = $this->dispatch_map[$this->methodname]["in"]) 332 { 333 $this->input_value = count($sig); 334 if(is_array($params)) 335 { 336 $this->debug("entered verify_method() with ".count($params)." parameters"); 337 foreach($params as $v) 338 { 339 $this->debug("param '$v->name' of type '$v->type'"); 340 } 341 // validate the number of parameters 342 if(count($params) == count($sig)) 343 { 344 $this->debug("got correct number of parameters: ".count($sig)); 345 // make array of param types 346 foreach($params as $param) 347 { 348 $p[] = strtolower($param->type); 349 } 350 // validate each param's type 351 for($i=0; $i < count($p); $i++) 352 { 353 // type not match 354 if(strtolower($sig[$i]) != strtolower($p[$i])) 355 { 356 $this->debug("mismatched parameter types: $sig[$i] != $p[$i]"); 357 $this->make_fault("Client","soap request contained mismatching parameters of name $v->name had type $p[$i], which did not match signature's type: $sig[$i]"); 358 return false; 359 } 360 $this->debug("parameter type match: $sig[$i] = $p[$i]"); 361 } 362 return true; 363 // oops, wrong number of paramss 364 } 365 else 366 { 367 $this->debug("oops, wrong number of parameter!"); 368 $this->make_fault("Client","soap request contained incorrect number of parameters. method '$this->methodname' required ".count($sig)." and request provided ".count($params)); 369 return false; 370 } 371 // oops, no params... 372 } 373 else 374 { 375 $this->debug("oops, no parameters sent! Method '$this->methodname' requires ".count($sig)." input parameters!"); 376 $this->make_fault("Client","soap request contained incorrect number of parameters. method '$this->methodname' requires ".count($sig)." parameters, and request provided none"); 377 return false; 378 } 379 // no params 380 } 381 elseif( (count($params)==0) && (count($sig) <= 1) ) 382 { 383 $this->input_values = 0; 384 return true; 385 } 386 else 387 { 388 //$this->debug("well, request passed parameters to a method that requires none?"); 389 //$this->make_fault("Client","method '$this->methodname' requires no parameters. The request passed in ".count($params).": ".@implode(" param: ",$params) ); 390 return true; 391 } 392 } 393 394 // get string return type from dispatch map 395 function get_return_type() 396 { 397 if(count($this->dispatch_map[$this->methodname]["out"]) >= 1) 398 { 399 $type = array_shift($this->dispatch_map[$this->methodname]["out"]); 400 $this->debug("got return type from dispatch map: '$type'"); 401 return $type; 402 } 403 return false; 404 } 405 406 // dbg 407 function debug($string) 408 { 409 if($this->debug_flag) 410 { 411 $this->debug_str .= "$string\n"; 412 } 413 } 414 415 // add a method to the dispatch map 416 function add_to_map($methodname,$in,$out) 417 { 418 $this->dispatch_map[$methodname]["in"] = $in; 419 $this->dispatch_map[$methodname]["out"] = $out; 420 } 421 422 // set up a fault 423 function fault() 424 { 425 return CreateObject('phpgwapi.soapmsg', 426 "Fault", 427 array( 428 "faultcode" => $this->fault_code, 429 "faultstring" => $this->fault_str, 430 "faultactor" => $this->fault_actor, 431 "faultdetail" => $this->fault_detail.$this->debug_str 432 ), 433 "http://schemas.xmlphpgwapi.org/soap/envelope/" 434 ); 435 } 436 437 function make_fault($fault_code,$fault_string) 438 { 439 $this->fault_code = $fault_code; 440 $this->fault_str = $fault_string; 441 $this->fault = true; 442 } 443 } 444 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 17:20:01 2007 | par Balluche grâce à PHPXref 0.7 |