PageRenderTime 45ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/3.0/obsolete/web_client/application/libraries/G3Remote.php

http://github.com/gallery/gallery3-contrib
PHP | 298 lines | 202 code | 37 blank | 59 comment | 33 complexity | 2e9fa1cf0f7a792f8bbb81d4e3f6f4d6 MD5 | raw file
Possible License(s): GPL-3.0, GPL-2.0, LGPL-2.1
  1. <?php defined('SYSPATH') OR die('No direct access allowed.');
  2. /**
  3. * Gallery - a web based photo album viewer and editor
  4. * Copyright (C) 2000-2013 Bharat Mediratta
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or (at
  9. * your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. // This class does not depend on any Kohana services so that it can be used in non-Kohana
  21. // applications.
  22. class G3Remote {
  23. protected static $_instance;
  24. private $_gallery3_site;
  25. private $_access_token;
  26. public static function instance($site=null, $access_token=null) {
  27. if (!isset(G3Remote::$_instance)) {
  28. G3Remote::$_instance = new G3Remote($site, $access_token);
  29. }
  30. return G3Remote::$_instance;
  31. }
  32. /**
  33. * Constructs a new G3Remote object
  34. *
  35. * @param array Database config array
  36. * @return G3Remote
  37. */
  38. protected function __construct($site, $access_token) {
  39. // Store the config locally
  40. $this->_gallery3_site = $site;
  41. $this->_access_token = $access_token;
  42. }
  43. public function get_access_token($user, $password) {
  44. $request = "{$this->_gallery3_site}/access_key";
  45. list ($response_status, $response_headers, $response_body) =
  46. G3Remote::_get($request, array("user" => $user, "password" => $password));
  47. if (G3Remote::_success($response_status)) {
  48. $response = json_decode($response_body);
  49. if ($response->status == "OK") {
  50. $this->_access_token = $response->token;
  51. } else {
  52. throw new Exception("Remote host failure: {$response->message}");
  53. }
  54. } else {
  55. throw new Exception("Remote host failure: $response_status");
  56. }
  57. return $this->_access_token;
  58. }
  59. public function get_resource($path, $params=array()) {
  60. return $this->_do_request("get", $path, $params);
  61. }
  62. public function delete_resource($path) {
  63. return $this->_do_request("delete", $path);
  64. }
  65. public function update_resource($path, $params) {
  66. return $this->_do_request("put", $path, $params);
  67. }
  68. public function add_resource($path, $params) {
  69. return $this->_do_request("post", $path, $params);
  70. }
  71. private function _do_request($method, $path, $params=array()) {
  72. $request_path = "{$this->_gallery3_site}/$path";
  73. $headers = array();
  74. if ($method == "put" || $method == "delete") {
  75. $headers["X_GALLERY_REQUEST_METHOD"] = $method;
  76. $method = "post";
  77. }
  78. if (!empty($this->_access_token)) {
  79. $headers["X_GALLERY_REQUEST_KEY"] = $this->_access_token;
  80. }
  81. list ($response_status, $response_headers, $response_body) =
  82. $method == "get" ? G3Remote::_get($request_path, $params, $headers) :
  83. G3Remote::_post($request_path, $params, $headers);
  84. if (G3Remote::_success($response_status)) {
  85. $response = json_decode($response_body);
  86. switch ($response->status) {
  87. case "OK":
  88. case "VALIDATE_ERROR":
  89. return $response;
  90. default:
  91. throw new Exception("Remote host failure: {$response->message}");
  92. }
  93. } else {
  94. throw new Exception("Remote host failure: $response_status");
  95. }
  96. }
  97. private static function _post($url, $post_data_array, $extra_headers=array()) {
  98. $boundary = str_repeat("-", 9) . md5(microtime());
  99. $boundary_length = strlen($boundary);
  100. $extra_headers['Content-Type'] = "multipart/form-data; boundary=$boundary";
  101. $length = 0;
  102. $fields = array();
  103. foreach ($post_data_array as $field => $value) {
  104. $fields[$field] = array();
  105. if (is_string($value)) {
  106. $fields[$field]["disposition"] = "Content-Disposition: form-data; name=\"$field\"\r\n\r\n";
  107. $fields[$field]["type"] = "";
  108. $fields[$field]["value"] = "$value\r\n";
  109. } else {
  110. $fields[$field]["disposition"] =
  111. "Content-Disposition: form-data; name=\"$field\"; filename=\"{$value->name}\"\r\n";
  112. $fields[$field]["type"] = "Content-Type: {$value->type}\r\n\r\n";
  113. $fields[$field]["value"] = "\r\n";
  114. $fields[$field]["local_file"] = $value->tmp_name;
  115. $length += $value->size;
  116. }
  117. $length += strlen($fields[$field]["disposition"]) + strlen($fields[$field]["value"]) +
  118. strlen($fields[$field]["type"]) + $boundary_length + 4;
  119. }
  120. $length += $boundary_length + 6; // boundary terminator and last crlf
  121. $extra_headers['Content-Length'] = $length;
  122. $socket = G3Remote::_open_socket($url, 'POST', $extra_headers);
  123. $sent_length = 0;
  124. foreach ($fields as $field => $value) {
  125. $sent_length += fwrite($socket, "--$boundary\r\n");
  126. $sent_length += fwrite($socket, $value["disposition"]);
  127. if (!empty($value["type"])) {
  128. $sent_length += fwrite($socket, $value["type"]);
  129. $file = fopen($value["local_file"], "rb");
  130. while (!feof($file)) {
  131. $buffer = fread($file, 8192);
  132. $sent_length += fwrite($socket, $buffer);
  133. fflush($socket);
  134. }
  135. }
  136. $sent_length += fwrite($socket, $value["value"]);
  137. fflush($socket);
  138. }
  139. $sent_length += fwrite($socket, "--$boundary--\r\n");
  140. fflush($socket);
  141. /* Read the web page into a buffer */
  142. return G3Remote::_get_response($socket);
  143. }
  144. private static function _get($url, $_data_array=array(), $extra_headers=array()) {
  145. $_data_raw = self::_encode_data($_data_array, $extra_headers);
  146. $handle = G3Remote::_open_socket("{$url}?$_data_raw", "GET", $extra_headers);
  147. /* Read the web page into a buffer */
  148. return G3Remote::_get_response($handle);
  149. }
  150. private static function _success($response_status) {
  151. return preg_match("/^HTTP\/\d+\.\d+\s2\d{2}(\s|$)/", trim($response_status));
  152. }
  153. /**
  154. * Encode the data. For each key/value pair, urlencode both the key and the value and then
  155. * concatenate together. As per the specification, each key/value pair is separated with an
  156. * ampersand (&)
  157. * @param array $data_array the key/value data
  158. * @param array $extra_headers extra headers to pass to the server
  159. * @return string the encoded post data
  160. */
  161. private static function _encode_data($_data_array, &$extra_headers) {
  162. $_data_raw = '';
  163. foreach ($_data_array as $key => $value) {
  164. if (!empty($_data_raw)) {
  165. $_data_raw .= '&';
  166. }
  167. $_data_raw .= urlencode($key) . '=' . urlencode($value);
  168. }
  169. return $_data_raw;
  170. }
  171. /**
  172. * Open the socket to server
  173. */
  174. static function _open_socket($url, $method='GET', $headers=array()) {
  175. /* Convert illegal characters */
  176. $url = str_replace(' ', '%20', $url);
  177. $url_components = self::_parse_url_for_fsockopen($url);
  178. $handle = fsockopen(
  179. $url_components['fsockhost'], $url_components['port'], $errno, $errstr, 5);
  180. if (empty($handle)) {
  181. return array(null, null, null);
  182. }
  183. $header_lines = array('Host: ' . $url_components['host']);
  184. foreach ($headers as $key => $value) {
  185. $header_lines[] = $key . ': ' . $value;
  186. }
  187. $success = fwrite($handle, sprintf("%s %s HTTP/1.0\r\n%s\r\n\r\n",
  188. $method,
  189. $url_components['uri'],
  190. implode("\r\n", $header_lines)));
  191. fflush($handle);
  192. return $handle;
  193. }
  194. /**
  195. * Read the http response
  196. */
  197. static function _get_response($handle) {
  198. /*
  199. * Read the status line. fgets stops after newlines. The first line is the protocol
  200. * version followed by a numeric status code and its associated textual phrase.
  201. */
  202. $response_status = trim(fgets($handle, 4096));
  203. if (empty($response_status)) {
  204. // 'Empty http response code, maybe timeout'
  205. return array(null, null, null);
  206. }
  207. /* Read the headers */
  208. $response_headers = array();
  209. while (!feof($handle)) {
  210. $line = trim(fgets($handle, 4096));
  211. if (empty($line)) {
  212. break;
  213. }
  214. /* Normalize the line endings */
  215. $line = str_replace("\r", '', $line);
  216. list ($key, $value) = explode(':', $line, 2);
  217. if (isset($response_headers[$key])) {
  218. if (!is_array($response_headers[$key])) {
  219. $response_headers[$key] = array($response_headers[$key]);
  220. }
  221. $response_headers[$key][] = trim($value);
  222. } else {
  223. $response_headers[$key] = trim($value);
  224. }
  225. }
  226. /* Read the body */
  227. $response_body = '';
  228. while (!feof($handle)) {
  229. $response_body .= fread($handle, 4096);
  230. }
  231. fclose($handle);
  232. return array($response_status, $response_headers, $response_body);
  233. }
  234. /**
  235. * Prepare for fsockopen call.
  236. * @param string $url
  237. * @return array url components
  238. * @access private
  239. */
  240. private static function _parse_url_for_fsockopen($url) {
  241. $url_components = parse_url($url);
  242. if (strtolower($url_components['scheme']) == 'https') {
  243. $url_components['fsockhost'] = 'ssl://' . $url_components['host'];
  244. $default_port = 443;
  245. } else {
  246. $url_components['fsockhost'] = $url_components['host'];
  247. $default_port = 80;
  248. }
  249. if (empty($url_components['port'])) {
  250. $url_components['port'] = $default_port;
  251. }
  252. if (empty($url_components['path'])) {
  253. $url_components['path'] = '/';
  254. }
  255. $uri = $url_components['path']
  256. . (empty($url_components['query']) ? '' : '?' . $url_components['query']);
  257. /* Unescape ampersands, since if the url comes from form input it will be escaped */
  258. $url_components['uri'] = str_replace('&amp;', '&', $uri);
  259. return $url_components;
  260. }
  261. }