/[cvs]/nfo/php/libs/org.netfrag.glib/DataSource/Proxy/XMLRPC.php
ViewVC logotype

Diff of /nfo/php/libs/org.netfrag.glib/DataSource/Proxy/XMLRPC.php

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.4 by joko, Fri Mar 28 03:00:12 2003 UTC revision 1.7 by joko, Fri Apr 18 15:42:26 2003 UTC
# Line 14  Line 14 
14  ##    $Id$  ##    $Id$
15  ##    --------------------------------------------------------------------------  ##    --------------------------------------------------------------------------
16  ##    $Log$  ##    $Log$
17    ##    Revision 1.7  2003/04/18 15:42:26  joko
18    ##    minor update to comment
19    ##
20    ##    Revision 1.6  2003/04/04 21:23:29  joko
21    ##    session-based rpc-communcation: revamped code (especially 'function _call')
22    ##    renamed state-handling trigger-methods: now _sleep and _wakeup
23    ##
24    ##    Revision 1.5  2003/03/28 06:56:52  joko
25    ##    updated logging/debugging code
26    ##
27  ##    Revision 1.4  2003/03/28 03:00:12  joko  ##    Revision 1.4  2003/03/28 03:00:12  joko
28  ##    enhanced error- and exception-handling  ##    enhanced error- and exception-handling
29  ##  ##
# Line 109  class DataSource_Proxy_XMLRPC extends Cl Line 119  class DataSource_Proxy_XMLRPC extends Cl
119      //print Dumper($this, $args);      //print Dumper($this, $args);
120      //print Dumper($args);      //print Dumper($args);
121    
122      global $Data_Driver_RPC_Remote_meta;      $this->_wakeup();
     session_register_safe("Data_Driver_RPC_Remote_meta");  
     $this->meta = $Data_Driver_RPC_Remote_meta;  
123    
124      // force connect?      // force connect?
125            
# Line 125  class DataSource_Proxy_XMLRPC extends Cl Line 133  class DataSource_Proxy_XMLRPC extends Cl
133      // V2      // V2
134      $this->FORCE_CONNECT = $args[connect];      $this->FORCE_CONNECT = $args[connect];
135    
     $this->_save_meta();  
