コード例 #1
0
ファイル: JsonRpcTest.php プロジェクト: psagi/sdo
 /**
  * make it look to the component as if it is receiving  
  * a request for a method invocation and check the response 
  * is correct
  */
 public function testWrapperAndProxy()
 {
     $_SERVER['HTTP_HOST'] = 'localhost';
     $_SERVER['REQUEST_METHOD'] = 'POST';
     $_SERVER['SCRIPT_FILENAME'] = 'TestService.php';
     $_SERVER['REQUEST_URI'] = 'http://localhost/TestService.php';
     $_SERVER['CONTENT_TYPE'] = 'application/json-rpc';
     SCA_JsonRpcServer::$test_request = $this->request;
     SCA_JsonRpcClient::$store_test_request = true;
     SCA_JsonRpcClient::$test_response = $this->email_response;
     ob_start();
     SCA::initComponent("TestService.php");
     $out = ob_get_contents();
     ob_end_clean();
     $this->assertContains($this->response, $out);
     $this->assertContains(SCA_JsonRpcClient::$test_request, $this->email_request);
 }
コード例 #2
0
ファイル: SCA_JsonRpcClient.php プロジェクト: psagi/sdo
 /**
  * Call the remote JSON service method using CURL to
  * send the HTTP request
  *
  * @param string $method_name Method name
  * @param array  $arguments   Arguments
  *
  * @return mixed
  */
 public function __call($method_name, $arguments)
 {
     // check that the requested method exists
     $method = null;
     foreach ($this->methods as $methods_entry) {
         if ($methods_entry->name == $method_name) {
             $method = $methods_entry;
         }
     }
     if ($method == null) {
         throw new SCA_RuntimeException("Trying to call {$method_name} on remote service " . "using JSONRPC and the method cannot be found. " . "The remote service has the following interface " . $this->smd_file);
     }
     // collect useful information about the method
     $return_type = $method->return->type;
     // construct the JSON request
     $json_request = "{\"id\":" . $this->id . ",";
     // increment the id so we get a unique id for calls from this client
     // its done up here so that we don't resuse IDs in this session
     // regardless of what happens to the call
     // TODO - is this sufficient?
     $this->id = $this->id + 1;
     $json_request = $json_request . "\"method\":\"{$method_name}\",";
     $json_request = $json_request . "\"params\":[";
     // convert all the arguments into JSON strings
     $argument_id = 0;
     foreach ($arguments as $argument) {
         if ($argument == null) {
             $json_request = $json_request;
         } else {
             if (is_object($argument)) {
                 $json_request = $json_request . $this->json_das->encode($argument);
             } else {
                 if (is_array($argument)) {
                     throw new SCA_RuntimeException("Argument {$argument_id} to {$method_name} of type array found. " . "Arguments must be either primitives or SDOs");
                 } else {
                     $json_request = $json_request . json_encode($argument);
                 }
             }
         }
         $argument_id += 1;
         if ($argument_id < count($arguments)) {
             $json_request = $json_request . ",";
         }
     }
     $json_request = $json_request . "],\"version\":\"1.0\"}";
     // some debugging
     //            file_put_contents("json_messages.txt",
     //            "Request at JSONRPC client = " . $json_request . "\n",
     //            FILE_APPEND);
     if (self::$store_test_request == false) {
         // send this string to the service url
         $request = curl_init($this->service_url);
         curl_setopt($request, CURLOPT_POST, true);
         curl_setopt($request, CURLOPT_POSTFIELDS, $json_request);
         curl_setopt($request, CURLOPT_HEADER, false);
         curl_setopt($request, CURLOPT_RETURNTRANSFER, true);
         $header = array("User-Agent: SCA", "Content-Type: application/json-rpc", "Accept: application/json-rpc");
         curl_setopt($request, CURLOPT_HTTPHEADER, $header);
         // Do the POST
         $response = curl_exec($request);
         // TODO probably need a better way of detecting PHP errors at the far end
         if (strchr($response, '<b>Fatal error</b>') !== false || strchr($response, '<b>Parse error</b>') !== false) {
             throw new SCA_RuntimeException('Bad response from jsonrpc call: ' . $response);
         }
         // Get info about the response
         $response_http_code = curl_getinfo($request, CURLINFO_HTTP_CODE);
         // close the session
         curl_close($request);
         // some debugging
         //            file_put_contents("json_messages.txt",
         //            "Response at JSONRPC client = " . $response . "\n",
         //            FILE_APPEND);
         // test the response status
         if ($response == null || $response == false) {
             throw new SCA_RuntimeException("JSONRPC call to {$this->service_url} for method " . "{$method_name} failed ");
         }
         // test the response status
         if ($response_http_code != 200) {
             throw new SCA_RuntimeException("JSONRPC call to {$this->service_url} for method " . "{$method_name} failed with HTTP response code " . $response_http_code);
         }
     } else {
         self::$test_request = $json_request;
         $response = self::$test_response;
     }
     // decode the response
     $json_response = json_decode($response);
     $id = $json_response->id;
     // test to make sure that the id on the response matches
     // the id on the request
     if ($id != $this->id - 1) {
         throw new SCA_RuntimeException("JSONRPC call to {$this->service_url} for method " . "{$method_name} failed as the id of the response {$id} " . "does not match id of the request " . ($this->id - 1));
     }
     // test to see if there is an error in the response message
     if (isset($json_response->error)) {
         $error = $json_response->error;
         if ($error != null) {
             throw new SCA_RuntimeException("JSONRPC call to {$this->service_url} for method " . "{$method_name} failed. The JSON error field contained " . '"' . $error . '"');
         }
     } else {
         // decode the response based on its type.
         $result = $json_response->result;
         $return_object = null;
         if (is_object($result)) {
             // decode the complex object into an SDO. The return type
             // has come from  the SMD. If XSD files
             // have also been specified then we guess the namespace
             // of the return type based on the matching the return
             // type name from the SMD with the type names from the
             // XSD
             $return_namespace = $this->_guessReturnTypeNamespace($return_type);
             $return_object = $this->json_das->decodeFromPHPObject($result, $return_type, $return_namespace);
         } else {
             if (is_array($result)) {
                 throw new SCA_RuntimeException("JSONRPC call to {$this->service_url} for method " . "{$method_name} failed. Result of type array found. " . "Return types must be either primitives or SDOs");
             } else {
                 // do nothing in this case. The json_decode method
                 // call has done all the work for us for primitive
                 // types and null
                 $return_object = $result;
             }
         }
     }
     return $return_object;
 }