PageRenderTime 41ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/libraries/openid/Auth/Yadis/PlainHTTPFetcher.php

https://github.com/Shigaru/shigaru
PHP | 254 lines | 160 code | 56 blank | 38 comment | 34 complexity | 7771a1799a783e9bc9347493659e745e MD5 | raw file
  1. <?php
  2. /**
  3. * This module contains the plain non-curl HTTP fetcher
  4. * implementation.
  5. *
  6. * PHP versions 4 and 5
  7. *
  8. * LICENSE: See the COPYING file included in this distribution.
  9. *
  10. * @package OpenID
  11. * @author JanRain, Inc. <openid@janrain.com>
  12. * @copyright 2005-2008 Janrain, Inc.
  13. * @license http://www.apache.org/licenses/LICENSE-2.0 Apache
  14. */
  15. // Do not allow direct access
  16. defined( '_JEXEC' ) or die( 'Restricted access' );
  17. /**
  18. * Interface import
  19. */
  20. require_once "Auth/Yadis/HTTPFetcher.php";
  21. /**
  22. * This class implements a plain, hand-built socket-based fetcher
  23. * which will be used in the event that CURL is unavailable.
  24. *
  25. * @package OpenID
  26. */
  27. class Auth_Yadis_PlainHTTPFetcher extends Auth_Yadis_HTTPFetcher {
  28. /**
  29. * Does this fetcher support SSL URLs?
  30. */
  31. function supportsSSL()
  32. {
  33. return function_exists('openssl_open');
  34. }
  35. function get($url, $extra_headers = null)
  36. {
  37. if (!$this->canFetchURL($url)) {
  38. return null;
  39. }
  40. $redir = true;
  41. $stop = time() + $this->timeout;
  42. $off = $this->timeout;
  43. while ($redir && ($off > 0)) {
  44. $parts = parse_url($url);
  45. $specify_port = true;
  46. // Set a default port.
  47. if (!array_key_exists('port', $parts)) {
  48. $specify_port = false;
  49. if ($parts['scheme'] == 'http') {
  50. $parts['port'] = 80;
  51. } elseif ($parts['scheme'] == 'https') {
  52. $parts['port'] = 443;
  53. } else {
  54. return null;
  55. }
  56. }
  57. if (!array_key_exists('path', $parts)) {
  58. $parts['path'] = '/';
  59. }
  60. $host = $parts['host'];
  61. if ($parts['scheme'] == 'https') {
  62. $host = 'ssl://' . $host;
  63. }
  64. $user_agent = Auth_OpenID_USER_AGENT;
  65. $headers = array(
  66. "GET ".$parts['path'].
  67. (array_key_exists('query', $parts) ?
  68. "?".$parts['query'] : "").
  69. " HTTP/1.0",
  70. "User-Agent: $user_agent",
  71. "Host: ".$parts['host'].
  72. ($specify_port ? ":".$parts['port'] : ""),
  73. "Range: 0-".
  74. (1024*Auth_OpenID_FETCHER_MAX_RESPONSE_KB),
  75. "Port: ".$parts['port']);
  76. $errno = 0;
  77. $errstr = '';
  78. if ($extra_headers) {
  79. foreach ($extra_headers as $h) {
  80. $headers[] = $h;
  81. }
  82. }
  83. @$sock = fsockopen($host, $parts['port'], $errno, $errstr,
  84. $this->timeout);
  85. if ($sock === false) {
  86. return false;
  87. }
  88. stream_set_timeout($sock, $this->timeout);
  89. fputs($sock, implode("\r\n", $headers) . "\r\n\r\n");
  90. $data = "";
  91. $kilobytes = 0;
  92. while (!feof($sock) &&
  93. $kilobytes < Auth_OpenID_FETCHER_MAX_RESPONSE_KB ) {
  94. $data .= fgets($sock, 1024);
  95. $kilobytes += 1;
  96. }
  97. fclose($sock);
  98. // Split response into header and body sections
  99. list($headers, $body) = explode("\r\n\r\n", $data, 2);
  100. $headers = explode("\r\n", $headers);
  101. $http_code = explode(" ", $headers[0]);
  102. $code = $http_code[1];
  103. if (in_array($code, array('301', '302'))) {
  104. $url = $this->_findRedirect($headers);
  105. $redir = true;
  106. } else {
  107. $redir = false;
  108. }
  109. $off = $stop - time();
  110. }
  111. $new_headers = array();
  112. foreach ($headers as $header) {
  113. if (preg_match("/:/", $header)) {
  114. $parts = explode(": ", $header, 2);
  115. if (count($parts) == 2) {
  116. list($name, $value) = $parts;
  117. $new_headers[$name] = $value;
  118. }
  119. }
  120. }
  121. return new Auth_Yadis_HTTPResponse($url, $code, $new_headers, $body);
  122. }
  123. function post($url, $body, $extra_headers = null)
  124. {
  125. if (!$this->canFetchURL($url)) {
  126. return null;
  127. }
  128. $parts = parse_url($url);
  129. $headers = array();
  130. $post_path = $parts['path'];
  131. if (isset($parts['query'])) {
  132. $post_path .= '?' . $parts['query'];
  133. }
  134. $headers[] = "POST ".$post_path." HTTP/1.0";
  135. $headers[] = "Host: " . $parts['host'];
  136. $headers[] = "Content-type: application/x-www-form-urlencoded";
  137. $headers[] = "Content-length: " . strval(strlen($body));
  138. if ($extra_headers &&
  139. is_array($extra_headers)) {
  140. $headers = array_merge($headers, $extra_headers);
  141. }
  142. // Join all headers together.
  143. $all_headers = implode("\r\n", $headers);
  144. // Add headers, two newlines, and request body.
  145. $request = $all_headers . "\r\n\r\n" . $body;
  146. // Set a default port.
  147. if (!array_key_exists('port', $parts)) {
  148. if ($parts['scheme'] == 'http') {
  149. $parts['port'] = 80;
  150. } elseif ($parts['scheme'] == 'https') {
  151. $parts['port'] = 443;
  152. } else {
  153. return null;
  154. }
  155. }
  156. if ($parts['scheme'] == 'https') {
  157. $parts['host'] = sprintf("ssl://%s", $parts['host']);
  158. }
  159. // Connect to the remote server.
  160. $errno = 0;
  161. $errstr = '';
  162. $sock = fsockopen($parts['host'], $parts['port'], $errno, $errstr,
  163. $this->timeout);
  164. if ($sock === false) {
  165. return null;
  166. }
  167. stream_set_timeout($sock, $this->timeout);
  168. // Write the POST request.
  169. fputs($sock, $request);
  170. // Get the response from the server.
  171. $response = "";
  172. while (!feof($sock)) {
  173. if ($data = fgets($sock, 128)) {
  174. $response .= $data;
  175. } else {
  176. break;
  177. }
  178. }
  179. // Split the request into headers and body.
  180. list($headers, $response_body) = explode("\r\n\r\n", $response, 2);
  181. $headers = explode("\r\n", $headers);
  182. // Expect the first line of the headers data to be something
  183. // like HTTP/1.1 200 OK. Split the line on spaces and take
  184. // the second token, which should be the return code.
  185. $http_code = explode(" ", $headers[0]);
  186. $code = $http_code[1];
  187. $new_headers = array();
  188. foreach ($headers as $header) {
  189. if (preg_match("/:/", $header)) {
  190. list($name, $value) = explode(": ", $header, 2);
  191. $new_headers[$name] = $value;
  192. }
  193. }
  194. return new Auth_Yadis_HTTPResponse($url, $code,
  195. $new_headers, $response_body);
  196. }
  197. }
  198. ?>