HTTPClient.php
1 <?php
2 /**
3  * wCMF - wemove Content Management Framework
4  * Copyright (C) 2005-2015 wemove digital solutions GmbH
5  *
6  * Licensed under the terms of the MIT License.
7  *
8  * See the LICENSE file distributed with this work for
9  * additional information.
10  */
11 namespace wcmf\lib\service\impl;
12 
19 
20 if (!class_exists('Zend_Http_Client')) {
21  throw new ConfigurationException(
22  'wcmf\lib\service\impl\HTTPClient requires '.
23  'Zend_Http_Client. If you are using composer, add zf1/zend-http '.
24  'as dependency to your project');
25 }
26 
27 /**
28  * HTTPClient is used to do calls to other wCMF instances over HTTP.
29  * @see RemotingServer
30  *
31  * @note This class requires Zend_Http_Client
32  *
33  * @author ingo herwig <ingo@wemove.com>
34  */
35 class HTTPClient implements RemotingClient {
36 
37  private static $_logger = null;
38 
39  private $_client = null;
40  private $_user = null;
41 
42  /**
43  * Constructor
44  * @param $serverUrl The url of the other server instance.
45  * @param $user The remote user instance.
46  */
47  public function __construct($serverUrl, $user) {
48  if (self::$_logger == null) {
49  self::$_logger = LogManager::getLogger(__CLASS__);
50  }
51  $this->_client = new Zend_Http_Client($serverUrl, array(
52  'keepalive' => true,
53  'timeout' => 3600
54  )
55  );
56  $this->_client->setMethod(Zend_Http_Client::POST);
57  $this->_client->setCookieJar();
58  $this->_user = $user;
59  }
60 
61  /**
62  * Do a call to the remote server.
63  * @param $request A Request instance
64  * @return A Response instance
65  */
66  public function call(Request $request) {
67  $response = $this->doRemoteCall($request, false);
68  return $response;
69  }
70 
71  /**
72  * Do a remote call.
73  * @param $request The Request instance
74  * @param $isLogin Boolean whether this request is a login request or not
75  * @return The Response instance
76  */
77  protected function doRemoteCall(Request $request, $isLogin) {
78  // initially login, if no cookie is set
79  $cookyJar = $this->_client->getCookieJar();
80  if (!$isLogin && sizeof($cookyJar->getAllCookies()) == 0) {
81  $response = $this->doLogin();
82  }
83 
84  // do the request
85  $request->setResponseFormat('json');
86  $this->_client->resetParameters();
87  $this->_client->setParameterPost('controller', $request->getSender());
88  $this->_client->setParameterPost('context', $request->getContext());
89  $this->_client->setParameterPost('action', $request->getAction());
90  $this->_client->setParameterPost('request_format', $request->getFormat());
91  $this->_client->setParameterPost('response_format', $request->getResponseFormat());
92  $this->_client->setParameterPost($request->getValues());
93  try {
94  $httpResponse = $this->_client->request();
95  }
96  catch (\Exception $ex) {
97  self::$_logger->error("Error in remote call to ".$url.":\n".$ex, __FILE__);
98  throw new \RuntimeException("Error in remote call to ".$url.": ".$ex->getMessage());
99  }
100 
101  // deserialize the response
102  $responseData = json_decode($httpResponse->getBody(), true);
103  $response = new ControllerMessage('', '', '', $responseData);
104  $response->setFormat('json');
105  $formatter = ObjectFactory::getInstance('formatter');
106  $formatter->deserialize($response);
107 
108  // handle errors
109  if (!$response->getValue('success'))
110  {
111  $errorMsg = $response->getValue('errorMsg');
112  // if the session expired, try to relogin
113  if (strpos('Authorization failed', $errorMsg) === 0 && !$isLogin) {
114  $this->doLogin();
115  }
116  $url = $this->_client->getUri();
117  self::$_logger->error("Error in remote call to ".$url.": ".$errorMsg."\n".$response->toString(), __FILE__);
118  throw new \RuntimeException("Error in remote call: $errorMsg");
119  }
120  return $response;
121  }
122 
123  /**
124  * Do the login request. If the request is successful,
125  * the session id will be set.
126  * @return True on success
127  */
128  protected function doLogin() {
129  if ($this->_user) {
130  $request = ObjectFactory::getInstance('request');
131  $request->setAction('login');
132  $request->setValues(
133  array(
134  'login' => $this->_user['login'],
135  'password' => $this->_user['password']
136  )
137  );
138  $response = $this->doRemoteCall($request, true);
139  if ($response->getValue('success')) {
140  $this->_sessionId = $response->getValue('sid');
141  return true;
142  }
143  }
144  else {
145  throw new \RuntimeException("Remote user required for remote call.");
146  }
147  }
148 
149  /**
150  * Error handling method
151  * @param $response The Response instance
152  */
153  protected function handleError($response) {
154  $errorMsg = $response->getValue('errorMsg');
155  self::$_logger->error("Error in remote call to ".$this->_serverBase.": ".$errorMsg."\n".$response->toString(), __FILE__);
156  throw new \RuntimeException("Error in remote call to ".$this->_serverBase.": ".$errorMsg);
157  }
158 }
159 ?>
getFormat()
Get the message format.
getContext()
Get the name of the context.
static getLogger($name)
Get the logger with the given name.
Definition: LogManager.php:35
setResponseFormat($format)
Set the desired response format.
Messages are sent between Controllers and are used to transfer data between them. ...
static getInstance($name, $dynamicConfiguration=array())
getResponseFormat()
Get the message response format.
getAction()
Get the name of the action.
Request holds the request values that are used as input to Controller instances.
Definition: Request.php:20
RemotingClient defines the interface for clients to be used with RemotingServer.
getSender()
Get the name of the sending Controller.
call(Request $request)
Do a call to the remote server.
Definition: HTTPClient.php:66
__construct($serverUrl, $user)
Constructor.
Definition: HTTPClient.php:47
HTTPClient is used to do calls to other wCMF instances over HTTP.
Definition: HTTPClient.php:35
doRemoteCall(Request $request, $isLogin)
Do a remote call.
Definition: HTTPClient.php:77
getValues()
Get all key value pairs.
doLogin()
Do the login request.
Definition: HTTPClient.php:128
handleError($response)
Error handling method.
Definition: HTTPClient.php:153