array(),"xml" => ""); private $post_xml = null; private $maarch_url = null; private $curl_res = null; function __construct($ws_conf_file_path="ws_conf.xml") { $ws_conf_file = new DomDocument('1.0', 'UTF-8'); if(!@$ws_conf_file->load($ws_conf_file_path)) { throw new Exception('Unable to load the web service config file '.$ws_conf_file_path); } else { $this->xp_conf_file = new domxpath($ws_conf_file); $lbx_conf = new DomDocument(); if(!@$lbx_conf->load("../xml/config.xml")) { throw new Exception('Unable to load the letterbox config file ../xml/config.xml'); } else { $xp_lbx_conf = new domxpath($lbx_conf); $this->maarch_url = $xp_lbx_conf->query("/ROOT/CONFIG/MaarchURL")->item(0)->nodeValue; } } try{ $this->curl_res = curl_init(); } catch(Exception $e){ throw new Exception($e->getMessage());} } function __destruct() { curl_close($this->curl_res); } static function wsErrorHandler($level, $string, $file, $ligne, $context) { switch ($level) { case E_ERROR: throw new Exception("Error $level : $string in : $file line : $ligne"); break; case E_WARNING: throw new Exception("Warning $level : $string in : $file line : $ligne"); break; case E_PARSE: throw new Exception("Parse Error $level : $string in : $file line : $ligne"); break; case E_NOTICE: throw new Exception("Notice $level : $string in : $file line : $ligne"); break; case E_CORE_ERROR: throw new Exception("Core Error $level : $string in : $file line : $ligne"); break; case E_CORE_WARNING: throw new Exception("Core Warning $level : $string in : $file line : $ligne"); break; case E_COMPILE_ERROR: throw new Exception("Compile Error $level : $string in : $file line : $ligne"); break; case E_COMPILE_WARNING: throw new Exception("Compile Warning $level : $string in : $file line : $ligne"); break; case E_USER_ERROR: throw new Exception("User Error $level : $string in : $file line : $ligne"); break; case E_USER_WARNING: throw new Exception("User Warning $level : $string in : $file line : $ligne"); break; case E_USER_NOTICE: throw new Exception("User Notice $level : $string in : $file line : $ligne"); break; case E_STRICT: throw new Exception("Strict Notice $level : $string in : $file line : $ligne"); break; case E_RECOVERABLE_ERROR: throw new Exception("Recoverable Error $level : $string in : $file line : $ligne"); break; default: throw new Exception("Unknown error $level : $string in : $file line : $ligne"); break; } return false; } function ws_available($ws_name) { $ws_found=false; $wss = $this->xp_conf_file->query("/config/ws/name"); foreach($wss as $ws) { if($ws->nodeValue == $ws_name) $ws_found = true; } return $ws_found; } function add_header($header) { $this->xml_response["headers"][] = $header; } function add_error_node($desc="Erreur Interne Inconnue",$http_error=500) { $this->ws_return_xml = new DomDocument('1.0','UTF-8'); $erreur_node = $this->ws_return_xml->createElement("erreur"); $desc_node = $this->ws_return_xml->createElement("desc"); if(mb_detect_encoding($desc,"auto") == 'UTF-8') $desc_node->nodeValue = $desc; else $desc_node->nodeValue = utf8_encode($desc); $erreur_node->appendChild($desc_node); $this->ws_return_xml->appendChild($erreur_node); $this->xml_response["xml"] = $this->ws_return_xml->saveXML(); $this->xml_response["headers"][] = $_SERVER["SERVER_PROTOCOL"]." $http_error"; } function add_succes_node($nodeName=null,$nodeValue=null) { if( empty($this->ws_return_xml) ) { $this->ws_return_xml = new DomDocument('1.0', 'UTF-8'); } if( $this->ws_return_xml->getElementsByTagName("erreur")->length < 1 && !empty($nodeName) && !empty($nodeValue) ) { $$nodeName = $this->ws_return_xml->createElement($nodeName); if(mb_detect_encoding($nodeValue,"auto") == 'UTF-8') $$nodeName->nodeValue = utf8_encode($nodeValue); else $$nodeName->nodeValue = $nodeValue; if( $this->ws_return_xml->getElementsByTagName("succes")->length > 0 ) { $succes_node = $this->ws_return_xml->getElementsByTagName("succes")->item(0); } else { $succes_node = $this->ws_return_xml->createElement("succes"); } $succes_node->appendChild($$nodeName); $this->ws_return_xml->appendChild($succes_node); } else { } $this->xml_response["xml"] = $this->ws_return_xml->saveXML(); $this->xml_response["headers"][] = $_SERVER["SERVER_PROTOCOL"]." 201"; } function getSession() { $lbx_conf = new DomDocument(); $lbx_conf->load("../xml/config.xml"); $xp_lbx_conf = new domxpath($lbx_conf); $url = $this->maarch_url.$this->session; $method = "GET"; return(unserialize($this->http_request($url,$method))); } function setSession($session) { $lbx_conf = new DomDocument(); $lbx_conf->load("../xml/config.xml"); $xp_lbx_conf = new domxpath($lbx_conf); $url = $this->maarch_url.$this->session; $method = "POST"; $post = array("session"=>urlencode(serialize($session))); $this->http_request($url,$method,$post); } function http_request($url,$method,$post_data=array(),$header=false) { if($method == 'POST') { curl_setopt($this->curl_res,CURLOPT_POST,TRUE); curl_setopt($this->curl_res,CURLOPT_POSTFIELDS,$post_data); } else { curl_setopt($this->curl_res,CURLOPT_POST,FALSE); curl_setopt($this->curl_res, CURLOPT_HTTPGET, TRUE); } curl_setopt($this->curl_res, CURLOPT_URL,$url); curl_setopt($this->curl_res, CURLOPT_COOKIEJAR,'cookie.txt'); curl_setopt($this->curl_res, CURLOPT_FOLLOWLOCATION, FALSE); curl_setopt($this->curl_res, CURLOPT_RETURNTRANSFER, TRUE); if($header) curl_setopt($this->curl_res, CURLOPT_HEADER, TRUE); else curl_setopt($this->curl_res, CURLOPT_HEADER, FALSE); return curl_exec($this->curl_res); } function execute($ws_name,$data) { //Verifie l'IP du client $auth_ip = false; $ips_client = $this->xp_conf_file->query("/config/ip_client"); //Aucune clause sur les IPs, on autorise tous les IPs if($ips_client->item(0) == null) $auth_ip = true; foreach($ips_client as $ip) if( $_SERVER["REMOTE_ADDR"] == $ip->nodeValue ) $auth_ip = true; if(!$auth_ip) { $this->add_error_node("L'IP ".$_SERVER["REMOTE_ADDR"]." n'est pas autorisé à utiliser ce service",403); return $this->xml_response; } //Aucun login / mot de passe : il faut s'authentifier if( empty($_SERVER["PHP_AUTH_USER"]) || empty($_SERVER["PHP_AUTH_PW"]) ){ //Demande l'authentification au client $this->add_header($_SERVER["SERVER_PROTOCOL"]." 401"); $this->add_header("WWW-Authenticate: Basic realm=\"Maarch WebServer Engine\""); return $this->xml_response; } //Login et mot de passe saisie : il faut le valider dans letterbox else { set_error_handler('ws::wsErrorHandler'); $url = $this->maarch_url.$this->xp_conf_file->query("/config/login_page")->item(0)->nodeValue; $method = "POST"; $post=array( "login" => $_SERVER["PHP_AUTH_USER"], "pass" => $_SERVER["PHP_AUTH_PW"], "submit" => "Envoyer" ); $this->http_request($url,$method,$post); $login_session = $this->getSession(); //Le login s'est-il correctement passé if(empty($login_session['user'])) { $this->add_error_node("_BAD_LOGIN_OR_PSW",403); $this->setSession(array()); restore_error_handler(); return $this->xml_response; } if(!empty($login_session['error'])) { $this->add_error_node($login_session['error'],403); $this->setSession(array()); restore_error_handler(); return $this->xml_response; } else restore_error_handler(); } //Verifie que le Service Web existe if(!$this->ws_available($ws_name)) { $this->add_error_node("Le service ".$ws_name." n'est pas disponible",500); $this->setSession(array()); return $this->xml_response; } //Si XML Posté, on vérifie qu'il est bien formé (?! qu'il est valide un xmlschema ?! ) if($data != null) { set_error_handler('ws::wsErrorHandler'); $this->post_xml = new DomDocument(); try{ $this->post_xml->loadXML($data); } catch(Exception $e) { $this->add_error_node($e->getMessage(),500); $this->setSession(array()); return $this->xml_response; } restore_error_handler(); } //Execution du script php correpondant au service set_error_handler('ws::wsErrorHandler'); $script_to_exe = $this->xp_conf_file->query("/config/ws[name='$ws_name']/script"); try{ include($script_to_exe->item(0)->nodeValue);} catch(Exception $e) { $this->add_error_node($e->getMessage(),500); $this->setSession(array()); return $this->xml_response; } restore_error_handler(); //Tout est OK $this->setSession(array()); return $this->xml_response; } function ws_available_list() { $wss = $this->xp_conf_file->query("/config/ws"); $wal = array(); for($i=0; $i < $wss->length; $i++) foreach($wss->item($i)->childNodes as $elt) $wal[$i][$elt->nodeName] = $elt->nodeValue; return $wal; } } ?>