136    
137    
138      // merge args - V1      // merge args - V1
# Line 138  class DataSource_Proxy_XMLRPC extends Cl Line 145  class DataSource_Proxy_XMLRPC extends Cl
145      //print Dumper($args);      //print Dumper($args);
146      if (is_array($args)) {      if (is_array($args)) {
147        foreach ($args as $key => $val) {        foreach ($args as $key => $val) {
148            //print "key: $key<br/>";
149          $key = strtoupper($key);          $key = strtoupper($key);
150          $this->$key = $val;          $this->$key = $val;
151        }        }
# Line 158  class DataSource_Proxy_XMLRPC extends Cl Line 166  class DataSource_Proxy_XMLRPC extends Cl
166            
167    }    }
168    
169    function _save_meta() {    function _wakeup() {
170        global $Data_Driver_RPC_Remote_meta;
171        session_register_safe("Data_Driver_RPC_Remote_meta");
172        $this->meta = $Data_Driver_RPC_Remote_meta;
173        $this->_sleep();
174      }
175      
176      function _sleep() {
177      global $Data_Driver_RPC_Remote_meta;      global $Data_Driver_RPC_Remote_meta;
178      $Data_Driver_RPC_Remote_meta = $this->meta;      $Data_Driver_RPC_Remote_meta = $this->meta;
179    }    }
# Line 167  class DataSource_Proxy_XMLRPC extends Cl Line 182  class DataSource_Proxy_XMLRPC extends Cl
182    
183      $this->log(get_class($this) . "->send: " . $command, PEAR_LOG_DEBUG);      $this->log(get_class($this) . "->send: " . $command, PEAR_LOG_DEBUG);
184            
185        /*
186      if (!$this->isConnected()) {      if (!$this->isConnected()) {
187        $this->_raiseException( "->send[ command=$command ]: not connected while trying to send command!");        $this->_raiseException( "->send[ command=$command ]: not connected while trying to send command!");
188        return;        return;
189      }      }
190        */
191            
192      // do 'encode' here and ...      // do 'encode' here and ...
193      if ($options[utf8]) {      if ($options[utf8]) {
# Line 184  class DataSource_Proxy_XMLRPC extends Cl Line 201  class DataSource_Proxy_XMLRPC extends Cl
201    
202    function _call($command, $data = "", $options = array() ) {    function _call($command, $data = "", $options = array() ) {
203    
204      if (!$this->configured) {      $RETRY_COUNT = 0;
205        $this->_raiseException( "->_call: class not configured properly");      $RETRY_MAX = 1;
       return;  
     }  
       
     // populate options list - mostly for debugging purposes  
       $options_list = array();  
       foreach ($options as $key => $value) {  
         array_push($options_list, "$key=$value");  
       }  
206    
207      $data_debug = $data;      do {
     if (is_array($data_debug)) { $data_debug = join(", ", $data_debug); }  
     $options_debug = join(", ", $options_list);  
     $this->log(get_class($this) . "->_call: " . $command . "(" . $data_debug . ") [" . $options_debug . "]", PEAR_LOG_DEBUG);  
   
     // trace  
       //print "call: $command<hr>";  
       //print Dumper($data);  
       //print Dumper($this);  
208    
209      // data        $RETRY_COUNT++;
     $data_enc = XML_RPC_encode($data);  
210    
211      // message - request        $this->__exception_method = '_call';
212      $msg = new XML_RPC_Message($command);    
213      $msg->addParam($data_enc);        if (!$this->configured) {
214            $this->_raiseException("class not configured properly");
215      // ???          return;
216      //print htmlentities($msg->serialize());        }
217          
218      // remote procedure call        // populate options list - mostly for debugging purposes
219      $rpc = new XML_RPC_Client("/", $this->HOST, $this->PORT);          $options_list = array();
220                foreach ($options as $key => $value) {
221      // TODO: detect highlevel errors, raise proper exceptions on them (e.g. 'Unknown method', 'Method signature error(s)')            array_push($options_list, "$key=$value");
222      // done: now possible to declare tracing at this point in configuration          }
223      //    Please look inside your {appname}/etc/hosts/{hostname}.php    
224      $rpc->setDebug($this->TRACE);        $data_debug = $data;
225      //$rpc->setDebug(1);        if (is_array($data_debug)) { $data_debug = join(", ", $data_debug); }
226              $options_debug = join(", ", $options_list);
227      if ( $this->response = $rpc->send($msg) ) {        // FIXME: replace through '_raiseException'?
228        // intermediate result error checking        $this->log(get_class($this) . "->_call: " . $command . "(" . $data_debug . ") [" . $options_debug . "]", PEAR_LOG_DEBUG);
229        $this->_checkException();    
230      } else {        // trace
231        // TODO: redirect this error elsewhere!          //print "call: $command<hr>";
232        //print "RPC-error!<br>";          //print Dumper($data);
233        $this->_raiseException( "->_call: no response");          //print Dumper($this);
234        return;    
235      }        // message - request
236          $msg = new XML_RPC_Message($command);
237      
238          // data
239          if ($data) {
240            $data_enc = XML_RPC_encode($data);
241            $msg->addParam($data_enc);
242          }
243      
244          $this->_hook_request($msg);
245      
246          // ???
247          //print htmlentities($msg->serialize());
248      
249          // remote procedure call
250          $rpc = new XML_RPC_Client("/", $this->HOST, $this->PORT);
251          
252          // TODO: detect highlevel errors, raise proper exceptions on them (e.g. 'Unknown method', 'Method signature error(s)')
253          // done: now possible to declare tracing at this point in configuration
254          //    Please look inside your {appname}/etc/hosts/{hostname}.php
255          $rpc->setDebug($this->TRACE);
256          
257          //$rpc->setDebug(1);
258          
259          if ( $this->response = $rpc->send($msg) ) {
260            // intermediate response checking
261            $errcode = $this->_hook_errorcheck();
262            $negotiation = $this->_hook_negotiation($errcode);
263          } else {
264            // TODO: redirect this error elsewhere!
265            //print "RPC-error!<br>";
266            $this->_raiseException("no response");
267            return;
268          }
269      
270          // retry method issued right now - i.e. in case an authentication came in between
271          if (!$negotiation[retry]) {
272            break;
273          }
274          
275        } while ($RETRY_COUNT < $RETRY_MAX);
276            
277      // message - response      // message - response
278      $response_enc = $this->response->value();      $response_enc = $this->response->value();
279    
280      // TODO: what's this? prematurely returning here should not be considered "stable"....      // TODO: what's this? prematurely returning here should not be considered "stable"....
281      return $this->decodeData($response_enc, $options);      $data = $this->decodeData($response_enc, $options);
282        $this->_hook_response($data);
283        return $data;
284    
285    }    }
286        
# Line 267  class DataSource_Proxy_XMLRPC extends Cl Line 309  class DataSource_Proxy_XMLRPC extends Cl
309        
310    function _be_connected() {    function _be_connected() {
311      $this->meta[connected] = 1;      $this->meta[connected] = 1;
312      $this->_save_meta();      $this->_sleep();
313    }    }
314        
315    function _raiseException($message, $code = null) {    function _raiseException($message, $code = null) {
316            
317        $classname = get_class($this);
318        
319        if ($this->__exception_method) {
320          $message_full = $classname . '->' . $this->__exception_method . ': ' . $message;
321        }
322        
323      // aggregate errors for this run/query      // aggregate errors for this run/query
324      $this->_add_error($message, $code);      $this->_add_error($message, $code);
325            
326      // spout out the error message of the raised exception      // spout out the error message of the raised exception
327      $this->log(get_class($this) . $message, PEAR_LOG_ERR);      $this->log($classname . $message_full, PEAR_LOG_ERR);
328    
329      // handle some stuff regarding more special behaviour (will this get rule-based sometimes?)      // handle some stuff regarding more special behaviour (will this get rule-based sometimes?)
330            
# Line 284  class DataSource_Proxy_XMLRPC extends Cl Line 332  class DataSource_Proxy_XMLRPC extends Cl
332      $connect_condition = $this->FORCE_CONNECT = ($this->isConnected() && $this->DISCONNECT_ON_ERROR);      $connect_condition = $this->FORCE_CONNECT = ($this->isConnected() && $this->DISCONNECT_ON_ERROR);
333      if ($connect_condition) {      if ($connect_condition) {
334        $message = '->_raiseException: [DISCONNECT_ON_ERROR] done transparently. Please reconnect manually.';        $message = '->_raiseException: [DISCONNECT_ON_ERROR] done transparently. Please reconnect manually.';
335        $this->_add_error($message, $code);        $this->_add_error($classname . $message, $code);
336        //$this->log(get_class($this) . $message, PEAR_LOG_WARNING);        //$this->log($classname . $message, PEAR_LOG_WARNING);
337        $this->log(get_class($this) . $message, PEAR_LOG_ERR);        $this->log($classname . $message, PEAR_LOG_ERR);
338        $this->meta[connected] = 0;        $this->meta[connected] = 0;
339        $this->_save_meta();        $this->_sleep();
340      }      }
341    }    }
342        
# Line 299  class DataSource_Proxy_XMLRPC extends Cl Line 347  class DataSource_Proxy_XMLRPC extends Cl
347    function ping() {    function ping() {
348      $this->_call('ping');      $this->_call('ping');
349    }    }
     
350    
351    function _checkException() {  
352      function _hook_negotiation($error_code) {
353        
354        $result = array();
355        
356        // 401 = authorization required
357        if ($error_code == 401) {
358    
359          //print "<b>401</b>!!!<br/>";
360          //print Dumper($this);
361    
362          // V1 - authenticate using hardcoded plaintext values (bad thing inside here!!!)
363          $auth_ok = $this->_call('authenticate', array( user => 'hello', pass => '123' ));
364          //$auth_ok = $this->_call('authenticate', array( user => 'hello', pass => '12345' ));
365    
366          // authentication success? try issued method again now...
367          if ($auth_ok) {
368            $result[retry] = 1;
369          }
370    
371          // V2 - sub-negotiation:
372          // "Do we already have a password supplied in cache?"
373          // Use it if we have, otherwise redirect to login page
374          // prompting for credentials for specified transport.
375          //Header("Location: " . topicLink('Login'));
376          //print "user: " . $this->USER . "<br/>";
377          //print "pass: " . $this->PASS . "<br/>";
378    
379        }
380    
381        // 511 = sent unknown session identifier (probably: session timed out)
382        // solution: invalidate local session in state => new session will be attempted on next request
383        if ($error_code == 511) {
384          $this->meta[session][enabled] = 0;
385          $this->_sleep();
386        }
387        
388        return $result;
389    
390      }
391    
392      function _hook_errorcheck() {
393      //    Please look inside your {appname}/etc/hosts/{hostname}.php for toggling $this->DEBUG      //    Please look inside your {appname}/etc/hosts/{hostname}.php for toggling $this->DEBUG
394      if ($error_code = $this->response->faultCode()) {      if ($error_code = $this->response->faultCode()) {
395        //print $msg_response->faultString();        // raise exception
396        $this->_raiseException( "->_call: " . $this->response->faultString(), $error_code );        //print "fault-code: " . $this->response->faultCode() . "<br/>";
397          //print "fault-string: " . $this->response->faultString() . "<br/>";
398          $this->_raiseException($this->response->faultString(), $error_code);
399          return $error_code;
400      }      }
401    }    }
402    
403      //if ($this->DEBUG && $error_code = $msg_response->faultCode()) {    //if ($this->DEBUG && $error_code = $msg_response->faultCode()) {
   
404    
405    function _add_error($message, $code) {    function _add_error($message, $code) {
406      array_push( $this->errors, array(code => $code, message => $message) );      array_push( $this->errors, array(code => $code, message => $message) );
407    }    }
408        
409    function getStatus() {    function status() {
410      return array( connected => $this->isConnected(), errors => $this->errors );      $status = array(
411          connected => $this->isConnected(),
412          errors => $this->errors,
413        );
414        $status[RPCSESSID] = $this->meta[session][id];
415        return $status;
416    }    }
417    
418        
419      // TODO: introduce condition: just do if connection requires session and/or auth
420      function _hook_request(&$request) {
421        
422        //print Dumper($request);
423        
424        // ignore core methods (like 'session_id') here to prevent recursive loops!
425        // would be a bad thing on the net!
426        if (in_array($request->methodname, array('ping', 'session_id')))  { return 1; }
427        
428        // calculate conditions
429        $session_requested = 1;
430        //$use_session = $this->meta[session][requested];
431        $session_running = $this->meta[session][enabled];
432        $session_error = $this->meta[session][error];
433        $init_session = $session_requested && !$session_running && !$session_error;
434        
435        // 1. if session already established, add sessionid to request and return
436        if ($session_running) {
437          //trace("Session " . $this->meta[session][id] . " already initialized!" . "<br/>");
438          // append additional parameter (hash with key 'RPCSESSID')
439          // to send assigned sessionid back to server inside each request
440          $data = array( RPCSESSID => $this->meta[session][id] );
441          $data_enc = XML_RPC_encode($data);
442          //print Dumper($data_enc);
443          $request->addParam($data_enc);
444          //return 1;
445        }
446    
447    
448        // 2. if session is required/requested, but not yet initialized,
449        // do it to be able to propagate the sessionid transparently later
450    
451        if ($init_session) {
452          static $init_count;
453          $init_count++;
454          //trace("Initializing session: $init_count" . "<br/>");
455          //exit;
456          $response = $this->_call('session_id');
457          //print "response: " . Dumper($response) . "<br/>";
458          //exit;
459          
460          if ($response) {
461            $this->meta[session][id] = $response;
462            $this->meta[session][enabled] = 1;
463          } else {
464            $this->meta[session][error] = 1;
465          }
466          
467          $this->_sleep();
468          //print Dumper($this->meta);
469          //exit;
470        }
471    
472        //print Dumper($request);
473    
474        return 1;
475      }
476    
477      function _hook_response(&$data) {
478        //$status[RPCSESSID] = $this->meta[session][RPCSESSID];
479      }
480    
481  }  }
482    
483  ?>  ?>

Legend:
Removed from v.1.4  
changed lines
  Added in v.1.7

MailToCvsAdmin">MailToCvsAdmin
ViewVC Help
Powered by ViewVC 1.1.26 RSS 2.0 feed