/Services/CAS/lib/CAS/Request/AbstractRequest.php

https://github.com/ILIAS-eLearning/ILIAS · PHP · 378 lines · 171 code · 33 blank · 174 comment · 17 complexity · 4c649e8f58f6cb616291960bd2c314db MD5 · raw file

  1. <?php
  2. /**
  3. * Licensed to Jasig under one or more contributor license
  4. * agreements. See the NOTICE file distributed with this work for
  5. * additional information regarding copyright ownership.
  6. *
  7. * Jasig licenses this file to you under the Apache License,
  8. * Version 2.0 (the "License"); you may not use this file except in
  9. * compliance with the License. You may obtain a copy of the License at:
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. *
  19. * PHP Version 5
  20. *
  21. * @file CAS/Request/AbstractRequest.php
  22. * @category Authentication
  23. * @package PhpCAS
  24. * @author Adam Franco <afranco@middlebury.edu>
  25. * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
  26. * @link https://wiki.jasig.org/display/CASC/phpCAS
  27. */
  28. /**
  29. * Provides support for performing web-requests via curl
  30. *
  31. * @class CAS_Request_AbstractRequest
  32. * @category Authentication
  33. * @package PhpCAS
  34. * @author Adam Franco <afranco@middlebury.edu>
  35. * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
  36. * @link https://wiki.jasig.org/display/CASC/phpCAS
  37. */
  38. abstract class CAS_Request_AbstractRequest implements CAS_Request_RequestInterface
  39. {
  40. protected $url = null;
  41. protected $cookies = array();
  42. protected $headers = array();
  43. protected $isPost = false;
  44. protected $postBody = null;
  45. protected $caCertPath = null;
  46. protected $validateCN = true;
  47. private $_sent = false;
  48. private $_responseHeaders = array();
  49. private $_responseBody = null;
  50. private $_errorMessage = '';
  51. /*********************************************************
  52. * Configure the Request
  53. *********************************************************/
  54. /**
  55. * Set the URL of the Request
  56. *
  57. * @param string $url Url to set
  58. *
  59. * @return void
  60. * @throws CAS_OutOfSequenceException If called after the Request has been sent.
  61. */
  62. public function setUrl($url)
  63. {
  64. if ($this->_sent) {
  65. throw new CAS_OutOfSequenceException(
  66. 'Request has already been sent cannot ' . __METHOD__
  67. );
  68. }
  69. $this->url = $url;
  70. }
  71. /**
  72. * Add a cookie to the request.
  73. *
  74. * @param string $name Name of entry
  75. * @param string $value value of entry
  76. *
  77. * @return void
  78. * @throws CAS_OutOfSequenceException If called after the Request has been sent.
  79. */
  80. public function addCookie($name, $value)
  81. {
  82. if ($this->_sent) {
  83. throw new CAS_OutOfSequenceException(
  84. 'Request has already been sent cannot ' . __METHOD__
  85. );
  86. }
  87. $this->cookies[$name] = $value;
  88. }
  89. /**
  90. * Add an array of cookies to the request.
  91. * The cookie array is of the form
  92. * array('cookie_name' => 'cookie_value', 'cookie_name2' => cookie_value2')
  93. *
  94. * @param array $cookies cookies to add
  95. *
  96. * @return void
  97. * @throws CAS_OutOfSequenceException If called after the Request has been sent.
  98. */
  99. public function addCookies(array $cookies)
  100. {
  101. if ($this->_sent) {
  102. throw new CAS_OutOfSequenceException(
  103. 'Request has already been sent cannot ' . __METHOD__
  104. );
  105. }
  106. $this->cookies = array_merge($this->cookies, $cookies);
  107. }
  108. /**
  109. * Add a header string to the request.
  110. *
  111. * @param string $header Header to add
  112. *
  113. * @return void
  114. * @throws CAS_OutOfSequenceException If called after the Request has been sent.
  115. */
  116. public function addHeader($header)
  117. {
  118. if ($this->_sent) {
  119. throw new CAS_OutOfSequenceException(
  120. 'Request has already been sent cannot ' . __METHOD__
  121. );
  122. }
  123. $this->headers[] = $header;
  124. }
  125. /**
  126. * Add an array of header strings to the request.
  127. *
  128. * @param array $headers headers to add
  129. *
  130. * @return void
  131. * @throws CAS_OutOfSequenceException If called after the Request has been sent.
  132. */
  133. public function addHeaders(array $headers)
  134. {
  135. if ($this->_sent) {
  136. throw new CAS_OutOfSequenceException(
  137. 'Request has already been sent cannot ' . __METHOD__
  138. );
  139. }
  140. $this->headers = array_merge($this->headers, $headers);
  141. }
  142. /**
  143. * Make the request a POST request rather than the default GET request.
  144. *
  145. * @return void
  146. * @throws CAS_OutOfSequenceException If called after the Request has been sent.
  147. */
  148. public function makePost()
  149. {
  150. if ($this->_sent) {
  151. throw new CAS_OutOfSequenceException(
  152. 'Request has already been sent cannot ' . __METHOD__
  153. );
  154. }
  155. $this->isPost = true;
  156. }
  157. /**
  158. * Add a POST body to the request
  159. *
  160. * @param string $body body to add
  161. *
  162. * @return void
  163. * @throws CAS_OutOfSequenceException If called after the Request has been sent.
  164. */
  165. public function setPostBody($body)
  166. {
  167. if ($this->_sent) {
  168. throw new CAS_OutOfSequenceException(
  169. 'Request has already been sent cannot ' . __METHOD__
  170. );
  171. }
  172. if (!$this->isPost) {
  173. throw new CAS_OutOfSequenceException(
  174. 'Cannot add a POST body to a GET request, use makePost() first.'
  175. );
  176. }
  177. $this->postBody = $body;
  178. }
  179. /**
  180. * Specify the path to an SSL CA certificate to validate the server with.
  181. *
  182. * @param string $caCertPath path to cert
  183. * @param bool $validate_cn valdiate CN of certificate
  184. *
  185. * @return void
  186. * @throws CAS_OutOfSequenceException If called after the Request has been sent.
  187. */
  188. public function setSslCaCert($caCertPath, $validate_cn = true)
  189. {
  190. if ($this->_sent) {
  191. throw new CAS_OutOfSequenceException(
  192. 'Request has already been sent cannot ' . __METHOD__
  193. );
  194. }
  195. $this->caCertPath = $caCertPath;
  196. $this->validateCN = $validate_cn;
  197. }
  198. /*********************************************************
  199. * 2. Send the Request
  200. *********************************************************/
  201. /**
  202. * Perform the request.
  203. *
  204. * @return bool TRUE on success, FALSE on failure.
  205. * @throws CAS_OutOfSequenceException If called multiple times.
  206. */
  207. public function send()
  208. {
  209. if ($this->_sent) {
  210. throw new CAS_OutOfSequenceException(
  211. 'Request has already been sent cannot send again.'
  212. );
  213. }
  214. if (is_null($this->url) || !$this->url) {
  215. throw new CAS_OutOfSequenceException(
  216. 'A url must be specified via setUrl() before the request can be sent.'
  217. );
  218. }
  219. $this->_sent = true;
  220. return $this->sendRequest();
  221. }
  222. /**
  223. * Send the request and store the results.
  224. *
  225. * @return bool TRUE on success, FALSE on failure.
  226. */
  227. abstract protected function sendRequest();
  228. /**
  229. * Store the response headers.
  230. *
  231. * @param array $headers headers to store
  232. *
  233. * @return void
  234. */
  235. protected function storeResponseHeaders(array $headers)
  236. {
  237. $this->_responseHeaders = array_merge($this->_responseHeaders, $headers);
  238. }
  239. /**
  240. * Store a single response header to our array.
  241. *
  242. * @param string $header header to store
  243. *
  244. * @return void
  245. */
  246. protected function storeResponseHeader($header)
  247. {
  248. $this->_responseHeaders[] = $header;
  249. }
  250. /**
  251. * Store the response body.
  252. *
  253. * @param string $body body to store
  254. *
  255. * @return void
  256. */
  257. protected function storeResponseBody($body)
  258. {
  259. $this->_responseBody = $body;
  260. }
  261. /**
  262. * Add a string to our error message.
  263. *
  264. * @param string $message message to add
  265. *
  266. * @return void
  267. */
  268. protected function storeErrorMessage($message)
  269. {
  270. $this->_errorMessage .= $message;
  271. }
  272. /*********************************************************
  273. * 3. Access the response
  274. *********************************************************/
  275. /**
  276. * Answer the headers of the response.
  277. *
  278. * @return array An array of header strings.
  279. * @throws CAS_OutOfSequenceException If called before the Request has been sent.
  280. */
  281. public function getResponseHeaders()
  282. {
  283. if (!$this->_sent) {
  284. throw new CAS_OutOfSequenceException(
  285. 'Request has not been sent yet. Cannot ' . __METHOD__
  286. );
  287. }
  288. return $this->_responseHeaders;
  289. }
  290. /**
  291. * Answer HTTP status code of the response
  292. *
  293. * @return int
  294. * @throws CAS_OutOfSequenceException If called before the Request has been sent.
  295. */
  296. public function getResponseStatusCode()
  297. {
  298. if (!$this->_sent) {
  299. throw new CAS_OutOfSequenceException(
  300. 'Request has not been sent yet. Cannot ' . __METHOD__
  301. );
  302. }
  303. if (!preg_match(
  304. '/HTTP\/[0-9.]+\s+([0-9]+)\s*(.*)/',
  305. $this->_responseHeaders[0],
  306. $matches
  307. )
  308. ) {
  309. throw new CAS_Request_Exception(
  310. 'Bad response, no status code was found in the first line.'
  311. );
  312. }
  313. return intval($matches[1]);
  314. }
  315. /**
  316. * Answer the body of response.
  317. *
  318. * @return string
  319. * @throws CAS_OutOfSequenceException If called before the Request has been sent.
  320. */
  321. public function getResponseBody()
  322. {
  323. if (!$this->_sent) {
  324. throw new CAS_OutOfSequenceException(
  325. 'Request has not been sent yet. Cannot ' . __METHOD__
  326. );
  327. }
  328. return $this->_responseBody;
  329. }
  330. /**
  331. * Answer a message describing any errors if the request failed.
  332. *
  333. * @return string
  334. * @throws CAS_OutOfSequenceException If called before the Request has been sent.
  335. */
  336. public function getErrorMessage()
  337. {
  338. if (!$this->_sent) {
  339. throw new CAS_OutOfSequenceException(
  340. 'Request has not been sent yet. Cannot ' . __METHOD__
  341. );
  342. }
  343. return $this->_errorMessage;
  344. }
  345. }