PageRenderTime 70ms CodeModel.GetById 39ms RepoModel.GetById 1ms app.codeStats 0ms

/wp-content/plugins/w3-total-cache/lib/CF/cloudfiles_http.php

https://bitbucket.org/broderboy/nycendurance-wordpress
PHP | 1347 lines | 1102 code | 134 blank | 111 comment | 278 complexity | 47b52f49b4a062c0e018bd7b6ae8dbcd MD5 | raw file
Possible License(s): AGPL-1.0, GPL-3.0, Apache-2.0, GPL-2.0, LGPL-2.1
  1. <?php
  2. /**
  3. * This is an HTTP client class for Cloud Files. It uses PHP's cURL module
  4. * to handle the actual HTTP request/response. This is NOT a generic HTTP
  5. * client class and is only used to abstract out the HTTP communication for
  6. * the PHP Cloud Files API.
  7. *
  8. * This module was designed to re-use existing HTTP(S) connections between
  9. * subsequent operations. For example, performing multiple PUT operations
  10. * will re-use the same connection.
  11. *
  12. * This modules also provides support for streaming content into and out
  13. * of Cloud Files. The majority (all?) of the PHP HTTP client modules expect
  14. * to read the server's response into a string variable. This will not work
  15. * with large files without killing your server. Methods like,
  16. * get_object_to_stream() and put_object() take an open filehandle
  17. * argument for streaming data out of or into Cloud Files.
  18. *
  19. * Requres PHP 5.x (for Exceptions and OO syntax)
  20. *
  21. * See COPYING for license information.
  22. *
  23. * @author Eric "EJ" Johnson <ej@racklabs.com>
  24. * @copyright Copyright (c) 2008, Rackspace US, Inc.
  25. * @package php-cloudfiles-http
  26. */
  27. /**
  28. */
  29. require_once("cloudfiles_exceptions.php");
  30. define("PHP_CF_VERSION", "1.7.6");
  31. define("USER_AGENT", sprintf("PHP-CloudFiles/%s", PHP_CF_VERSION));
  32. define("ACCOUNT_CONTAINER_COUNT", "X-Account-Container-Count");
  33. define("ACCOUNT_BYTES_USED", "X-Account-Bytes-Used");
  34. define("CONTAINER_OBJ_COUNT", "X-Container-Object-Count");
  35. define("CONTAINER_BYTES_USED", "X-Container-Bytes-Used");
  36. define("METADATA_HEADER", "X-Object-Meta-");
  37. define("CDN_URI", "X-CDN-URI");
  38. define("CDN_ENABLED", "X-CDN-Enabled");
  39. define("CDN_LOG_RETENTION", "X-Log-Retention");
  40. define("CDN_ACL_USER_AGENT", "X-User-Agent-ACL");
  41. define("CDN_ACL_REFERRER", "X-Referrer-ACL");
  42. define("CDN_TTL", "X-TTL");
  43. define("CDNM_URL", "X-CDN-Management-Url");
  44. define("STORAGE_URL", "X-Storage-Url");
  45. define("AUTH_TOKEN", "X-Auth-Token");
  46. define("AUTH_USER_HEADER", "X-Auth-User");
  47. define("AUTH_KEY_HEADER", "X-Auth-Key");
  48. define("AUTH_USER_HEADER_LEGACY", "X-Storage-User");
  49. define("AUTH_KEY_HEADER_LEGACY", "X-Storage-Pass");
  50. define("AUTH_TOKEN_LEGACY", "X-Storage-Token");
  51. /**
  52. * HTTP/cURL wrapper for Cloud Files
  53. *
  54. * This class should not be used directly. It's only purpose is to abstract
  55. * out the HTTP communication from the main API.
  56. *
  57. * @package php-cloudfiles-http
  58. */
  59. class CF_Http
  60. {
  61. private $error_str;
  62. private $dbug;
  63. private $cabundle_path;
  64. private $api_version;
  65. # Authentication instance variables
  66. #
  67. private $storage_url;
  68. private $cdnm_url;
  69. private $auth_token;
  70. # Request/response variables
  71. #
  72. private $response_status;
  73. private $response_reason;
  74. private $connections;
  75. # Variables used for content/header callbacks
  76. #
  77. private $_user_read_progress_callback_func;
  78. private $_user_write_progress_callback_func;
  79. private $_write_callback_type;
  80. private $_text_list;
  81. private $_account_container_count;
  82. private $_account_bytes_used;
  83. private $_container_object_count;
  84. private $_container_bytes_used;
  85. private $_obj_etag;
  86. private $_obj_last_modified;
  87. private $_obj_content_type;
  88. private $_obj_content_length;
  89. private $_obj_metadata;
  90. private $_obj_write_resource;
  91. private $_obj_write_string;
  92. private $_cdn_enabled;
  93. private $_cdn_uri;
  94. private $_cdn_ttl;
  95. private $_cdn_log_retention;
  96. private $_cdn_acl_user_agent;
  97. private $_cdn_acl_referrer;
  98. function __construct($api_version)
  99. {
  100. $this->dbug = False;
  101. $this->cabundle_path = NULL;
  102. $this->api_version = $api_version;
  103. $this->error_str = NULL;
  104. $this->storage_url = NULL;
  105. $this->cdnm_url = NULL;
  106. $this->auth_token = NULL;
  107. $this->response_status = NULL;
  108. $this->response_reason = NULL;
  109. # Curl connections array - since there is no way to "re-set" the
  110. # connection paramaters for a cURL handle, we keep an array of
  111. # the unique use-cases and funnel all of those same type
  112. # requests through the appropriate curl connection.
  113. #
  114. $this->connections = array(
  115. "GET_CALL" => NULL, # GET objects/containers/lists
  116. "PUT_OBJ" => NULL, # PUT object
  117. "HEAD" => NULL, # HEAD requests
  118. "PUT_CONT" => NULL, # PUT container
  119. "DEL_POST" => NULL, # DELETE containers/objects, POST objects
  120. );
  121. $this->_user_read_progress_callback_func = NULL;
  122. $this->_user_write_progress_callback_func = NULL;
  123. $this->_write_callback_type = NULL;
  124. $this->_text_list = array();
  125. $this->_return_list = NULL;
  126. $this->_account_container_count = 0;
  127. $this->_account_bytes_used = 0;
  128. $this->_container_object_count = 0;
  129. $this->_container_bytes_used = 0;
  130. $this->_obj_write_resource = NULL;
  131. $this->_obj_write_string = "";
  132. $this->_obj_etag = NULL;
  133. $this->_obj_last_modified = NULL;
  134. $this->_obj_content_type = NULL;
  135. $this->_obj_content_length = NULL;
  136. $this->_obj_metadata = array();
  137. $this->_cdn_enabled = NULL;
  138. $this->_cdn_uri = NULL;
  139. $this->_cdn_ttl = NULL;
  140. $this->_cdn_log_retention = NULL;
  141. $this->_cdn_acl_user_agent = NULL;
  142. $this->_cdn_acl_referrer = NULL;
  143. # The OS list with a PHP without an updated CA File for CURL to
  144. # connect to SSL Websites. It is the first 3 letters of the PHP_OS
  145. # variable.
  146. $OS_CAFILE_NONUPDATED=array(
  147. "win","dar"
  148. );
  149. if (in_array((strtolower (substr(PHP_OS, 0,3))), $OS_CAFILE_NONUPDATED))
  150. $this->ssl_use_cabundle();
  151. }
  152. function ssl_use_cabundle($path=NULL)
  153. {
  154. if ($path) {
  155. $this->cabundle_path = $path;
  156. } else {
  157. $this->cabundle_path = dirname(__FILE__) . "/cacert.pem";
  158. }
  159. if (!file_exists($this->cabundle_path)) {
  160. throw new IOException("Could not use CA bundle: "
  161. . $this->cabundle_path);
  162. }
  163. return;
  164. }
  165. # Uses separate cURL connection to authenticate
  166. #
  167. function authenticate($user, $pass, $acct=NULL, $host=NULL)
  168. {
  169. $path = array();
  170. if (isset($acct)){
  171. $headers = array(
  172. sprintf("%s: %s", AUTH_USER_HEADER_LEGACY, $user),
  173. sprintf("%s: %s", AUTH_KEY_HEADER_LEGACY, $pass),
  174. );
  175. $path[] = $host;
  176. $path[] = rawurlencode(sprintf("v%d",$this->api_version));
  177. $path[] = rawurlencode($acct);
  178. } else {
  179. $headers = array(
  180. sprintf("%s: %s", AUTH_USER_HEADER, $user),
  181. sprintf("%s: %s", AUTH_KEY_HEADER, $pass),
  182. );
  183. $path[] = $host;
  184. }
  185. $path[] = "v1.0";
  186. $url = implode("/", $path);
  187. $curl_ch = curl_init();
  188. if (!is_null($this->cabundle_path)) {
  189. curl_setopt($curl_ch, CURLOPT_SSL_VERIFYPEER, True);
  190. curl_setopt($curl_ch, CURLOPT_CAINFO, $this->cabundle_path);
  191. }
  192. curl_setopt($curl_ch, CURLOPT_VERBOSE, $this->dbug);
  193. @curl_setopt($curl_ch, CURLOPT_FOLLOWLOCATION, 1);
  194. curl_setopt($curl_ch, CURLOPT_MAXREDIRS, 4);
  195. curl_setopt($curl_ch, CURLOPT_HEADER, 0);
  196. curl_setopt($curl_ch, CURLOPT_HTTPHEADER, $headers);
  197. curl_setopt($curl_ch, CURLOPT_USERAGENT, USER_AGENT);
  198. curl_setopt($curl_ch, CURLOPT_RETURNTRANSFER, TRUE);
  199. curl_setopt($curl_ch, CURLOPT_HEADERFUNCTION,array(&$this,'_auth_hdr_cb'));
  200. curl_setopt($curl_ch, CURLOPT_CONNECTTIMEOUT, 10);
  201. curl_setopt($curl_ch, CURLOPT_URL, $url);
  202. curl_exec($curl_ch);
  203. curl_close($curl_ch);
  204. return array($this->response_status, $this->response_reason,
  205. $this->storage_url, $this->cdnm_url, $this->auth_token);
  206. }
  207. # (CDN) GET /v1/Account
  208. #
  209. function list_cdn_containers($enabled_only)
  210. {
  211. $conn_type = "GET_CALL";
  212. $url_path = $this->_make_path("CDN");
  213. $this->_write_callback_type = "TEXT_LIST";
  214. if ($enabled_only)
  215. {
  216. $return_code = $this->_send_request($conn_type, $url_path .
  217. '/?enabled_only=true');
  218. }
  219. else
  220. {
  221. $return_code = $this->_send_request($conn_type, $url_path);
  222. }
  223. if (!$return_code) {
  224. $this->error_str .= ": Failed to obtain valid HTTP response.";
  225. array(0,$this->error_str,array());
  226. }
  227. if ($return_code == 401) {
  228. return array($return_code,"Unauthorized",array());
  229. }
  230. if ($return_code == 404) {
  231. return array($return_code,"Account not found.",array());
  232. }
  233. if ($return_code == 204) {
  234. return array($return_code,"Account has no CDN enabled Containers.",
  235. array());
  236. }
  237. if ($return_code == 200) {
  238. $this->create_array();
  239. return array($return_code,$this->response_reason,$this->_text_list);
  240. }
  241. $this->error_str = "Unexpected HTTP response: ".$this->response_reason;
  242. return array($return_code,$this->error_str,array());
  243. }
  244. # (CDN) POST /v1/Account/Container
  245. #
  246. function update_cdn_container($container_name, $ttl=86400, $cdn_log_retention=False,
  247. $cdn_acl_user_agent="", $cdn_acl_referrer)
  248. {
  249. if ($container_name == "")
  250. throw new SyntaxException("Container name not set.");
  251. if ($container_name != "0" and !isset($container_name))
  252. throw new SyntaxException("Container name not set.");
  253. $url_path = $this->_make_path("CDN", $container_name);
  254. $hdrs = array(
  255. CDN_ENABLED => "True",
  256. CDN_TTL => $ttl,
  257. CDN_LOG_RETENTION => $cdn_log_retention ? "True" : "False",
  258. CDN_ACL_USER_AGENT => $cdn_acl_user_agent,
  259. CDN_ACL_REFERRER => $cdn_acl_referrer,
  260. );
  261. $return_code = $this->_send_request("DEL_POST",$url_path,$hdrs,"POST");
  262. if ($return_code == 401) {
  263. $this->error_str = "Unauthorized";
  264. return array($return_code, $this->error_str, NULL);
  265. }
  266. if ($return_code == 404) {
  267. $this->error_str = "Container not found.";
  268. return array($return_code, $this->error_str, NULL);
  269. }
  270. if ($return_code != 202) {
  271. $this->error_str="Unexpected HTTP response: ".$this->response_reason;
  272. return array($return_code, $this->error_str, NULL);
  273. }
  274. return array($return_code, "Accepted", $this->_cdn_uri);
  275. }
  276. # (CDN) PUT /v1/Account/Container
  277. #
  278. function add_cdn_container($container_name, $ttl=86400)
  279. {
  280. if ($container_name == "")
  281. throw new SyntaxException("Container name not set.");
  282. if ($container_name != "0" and !isset($container_name))
  283. throw new SyntaxException("Container name not set.");
  284. $url_path = $this->_make_path("CDN", $container_name);
  285. $hdrs = array(
  286. CDN_ENABLED => "True",
  287. CDN_TTL => $ttl,
  288. );
  289. $return_code = $this->_send_request("PUT_CONT", $url_path, $hdrs);
  290. if ($return_code == 401) {
  291. $this->error_str = "Unauthorized";
  292. return array($return_code,$this->response_reason,False);
  293. }
  294. if (!in_array($return_code, array(201,202))) {
  295. $this->error_str="Unexpected HTTP response: ".$this->response_reason;
  296. return array($return_code,$this->response_reason,False);
  297. }
  298. return array($return_code,$this->response_reason,$this->_cdn_uri);
  299. }
  300. # (CDN) POST /v1/Account/Container
  301. #
  302. function remove_cdn_container($container_name)
  303. {
  304. if ($container_name == "")
  305. throw new SyntaxException("Container name not set.");
  306. if ($container_name != "0" and !isset($container_name))
  307. throw new SyntaxException("Container name not set.");
  308. $url_path = $this->_make_path("CDN", $container_name);
  309. $hdrs = array(CDN_ENABLED => "False");
  310. $return_code = $this->_send_request("DEL_POST",$url_path,$hdrs,"POST");
  311. if ($return_code == 401) {
  312. $this->error_str = "Unauthorized";
  313. return array($return_code, $this->error_str);
  314. }
  315. if ($return_code == 404) {
  316. $this->error_str = "Container not found.";
  317. return array($return_code, $this->error_str);
  318. }
  319. if ($return_code != 202) {
  320. $this->error_str="Unexpected HTTP response: ".$this->response_reason;
  321. return array($return_code, $this->error_str);
  322. }
  323. return array($return_code, "Accepted");
  324. }
  325. # (CDN) HEAD /v1/Account
  326. #
  327. function head_cdn_container($container_name)
  328. {
  329. if ($container_name == "")
  330. throw new SyntaxException("Container name not set.");
  331. if ($container_name != "0" and !isset($container_name))
  332. throw new SyntaxException("Container name not set.");
  333. $conn_type = "HEAD";
  334. $url_path = $this->_make_path("CDN", $container_name);
  335. $return_code = $this->_send_request($conn_type, $url_path);
  336. if (!$return_code) {
  337. $this->error_str .= ": Failed to obtain valid HTTP response.";
  338. return array(0,$this->error_str,NULL,NULL,NULL,NULL,NULL,NULL);
  339. }
  340. if ($return_code == 401) {
  341. return array($return_code,"Unauthorized",NULL,NULL,NULL,NULL,NULL,NULL);
  342. }
  343. if ($return_code == 404) {
  344. return array($return_code,"Account not found.",NULL,NULL,NULL,NULL,NULL,NULL);
  345. }
  346. if ($return_code == 204) {
  347. return array($return_code,$this->response_reason,
  348. $this->_cdn_enabled, $this->_cdn_uri, $this->_cdn_ttl,
  349. $this->_cdn_log_retention,
  350. $this->_cdn_acl_user_agent,
  351. $this->_cdn_acl_referrer
  352. );
  353. }
  354. return array($return_code,$this->response_reason,
  355. NULL,NULL,NULL,
  356. $this->_cdn_log_retention,
  357. $this->_cdn_acl_user_agent,
  358. $this->_cdn_acl_referrer
  359. );
  360. }
  361. # GET /v1/Account
  362. #
  363. function list_containers($limit=0, $marker=NULL)
  364. {
  365. $conn_type = "GET_CALL";
  366. $url_path = $this->_make_path();
  367. $limit = intval($limit);
  368. $params = array();
  369. if ($limit > 0) {
  370. $params[] = "limit=$limit";
  371. }
  372. if ($marker) {
  373. $params[] = "marker=".rawurlencode($marker);
  374. }
  375. if (!empty($params)) {
  376. $url_path .= "?" . implode("&", $params);
  377. }
  378. $this->_write_callback_type = "TEXT_LIST";
  379. $return_code = $this->_send_request($conn_type, $url_path);
  380. if (!$return_code) {
  381. $this->error_str .= ": Failed to obtain valid HTTP response.";
  382. return array(0,$this->error_str,array());
  383. }
  384. if ($return_code == 204) {
  385. return array($return_code, "Account has no containers.", array());
  386. }
  387. if ($return_code == 404) {
  388. $this->error_str = "Invalid account name for authentication token.";
  389. return array($return_code,$this->error_str,array());
  390. }
  391. if ($return_code == 200) {
  392. $this->create_array();
  393. return array($return_code, $this->response_reason, $this->_text_list);
  394. }
  395. $this->error_str = "Unexpected HTTP response: ".$this->response_reason;
  396. return array($return_code,$this->error_str,array());
  397. }
  398. # GET /v1/Account?format=json
  399. #
  400. function list_containers_info($limit=0, $marker=NULL)
  401. {
  402. $conn_type = "GET_CALL";
  403. $url_path = $this->_make_path() . "?format=json";
  404. $limit = intval($limit);
  405. $params = array();
  406. if ($limit > 0) {
  407. $params[] = "limit=$limit";
  408. }
  409. if ($marker) {
  410. $params[] = "marker=".rawurlencode($marker);
  411. }
  412. if (!empty($params)) {
  413. $url_path .= "&" . implode("&", $params);
  414. }
  415. $this->_write_callback_type = "OBJECT_STRING";
  416. $return_code = $this->_send_request($conn_type, $url_path);
  417. if (!$return_code) {
  418. $this->error_str .= ": Failed to obtain valid HTTP response.";
  419. return array(0,$this->error_str,array());
  420. }
  421. if ($return_code == 204) {
  422. return array($return_code, "Account has no containers.", array());
  423. }
  424. if ($return_code == 404) {
  425. $this->error_str = "Invalid account name for authentication token.";
  426. return array($return_code,$this->error_str,array());
  427. }
  428. if ($return_code == 200) {
  429. $json_body = json_decode($this->_obj_write_string, True);
  430. return array($return_code, $this->response_reason, $json_body);
  431. }
  432. $this->error_str = "Unexpected HTTP response: ".$this->response_reason;
  433. return array($return_code,$this->error_str,array());
  434. }
  435. # HEAD /v1/Account
  436. #
  437. function head_account()
  438. {
  439. $conn_type = "HEAD";
  440. $url_path = $this->_make_path();
  441. $return_code = $this->_send_request($conn_type,$url_path);
  442. if (!$return_code) {
  443. $this->error_str .= ": Failed to obtain valid HTTP response.";
  444. array(0,$this->error_str,0,0);
  445. }
  446. if ($return_code == 404) {
  447. return array($return_code,"Account not found.",0,0);
  448. }
  449. if ($return_code == 204) {
  450. return array($return_code,$this->response_reason,
  451. $this->_account_container_count, $this->_account_bytes_used);
  452. }
  453. return array($return_code,$this->response_reason,0,0);
  454. }
  455. # PUT /v1/Account/Container
  456. #
  457. function create_container($container_name)
  458. {
  459. if ($container_name == "")
  460. throw new SyntaxException("Container name not set.");
  461. if ($container_name != "0" and !isset($container_name))
  462. throw new SyntaxException("Container name not set.");
  463. $url_path = $this->_make_path("STORAGE", $container_name);
  464. $return_code = $this->_send_request("PUT_CONT",$url_path);
  465. if (!$return_code) {
  466. $this->error_str .= ": Failed to obtain valid HTTP response.";
  467. return False;
  468. }
  469. return $return_code;
  470. }
  471. # DELETE /v1/Account/Container
  472. #
  473. function delete_container($container_name)
  474. {
  475. if ($container_name == "")
  476. throw new SyntaxException("Container name not set.");
  477. if ($container_name != "0" and !isset($container_name))
  478. throw new SyntaxException("Container name not set.");
  479. $url_path = $this->_make_path("STORAGE", $container_name);
  480. $return_code = $this->_send_request("DEL_POST",$url_path,array(),"DELETE");
  481. if (!$return_code) {
  482. $this->error_str .= ": Failed to obtain valid HTTP response.";
  483. }
  484. if ($return_code == 409) {
  485. $this->error_str = "Container must be empty prior to removing it.";
  486. }
  487. if ($return_code == 404) {
  488. $this->error_str = "Specified container did not exist to delete.";
  489. }
  490. if ($return_code != 204) {
  491. $this->error_str = "Unexpected HTTP return code: $return_code.";
  492. }
  493. return $return_code;
  494. }
  495. # GET /v1/Account/Container
  496. #
  497. function list_objects($cname,$limit=0,$marker=NULL,$prefix=NULL,$path=NULL)
  498. {
  499. if (!$cname) {
  500. $this->error_str = "Container name not set.";
  501. return array(0, $this->error_str, array());
  502. }
  503. $url_path = $this->_make_path("STORAGE", $cname);
  504. $limit = intval($limit);
  505. $params = array();
  506. if ($limit > 0) {
  507. $params[] = "limit=$limit";
  508. }
  509. if ($marker) {
  510. $params[] = "marker=".rawurlencode($marker);
  511. }
  512. if ($prefix) {
  513. $params[] = "prefix=".rawurlencode($prefix);
  514. }
  515. if ($path) {
  516. $params[] = "path=".rawurlencode($path);
  517. }
  518. if (!empty($params)) {
  519. $url_path .= "?" . implode("&", $params);
  520. }
  521. $conn_type = "GET_CALL";
  522. $this->_write_callback_type = "TEXT_LIST";
  523. $return_code = $this->_send_request($conn_type,$url_path);
  524. if (!$return_code) {
  525. $this->error_str .= ": Failed to obtain valid HTTP response.";
  526. return array(0,$this->error_str,array());
  527. }
  528. if ($return_code == 204) {
  529. $this->error_str = "Container has no Objects.";
  530. return array($return_code,$this->error_str,array());
  531. }
  532. if ($return_code == 404) {
  533. $this->error_str = "Container has no Objects.";
  534. return array($return_code,$this->error_str,array());
  535. }
  536. if ($return_code == 200) {
  537. $this->create_array();
  538. return array($return_code,$this->response_reason, $this->_text_list);
  539. }
  540. $this->error_str = "Unexpected HTTP response code: $return_code";
  541. return array(0,$this->error_str,array());
  542. }
  543. # GET /v1/Account/Container?format=json
  544. #
  545. function get_objects($cname,$limit=0,$marker=NULL,$prefix=NULL,$path=NULL)
  546. {
  547. if (!$cname) {
  548. $this->error_str = "Container name not set.";
  549. return array(0, $this->error_str, array());
  550. }
  551. $url_path = $this->_make_path("STORAGE", $cname);
  552. $limit = intval($limit);
  553. $params = array();
  554. $params[] = "format=json";
  555. if ($limit > 0) {
  556. $params[] = "limit=$limit";
  557. }
  558. if ($marker) {
  559. $params[] = "marker=".rawurlencode($marker);
  560. }
  561. if ($prefix) {
  562. $params[] = "prefix=".rawurlencode($prefix);
  563. }
  564. if ($path) {
  565. $params[] = "path=".rawurlencode($path);
  566. }
  567. if (!empty($params)) {
  568. $url_path .= "?" . implode("&", $params);
  569. }
  570. $conn_type = "GET_CALL";
  571. $this->_write_callback_type = "OBJECT_STRING";
  572. $return_code = $this->_send_request($conn_type,$url_path);
  573. if (!$return_code) {
  574. $this->error_str .= ": Failed to obtain valid HTTP response.";
  575. return array(0,$this->error_str,array());
  576. }
  577. if ($return_code == 204) {
  578. $this->error_str = "Container has no Objects.";
  579. return array($return_code,$this->error_str,array());
  580. }
  581. if ($return_code == 404) {
  582. $this->error_str = "Container has no Objects.";
  583. return array($return_code,$this->error_str,array());
  584. }
  585. if ($return_code == 200) {
  586. $json_body = json_decode($this->_obj_write_string, True);
  587. return array($return_code,$this->response_reason, $json_body);
  588. }
  589. $this->error_str = "Unexpected HTTP response code: $return_code";
  590. return array(0,$this->error_str,array());
  591. }
  592. # HEAD /v1/Account/Container
  593. #
  594. function head_container($container_name)
  595. {
  596. if ($container_name == "") {
  597. $this->error_str = "Container name not set.";
  598. return False;
  599. }
  600. if ($container_name != "0" and !isset($container_name)) {
  601. $this->error_str = "Container name not set.";
  602. return False;
  603. }
  604. $conn_type = "HEAD";
  605. $url_path = $this->_make_path("STORAGE", $container_name);
  606. $return_code = $this->_send_request($conn_type,$url_path);
  607. if (!$return_code) {
  608. $this->error_str .= ": Failed to obtain valid HTTP response.";
  609. array(0,$this->error_str,0,0);
  610. }
  611. if ($return_code == 404) {
  612. return array($return_code,"Container not found.",0,0);
  613. }
  614. if ($return_code == 204 || $return_code == 200) {
  615. return array($return_code,$this->response_reason,
  616. $this->_container_object_count, $this->_container_bytes_used);
  617. }
  618. return array($return_code,$this->response_reason,0,0);
  619. }
  620. # GET /v1/Account/Container/Object
  621. #
  622. function get_object_to_string(&$obj, $hdrs=array())
  623. {
  624. if (!is_object($obj) || get_class($obj) != "CF_Object") {
  625. throw new SyntaxException(
  626. "Method argument is not a valid CF_Object.");
  627. }
  628. $conn_type = "GET_CALL";
  629. $url_path = $this->_make_path("STORAGE", $obj->container->name,$obj->name);
  630. $this->_write_callback_type = "OBJECT_STRING";
  631. $return_code = $this->_send_request($conn_type,$url_path,$hdrs);
  632. if (!$return_code) {
  633. $this->error_str .= ": Failed to obtain valid HTTP response.";
  634. return array($return_code0,$this->error_str,NULL);
  635. }
  636. if ($return_code == 404) {
  637. $this->error_str = "Object not found.";
  638. return array($return_code0,$this->error_str,NULL);
  639. }
  640. if (($return_code < 200) || ($return_code > 299
  641. && $return_code != 412 && $return_code != 304)) {
  642. $this->error_str = "Unexpected HTTP return code: $return_code";
  643. return array($return_code,$this->error_str,NULL);
  644. }
  645. return array($return_code,$this->response_reason, $this->_obj_write_string);
  646. }
  647. # GET /v1/Account/Container/Object
  648. #
  649. function get_object_to_stream(&$obj, &$resource=NULL, $hdrs=array())
  650. {
  651. if (!is_object($obj) || get_class($obj) != "CF_Object") {
  652. throw new SyntaxException(
  653. "Method argument is not a valid CF_Object.");
  654. }
  655. if (!is_resource($resource)) {
  656. throw new SyntaxException(
  657. "Resource argument not a valid PHP resource.");
  658. }
  659. $conn_type = "GET_CALL";
  660. $url_path = $this->_make_path("STORAGE", $obj->container->name,$obj->name);
  661. $this->_obj_write_resource = $resource;
  662. $this->_write_callback_type = "OBJECT_STREAM";
  663. $return_code = $this->_send_request($conn_type,$url_path,$hdrs);
  664. if (!$return_code) {
  665. $this->error_str .= ": Failed to obtain valid HTTP response.";
  666. return array($return_code,$this->error_str);
  667. }
  668. if ($return_code == 404) {
  669. $this->error_str = "Object not found.";
  670. return array($return_code,$this->error_str);
  671. }
  672. if (($return_code < 200) || ($return_code > 299
  673. && $return_code != 412 && $return_code != 304)) {
  674. $this->error_str = "Unexpected HTTP return code: $return_code";
  675. return array($return_code,$this->error_str);
  676. }
  677. return array($return_code,$this->response_reason);
  678. }
  679. # PUT /v1/Account/Container/Object
  680. #
  681. function put_object(&$obj, &$fp)
  682. {
  683. if (!is_object($obj) || get_class($obj) != "CF_Object") {
  684. throw new SyntaxException(
  685. "Method argument is not a valid CF_Object.");
  686. }
  687. if (!is_resource($fp)) {
  688. throw new SyntaxException(
  689. "File pointer argument is not a valid resource.");
  690. }
  691. $conn_type = "PUT_OBJ";
  692. $url_path = $this->_make_path("STORAGE", $obj->container->name,$obj->name);
  693. $hdrs = $this->_metadata_headers($obj);
  694. $etag = $obj->getETag();
  695. if (isset($etag)) {
  696. $hdrs[] = "ETag: " . $etag;
  697. }
  698. if (!$obj->content_type) {
  699. $hdrs[] = "Content-Type: application/octet-stream";
  700. } else {
  701. $hdrs[] = "Content-Type: " . $obj->content_type;
  702. }
  703. $this->_init($conn_type);
  704. curl_setopt($this->connections[$conn_type],
  705. CURLOPT_INFILE, $fp);
  706. if (!$obj->content_length) {
  707. # We don''t know the Content-Length, so assumed "chunked" PUT
  708. #
  709. curl_setopt($this->connections[$conn_type], CURLOPT_UPLOAD, True);
  710. $hdrs[] = 'Transfer-Encoding: chunked';
  711. } else {
  712. # We know the Content-Length, so use regular transfer
  713. #
  714. curl_setopt($this->connections[$conn_type],
  715. CURLOPT_INFILESIZE, $obj->content_length);
  716. }
  717. $return_code = $this->_send_request($conn_type,$url_path,$hdrs);
  718. if (!$return_code) {
  719. $this->error_str .= ": Failed to obtain valid HTTP response.";
  720. return array(0,$this->error_str,NULL);
  721. }
  722. if ($return_code == 412) {
  723. $this->error_str = "Missing Content-Type header";
  724. return array($return_code,$this->error_str,NULL);
  725. }
  726. if ($return_code == 422) {
  727. $this->error_str = "Derived and computed checksums do not match.";
  728. return array($return_code,$this->error_str,NULL);
  729. }
  730. if ($return_code != 201) {
  731. $this->error_str = "Unexpected HTTP return code: $return_code";
  732. return array($return_code,$this->error_str,NULL);
  733. }
  734. return array($return_code,$this->response_reason,$this->_obj_etag);
  735. }
  736. # POST /v1/Account/Container/Object
  737. #
  738. function update_object(&$obj)
  739. {
  740. if (!is_object($obj) || get_class($obj) != "CF_Object") {
  741. throw new SyntaxException(
  742. "Method argument is not a valid CF_Object.");
  743. }
  744. if (!is_array($obj->metadata) || empty($obj->metadata)) {
  745. $this->error_str = "Metadata array is empty.";
  746. return 0;
  747. }
  748. $url_path = $this->_make_path("STORAGE", $obj->container->name,$obj->name);
  749. $hdrs = $this->_metadata_headers($obj);
  750. $return_code = $this->_send_request("DEL_POST",$url_path,$hdrs,"POST");
  751. if (!$return_code) {
  752. $this->error_str .= ": Failed to obtain valid HTTP response.";
  753. return 0;
  754. }
  755. if ($return_code == 404) {
  756. $this->error_str = "Account, Container, or Object not found.";
  757. }
  758. if ($return_code != 202) {
  759. $this->error_str = "Unexpected HTTP return code: $return_code";
  760. }
  761. return $return_code;
  762. }
  763. # HEAD /v1/Account/Container/Object
  764. #
  765. function head_object(&$obj)
  766. {
  767. if (!is_object($obj) || get_class($obj) != "CF_Object") {
  768. throw new SyntaxException(
  769. "Method argument is not a valid CF_Object.");
  770. }
  771. $conn_type = "HEAD";
  772. $url_path = $this->_make_path("STORAGE", $obj->container->name,$obj->name);
  773. $return_code = $this->_send_request($conn_type,$url_path);
  774. if (!$return_code) {
  775. $this->error_str .= ": Failed to obtain valid HTTP response.";
  776. return array(0, $this->error_str." ".$this->response_reason,
  777. NULL, NULL, NULL, NULL, array());
  778. }
  779. if ($return_code == 404) {
  780. return array($return_code, $this->response_reason,
  781. NULL, NULL, NULL, NULL, array());
  782. }
  783. if ($return_code == 204 || $return_code == 200) {
  784. return array($return_code,$this->response_reason,
  785. $this->_obj_etag,
  786. $this->_obj_last_modified,
  787. $this->_obj_content_type,
  788. $this->_obj_content_length,
  789. $this->_obj_metadata);
  790. }
  791. $this->error_str = "Unexpected HTTP return code: $return_code";
  792. return array($return_code, $this->error_str." ".$this->response_reason,
  793. NULL, NULL, NULL, NULL, array());
  794. }
  795. # DELETE /v1/Account/Container/Object
  796. #
  797. function delete_object($container_name, $object_name)
  798. {
  799. if ($container_name == "") {
  800. $this->error_str = "Container name not set.";
  801. return 0;
  802. }
  803. if ($container_name != "0" and !isset($container_name)) {
  804. $this->error_str = "Container name not set.";
  805. return 0;
  806. }
  807. if (!$object_name) {
  808. $this->error_str = "Object name not set.";
  809. return 0;
  810. }
  811. $url_path = $this->_make_path("STORAGE", $container_name,$object_name);
  812. $return_code = $this->_send_request("DEL_POST",$url_path,NULL,"DELETE");
  813. if (!$return_code) {
  814. $this->error_str .= ": Failed to obtain valid HTTP response.";
  815. return 0;
  816. }
  817. if ($return_code == 404) {
  818. $this->error_str = "Specified container did not exist to delete.";
  819. }
  820. if ($return_code != 204) {
  821. $this->error_str = "Unexpected HTTP return code: $return_code.";
  822. }
  823. return $return_code;
  824. }
  825. function get_error()
  826. {
  827. return $this->error_str;
  828. }
  829. function setDebug($bool)
  830. {
  831. $this->dbug = $bool;
  832. foreach ($this->connections as $k => $v) {
  833. if (!is_null($v)) {
  834. curl_setopt($this->connections[$k], CURLOPT_VERBOSE, $this->dbug);
  835. }
  836. }
  837. }
  838. function getCDNMUrl()
  839. {
  840. return $this->cdnm_url;
  841. }
  842. function getStorageUrl()
  843. {
  844. return $this->storage_url;
  845. }
  846. function getAuthToken()
  847. {
  848. return $this->auth_token;
  849. }
  850. function setCFAuth($cfs_auth, $servicenet=False)
  851. {
  852. if ($servicenet) {
  853. $this->storage_url = "https://snet-" . substr($cfs_auth->storage_url, 8);
  854. } else {
  855. $this->storage_url = $cfs_auth->storage_url;
  856. }
  857. $this->auth_token = $cfs_auth->auth_token;
  858. $this->cdnm_url = $cfs_auth->cdnm_url;
  859. }
  860. function setReadProgressFunc($func_name)
  861. {
  862. $this->_user_read_progress_callback_func = $func_name;
  863. }
  864. function setWriteProgressFunc($func_name)
  865. {
  866. $this->_user_write_progress_callback_func = $func_name;
  867. }
  868. private function _header_cb($ch, $header)
  869. {
  870. preg_match("/^HTTP\/1\.[01] (\d{3}) (.*)/", $header, $matches);
  871. if (isset($matches[1])) {
  872. $this->response_status = $matches[1];
  873. }
  874. if (isset($matches[2])) {
  875. $this->response_reason = $matches[2];
  876. }
  877. if (stripos($header, CDN_ENABLED) === 0) {
  878. $val = trim(substr($header, strlen(CDN_ENABLED)+1));
  879. if (strtolower($val) == "true") {
  880. $this->_cdn_enabled = True;
  881. } elseif (strtolower($val) == "false") {
  882. $this->_cdn_enabled = False;
  883. } else {
  884. $this->_cdn_enabled = NULL;
  885. }
  886. return strlen($header);
  887. }
  888. if (stripos($header, CDN_URI) === 0) {
  889. $this->_cdn_uri = trim(substr($header, strlen(CDN_URI)+1));
  890. return strlen($header);
  891. }
  892. if (stripos($header, CDN_TTL) === 0) {
  893. $this->_cdn_ttl = trim(substr($header, strlen(CDN_TTL)+1))+0;
  894. return strlen($header);
  895. }
  896. if (stripos($header, CDN_LOG_RETENTION) === 0) {
  897. $this->_cdn_log_retention =
  898. trim(substr($header, strlen(CDN_LOG_RETENTION)+1)) == "True" ? True : False;
  899. return strlen($header);
  900. }
  901. if (stripos($header, CDN_ACL_USER_AGENT) === 0) {
  902. $this->_cdn_acl_user_agent =
  903. trim(substr($header, strlen(CDN_ACL_USER_AGENT)+1));
  904. return strlen($header);
  905. }
  906. if (stripos($header, CDN_ACL_REFERRER) === 0) {
  907. $this->_cdn_acl_referrer =
  908. trim(substr($header, strlen(CDN_ACL_REFERRER)+1));
  909. return strlen($header);
  910. }
  911. if (stripos($header, ACCOUNT_CONTAINER_COUNT) === 0) {
  912. $this->_account_container_count = (float) trim(substr($header,
  913. strlen(ACCOUNT_CONTAINER_COUNT)+1))+0;
  914. return strlen($header);
  915. }
  916. if (stripos($header, ACCOUNT_BYTES_USED) === 0) {
  917. $this->_account_bytes_used = (float) trim(substr($header,
  918. strlen(ACCOUNT_BYTES_USED)+1))+0;
  919. return strlen($header);
  920. }
  921. if (stripos($header, CONTAINER_OBJ_COUNT) === 0) {
  922. $this->_container_object_count = (float) trim(substr($header,
  923. strlen(CONTAINER_OBJ_COUNT)+1))+0;
  924. return strlen($header);
  925. }
  926. if (stripos($header, CONTAINER_BYTES_USED) === 0) {
  927. $this->_container_bytes_used = (float) trim(substr($header,
  928. strlen(CONTAINER_BYTES_USED)+1))+0;
  929. return strlen($header);
  930. }
  931. if (stripos($header, METADATA_HEADER) === 0) {
  932. # $header => X-Object-Meta-Foo: bar baz
  933. $temp = substr($header, strlen(METADATA_HEADER));
  934. # $temp => Foo: bar baz
  935. $parts = explode(":", $temp);
  936. # $parts[0] => Foo
  937. $val = substr(strstr($temp, ":"), 1);
  938. # $val => bar baz
  939. $this->_obj_metadata[$parts[0]] = trim($val);
  940. return strlen($header);
  941. }
  942. if (stripos($header, "ETag:") === 0) {
  943. # $header => ETag: abc123def456...
  944. $val = substr(strstr($header, ":"), 1);
  945. # $val => abc123def456...
  946. $this->_obj_etag = trim($val);
  947. return strlen($header);
  948. }
  949. if (stripos($header, "Last-Modified:") === 0) {
  950. $val = substr(strstr($header, ":"), 1);
  951. $this->_obj_last_modified = trim($val);
  952. return strlen($header);
  953. }
  954. if (stripos($header, "Content-Type:") === 0) {
  955. $val = substr(strstr($header, ":"), 1);
  956. $this->_obj_content_type = trim($val);
  957. return strlen($header);
  958. }
  959. if (stripos($header, "Content-Length:") === 0) {
  960. $val = substr(strstr($header, ":"), 1);
  961. $this->_obj_content_length = (float) trim($val)+0;
  962. return strlen($header);
  963. }
  964. return strlen($header);
  965. }
  966. private function _read_cb($ch, $fd, $length)
  967. {
  968. $data = fread($fd, $length);
  969. $len = strlen($data);
  970. if (isset($this->_user_write_progress_callback_func)) {
  971. call_user_func($this->_user_write_progress_callback_func, $len);
  972. }
  973. return $data;
  974. }
  975. private function _write_cb($ch, $data)
  976. {
  977. $dlen = strlen($data);
  978. switch ($this->_write_callback_type) {
  979. case "TEXT_LIST":
  980. $this->_return_list = $this->_return_list . $data;
  981. //= explode("\n",$data); # keep tab,space
  982. //his->_text_list[] = rtrim($data,"\n\r\x0B"); # keep tab,space
  983. break;
  984. case "OBJECT_STREAM":
  985. fwrite($this->_obj_write_resource, $data, $dlen);
  986. break;
  987. case "OBJECT_STRING":
  988. $this->_obj_write_string .= $data;
  989. break;
  990. }
  991. if (isset($this->_user_read_progress_callback_func)) {
  992. call_user_func($this->_user_read_progress_callback_func, $dlen);
  993. }
  994. return $dlen;
  995. }
  996. private function _auth_hdr_cb($ch, $header)
  997. {
  998. preg_match("/^HTTP\/1\.[01] (\d{3}) (.*)/", $header, $matches);
  999. if (isset($matches[1])) {
  1000. $this->response_status = $matches[1];
  1001. }
  1002. if (isset($matches[2])) {
  1003. $this->response_reason = $matches[2];
  1004. }
  1005. if (stripos($header, STORAGE_URL) === 0) {
  1006. $this->storage_url = trim(substr($header, strlen(STORAGE_URL)+1));
  1007. }
  1008. if (stripos($header, CDNM_URL) === 0) {
  1009. $this->cdnm_url = trim(substr($header, strlen(CDNM_URL)+1));
  1010. }
  1011. if (stripos($header, AUTH_TOKEN) === 0) {
  1012. $this->auth_token = trim(substr($header, strlen(AUTH_TOKEN)+1));
  1013. }
  1014. if (stripos($header, AUTH_TOKEN_LEGACY) === 0) {
  1015. $this->auth_token = trim(substr($header,strlen(AUTH_TOKEN_LEGACY)+1));
  1016. }
  1017. return strlen($header);
  1018. }
  1019. private function _make_headers($hdrs=NULL)
  1020. {
  1021. $new_headers = array();
  1022. $has_stoken = False;
  1023. $has_uagent = False;
  1024. if (is_array($hdrs)) {
  1025. foreach ($hdrs as $h => $v) {
  1026. if (is_int($h)) {
  1027. $parts = explode(":", $v);
  1028. $header = $parts[0];
  1029. $value = trim(substr(strstr($v, ":"), 1));
  1030. } else {
  1031. $header = $h;
  1032. $value = trim($v);
  1033. }
  1034. if (stripos($header, AUTH_TOKEN) === 0) {
  1035. $has_stoken = True;
  1036. }
  1037. if (stripos($header, "user-agent") === 0) {
  1038. $has_uagent = True;
  1039. }
  1040. $new_headers[] = $header . ": " . $value;
  1041. }
  1042. }
  1043. if (!$has_stoken) {
  1044. $new_headers[] = AUTH_TOKEN . ": " . $this->auth_token;
  1045. }
  1046. if (!$has_uagent) {
  1047. $new_headers[] = "User-Agent: " . USER_AGENT;
  1048. }
  1049. return $new_headers;
  1050. }
  1051. private function _init($conn_type, $force_new=False)
  1052. {
  1053. if (!array_key_exists($conn_type, $this->connections)) {
  1054. $this->error_str = "Invalid CURL_XXX connection type";
  1055. return False;
  1056. }
  1057. if (is_null($this->connections[$conn_type]) || $force_new) {
  1058. $ch = curl_init();
  1059. } else {
  1060. return;
  1061. }
  1062. if ($this->dbug) { curl_setopt($ch, CURLOPT_VERBOSE, 1); }
  1063. if (!is_null($this->cabundle_path)) {
  1064. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, True);
  1065. curl_setopt($ch, CURLOPT_CAINFO, $this->cabundle_path);
  1066. }
  1067. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, True);
  1068. @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
  1069. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
  1070. curl_setopt($ch, CURLOPT_MAXREDIRS, 4);
  1071. curl_setopt($ch, CURLOPT_HEADER, 0);
  1072. curl_setopt($ch, CURLOPT_HEADERFUNCTION, array(&$this, '_header_cb'));
  1073. if ($conn_type == "GET_CALL") {
  1074. curl_setopt($ch, CURLOPT_WRITEFUNCTION, array(&$this, '_write_cb'));
  1075. }
  1076. if ($conn_type == "PUT_OBJ") {
  1077. curl_setopt($ch, CURLOPT_PUT, 1);
  1078. curl_setopt($ch, CURLOPT_READFUNCTION, array(&$this, '_read_cb'));
  1079. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  1080. }
  1081. if ($conn_type == "HEAD") {
  1082. curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "HEAD");
  1083. curl_setopt($ch, CURLOPT_NOBODY, 1);
  1084. }
  1085. if ($conn_type == "PUT_CONT") {
  1086. curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
  1087. curl_setopt($ch, CURLOPT_INFILESIZE, 0);
  1088. curl_setopt($ch, CURLOPT_NOBODY, 1);
  1089. }
  1090. if ($conn_type == "DEL_POST") {
  1091. curl_setopt($ch, CURLOPT_NOBODY, 1);
  1092. }
  1093. $this->connections[$conn_type] = $ch;
  1094. return;
  1095. }
  1096. private function _reset_callback_vars()
  1097. {
  1098. $this->_text_list = array();
  1099. $this->_return_list = NULL;
  1100. $this->_account_container_count = 0;
  1101. $this->_account_bytes_used = 0;
  1102. $this->_container_object_count = 0;
  1103. $this->_container_bytes_used = 0;
  1104. $this->_obj_etag = NULL;
  1105. $this->_obj_last_modified = NULL;
  1106. $this->_obj_content_type = NULL;
  1107. $this->_obj_content_length = NULL;
  1108. $this->_obj_metadata = array();
  1109. $this->_obj_write_string = "";
  1110. $this->_cdn_enabled = NULL;
  1111. $this->_cdn_uri = NULL;
  1112. $this->_cdn_ttl = NULL;
  1113. $this->response_status = 0;
  1114. $this->response_reason = "";
  1115. }
  1116. private function _make_path($t="STORAGE",$c=NULL,$o=NULL)
  1117. {
  1118. $path = array();
  1119. switch ($t) {
  1120. case "STORAGE":
  1121. $path[] = $this->storage_url; break;
  1122. case "CDN":
  1123. $path[] = $this->cdnm_url; break;
  1124. }
  1125. if ($c == "0")
  1126. $path[] = rawurlencode($c);
  1127. if ($c) {
  1128. $path[] = rawurlencode($c);
  1129. }
  1130. if ($o) {
  1131. # mimic Python''s urllib.quote() feature of a "safe" '/' character
  1132. #
  1133. $path[] = str_replace("%2F","/",rawurlencode($o));
  1134. }
  1135. return implode("/",$path);
  1136. }
  1137. private function _metadata_headers(&$obj)
  1138. {
  1139. $hdrs = array();
  1140. foreach ($obj->metadata as $k => $v) {
  1141. if (strpos($k,":") !== False) {
  1142. throw new SyntaxException(
  1143. "Metadata keys cannot contain a ':' character.");
  1144. }
  1145. $k = trim($k);
  1146. $key = sprintf("%s%s", METADATA_HEADER, $k);
  1147. if (!array_key_exists($key, $hdrs)) {
  1148. if (strlen($k) > 128 || strlen($v) > 256) {
  1149. $this->error_str = "Metadata key or value exceeds ";
  1150. $this->error_str .= "maximum length: ($k: $v)";
  1151. return 0;
  1152. }
  1153. $hdrs[] = sprintf("%s%s: %s", METADATA_HEADER, $k, trim($v));
  1154. }
  1155. }
  1156. return $hdrs;
  1157. }
  1158. private function _send_request($conn_type, $url_path, $hdrs=NULL, $method="GET")
  1159. {
  1160. $this->_init($conn_type);
  1161. $this->_reset_callback_vars();
  1162. $headers = $this->_make_headers($hdrs);
  1163. if (gettype($this->connections[$conn_type]) == "unknown type")
  1164. throw new ConnectionNotOpenException (
  1165. "Connection is not open."
  1166. );
  1167. switch ($method) {
  1168. case "DELETE":
  1169. curl_setopt($this->connections[$conn_type],
  1170. CURLOPT_CUSTOMREQUEST, "DELETE");
  1171. break;
  1172. case "POST":
  1173. curl_setopt($this->connections[$conn_type],
  1174. CURLOPT_CUSTOMREQUEST, "POST");
  1175. default:
  1176. break;
  1177. }
  1178. curl_setopt($this->connections[$conn_type],
  1179. CURLOPT_HTTPHEADER, $headers);
  1180. curl_setopt($this->connections[$conn_type],
  1181. CURLOPT_URL, $url_path);
  1182. if (!curl_exec($this->connections[$conn_type]) && curl_errno($this->connections[$conn_type]) !== 0) {
  1183. $this->error_str = "(curl error: "
  1184. . curl_errno($this->connections[$conn_type]) . ") ";
  1185. $this->error_str .= curl_error($this->connections[$conn_type]);
  1186. return False;
  1187. }
  1188. return curl_getinfo($this->connections[$conn_type], CURLINFO_HTTP_CODE);
  1189. }
  1190. function close()
  1191. {
  1192. foreach ($this->connections as $cnx) {
  1193. if (isset($cnx)) {
  1194. curl_close($cnx);
  1195. $this->connections[$cnx] = NULL;
  1196. }
  1197. }
  1198. }
  1199. private function create_array()
  1200. {
  1201. $this->_text_list = explode("\n",rtrim($this->_return_list,"\n\x0B"));
  1202. return True;
  1203. }
  1204. }
  1205. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  1206. /*
  1207. * Local variables:
  1208. * tab-width: 4
  1209. * c-basic-offset: 4
  1210. * c-hanging-comment-ender-p: nil
  1211. * End:
  1212. */
  1213. ?>