Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Client.php
Go to the documentation of this file.
1 <?php
2 
27 #require_once 'Zend/Loader.php';
28 
29 
33 #require_once 'Zend/Uri.php';
34 
35 
39 #require_once 'Zend/Http/Client/Adapter/Interface.php';
40 
41 
45 #require_once 'Zend/Http/Header/HeaderValue.php';
46 
47 
51 #require_once 'Zend/Http/Response.php';
52 
56 #require_once 'Zend/Http/Response/Stream.php';
57 
73 {
77  const GET = 'GET';
78  const POST = 'POST';
79  const PUT = 'PUT';
80  const HEAD = 'HEAD';
81  const DELETE = 'DELETE';
82  const TRACE = 'TRACE';
83  const OPTIONS = 'OPTIONS';
84  const CONNECT = 'CONNECT';
85  const MERGE = 'MERGE';
86  const PATCH = 'PATCH';
87 
91  const AUTH_BASIC = 'basic';
92  //const AUTH_DIGEST = 'digest'; <-- not implemented yet
93 
97  const HTTP_1 = '1.1';
98  const HTTP_0 = '1.0';
99 
103  const CONTENT_TYPE = 'Content-Type';
104  const CONTENT_LENGTH = 'Content-Length';
105 
109  const ENC_URLENCODED = 'application/x-www-form-urlencoded';
110  const ENC_FORMDATA = 'multipart/form-data';
111 
115  const VTYPE_SCALAR = 'SCALAR';
116  const VTYPE_FILE = 'FILE';
117 
123  protected $config = array(
124  'maxredirects' => 5,
125  'strictredirects' => false,
126  'useragent' => 'Zend_Http_Client',
127  'timeout' => 10,
128  'adapter' => 'Zend_Http_Client_Adapter_Socket',
129  'httpversion' => self::HTTP_1,
130  'keepalive' => false,
131  'storeresponse' => true,
132  'strict' => true,
133  'output_stream' => false,
134  'encodecookies' => true,
135  'rfc3986_strict' => false
136  );
137 
143  protected $adapter = null;
144 
150  protected $uri = null;
151 
157  protected $headers = array();
158 
164  protected $method = self::GET;
165 
171  protected $paramsGet = array();
172 
178  protected $paramsPost = array();
179 
185  protected $enctype = null;
186 
192  protected $raw_post_data = null;
193 
206  protected $auth;
207 
216  protected $files = array();
217 
226  protected $body_field_order = array();
227 
233  protected $cookiejar = null;
234 
240  protected $last_request = null;
241 
247  protected $last_response = null;
248 
254  protected $redirectCounter = 0;
255 
261  protected $_unmaskStatus = false;
262 
268  protected $_queryBracketsEscaped = true;
269 
278  protected static $_fileInfoDb = null;
279 
287  public function __construct($uri = null, $config = null)
288  {
289  if ($uri !== null) {
290  $this->setUri($uri);
291  }
292  if ($config !== null) {
293  $this->setConfig($config);
294  }
295 
296  $this->_queryBracketsEscaped = version_compare(phpversion(), '5.1.3', '>=');
297  }
298 
306  public function setUri($uri)
307  {
308  if ($uri instanceof Zend_Uri_Http) {
309  // clone the URI in order to keep the passed parameter constant
310  $uri = clone $uri;
311  } elseif (is_string($uri)) {
313  }
314 
315  if (!$uri instanceof Zend_Uri_Http) {
317  #require_once 'Zend/Http/Client/Exception.php';
318  throw new Zend_Http_Client_Exception('Passed parameter is not a valid HTTP URI.');
319  }
320 
321  // Set auth if username and password has been specified in the uri
322  if ($uri->getUsername() && $uri->getPassword()) {
323  $this->setAuth($uri->getUsername(), $uri->getPassword());
324  }
325 
326  // We have no ports, set the defaults
327  if (! $uri->getPort()) {
328  $uri->setPort(($uri->getScheme() == 'https' ? 443 : 80));
329  }
330 
331  $this->uri = $uri;
332 
333  return $this;
334  }
335 
342  public function getUri($as_string = false)
343  {
344  if ($as_string && $this->uri instanceof Zend_Uri_Http) {
345  return $this->uri->__toString();
346  } else {
347  return $this->uri;
348  }
349  }
350 
358  public function setConfig($config = array())
359  {
360  if ($config instanceof Zend_Config) {
361  $config = $config->toArray();
362 
363  } elseif (! is_array($config)) {
365  #require_once 'Zend/Http/Client/Exception.php';
366  throw new Zend_Http_Client_Exception('Array or Zend_Config object expected, got ' . gettype($config));
367  }
368 
369  foreach ($config as $k => $v) {
370  $this->config[strtolower($k)] = $v;
371  }
372 
373  // Pass configuration options to the adapter if it exists
374  if ($this->adapter instanceof Zend_Http_Client_Adapter_Interface) {
375  $this->adapter->setConfig($config);
376  }
377 
378  return $this;
379  }
380 
392  public function setMethod($method = self::GET)
393  {
394  if (! preg_match('/^[^\x00-\x1f\x7f-\xff\(\)<>@,;:\\\\"\/\[\]\?={}\s]+$/', $method)) {
395  #require_once 'Zend/Http/Client/Exception.php';
396  throw new Zend_Http_Client_Exception("'{$method}' is not a valid HTTP request method.");
397  }
398 
399  if (($method == self::POST
400  || $method == self::PUT
401  || $method == self::DELETE
402  || $method == self::PATCH
403  || $method == self::OPTIONS)
404  && $this->enctype === null
405  ) {
406  $this->setEncType(self::ENC_URLENCODED);
407  }
408 
409  $this->method = $method;
410 
411  return $this;
412  }
413 
433  public function setHeaders($name, $value = null)
434  {
435  // If we got an array, go recursive!
436  if (is_array($name)) {
437  foreach ($name as $k => $v) {
438  if (is_string($k)) {
439  $this->setHeaders($k, $v);
440  continue;
441  }
442  $this->setHeaders($v, null);
443  }
444  return $this;
445  }
446 
447  // Check if $name needs to be split
448  if ($value === null && (strpos($name, ':') > 0)) {
449  list($name, $value) = explode(':', $name, 2);
450  }
451 
452  // Make sure the name is valid if we are in strict mode
453  if ($this->config['strict'] && (! preg_match('/^[a-zA-Z0-9-]+$/', $name))) {
454  #require_once 'Zend/Http/Client/Exception.php';
455  throw new Zend_Http_Client_Exception("{$name} is not a valid HTTP header name");
456  }
457 
458  $normalized_name = strtolower($name);
459 
460  // If $value is null or false, unset the header
461  if ($value === null || $value === false) {
462  unset($this->headers[$normalized_name]);
463  return $this;
464  }
465 
466  // Validate value
468 
469  // Header names are stored lowercase internally.
470  if (is_string($value)) {
471  $value = trim($value);
472  }
473  $this->headers[$normalized_name] = array($name, $value);
474 
475  return $this;
476  }
477 
487  public function getHeader($key)
488  {
489  $key = strtolower($key);
490  if (isset($this->headers[$key])) {
491  return $this->headers[$key][1];
492  } else {
493  return null;
494  }
495  }
496 
504  public function setParameterGet($name, $value = null)
505  {
506  if (is_array($name)) {
507  foreach ($name as $k => $v)
508  $this->_setParameter('GET', $k, $v);
509  } else {
510  $this->_setParameter('GET', $name, $value);
511  }
512 
513  return $this;
514  }
515 
523  public function setParameterPost($name, $value = null)
524  {
525  if (is_array($name)) {
526  foreach ($name as $k => $v)
527  $this->_setParameter('POST', $k, $v);
528  } else {
529  $this->_setParameter('POST', $name, $value);
530  }
531 
532  return $this;
533  }
534 
543  protected function _setParameter($type, $name, $value)
544  {
545  $parray = array();
546  $type = strtolower($type);
547  switch ($type) {
548  case 'get':
549  $parray = &$this->paramsGet;
550  break;
551  case 'post':
552  $parray = &$this->paramsPost;
553  if ( $value === null ) {
554  if (isset($this->body_field_order[$name]))
555  unset($this->body_field_order[$name]);
556  } else {
557  $this->body_field_order[$name] = self::VTYPE_SCALAR;
558  }
559  break;
560  }
561 
562  if ($value === null) {
563  if (isset($parray[$name])) unset($parray[$name]);
564  } else {
565  $parray[$name] = $value;
566  }
567  }
568 
574  public function getRedirectionsCount()
575  {
576  return $this->redirectCounter;
577  }
578 
602  public function setAuth($user, $password = '', $type = self::AUTH_BASIC)
603  {
604  // If we got false or null, disable authentication
605  if ($user === false || $user === null) {
606  $this->auth = null;
607 
608  // Clear the auth information in the uri instance as well
609  if ($this->uri instanceof Zend_Uri_Http) {
610  $this->getUri()->setUsername('');
611  $this->getUri()->setPassword('');
612  }
613  // Else, set up authentication
614  } else {
615  // Check we got a proper authentication type
616  if (! defined('self::AUTH_' . strtoupper($type))) {
618  #require_once 'Zend/Http/Client/Exception.php';
619  throw new Zend_Http_Client_Exception("Invalid or not supported authentication type: '$type'");
620  }
621 
622  $this->auth = array(
623  'user' => (string) $user,
624  'password' => (string) $password,
625  'type' => $type
626  );
627  }
628 
629  return $this;
630  }
631 
642  public function setCookieJar($cookiejar = true)
643  {
644  Zend_Loader::loadClass('Zend_Http_CookieJar');
645 
646  if ($cookiejar instanceof Zend_Http_CookieJar) {
647  $this->cookiejar = $cookiejar;
648  } elseif ($cookiejar === true) {
649  $this->cookiejar = new Zend_Http_CookieJar();
650  } elseif (! $cookiejar) {
651  $this->cookiejar = null;
652  } else {
654  #require_once 'Zend/Http/Client/Exception.php';
655  throw new Zend_Http_Client_Exception('Invalid parameter type passed as CookieJar');
656  }
657 
658  return $this;
659  }
660 
666  public function getCookieJar()
667  {
668  return $this->cookiejar;
669  }
670 
680  public function setCookie($cookie, $value = null)
681  {
682  Zend_Loader::loadClass('Zend_Http_Cookie');
683 
684  if (is_array($cookie)) {
685  foreach ($cookie as $c => $v) {
686  if (is_string($c)) {
687  $this->setCookie($c, $v);
688  } else {
689  $this->setCookie($v);
690  }
691  }
692 
693  return $this;
694  }
695 
696  if ($value !== null && $this->config['encodecookies']) {
697  $value = urlencode($value);
698  }
699 
700  if (isset($this->cookiejar)) {
701  if ($cookie instanceof Zend_Http_Cookie) {
702  $this->cookiejar->addCookie($cookie);
703  } elseif (is_string($cookie) && $value !== null) {
704  $cookie = Zend_Http_Cookie::fromString("{$cookie}={$value}",
705  $this->uri,
706  $this->config['encodecookies']);
707  $this->cookiejar->addCookie($cookie);
708  }
709  } else {
710  if ($cookie instanceof Zend_Http_Cookie) {
711  $name = $cookie->getName();
712  $value = $cookie->getValue();
713  $cookie = $name;
714  }
715 
716  if (preg_match("/[=,; \t\r\n\013\014]/", $cookie)) {
718  #require_once 'Zend/Http/Client/Exception.php';
719  throw new Zend_Http_Client_Exception("Cookie name cannot contain these characters: =,; \t\r\n\013\014 ({$cookie})");
720  }
721 
722  $value = addslashes($value);
723 
724  if (! isset($this->headers['cookie'])) {
725  $this->headers['cookie'] = array('Cookie', '');
726  }
727  $this->headers['cookie'][1] .= $cookie . '=' . $value . '; ';
728  }
729 
730  return $this;
731  }
732 
753  public function setFileUpload($filename, $formname, $data = null, $ctype = null)
754  {
755  if ($data === null) {
756  if (($data = @file_get_contents($filename)) === false) {
758  #require_once 'Zend/Http/Client/Exception.php';
759  throw new Zend_Http_Client_Exception("Unable to read file '{$filename}' for upload");
760  }
761 
762  if (! $ctype) {
763  $ctype = $this->_detectFileMimeType($filename);
764  }
765  }
766 
767  // Force enctype to multipart/form-data
768  $this->setEncType(self::ENC_FORMDATA);
769 
770  $this->files[] = array(
771  'formname' => $formname,
772  'filename' => basename($filename),
773  'ctype' => $ctype,
774  'data' => $data
775  );
776 
777  $this->body_field_order[$formname] = self::VTYPE_FILE;
778 
779  return $this;
780  }
781 
788  public function setEncType($enctype = self::ENC_URLENCODED)
789  {
790  $this->enctype = $enctype;
791 
792  return $this;
793  }
794 
809  public function setRawData($data, $enctype = null)
810  {
811  $this->raw_post_data = $data;
812  $this->setEncType($enctype);
813  if (is_resource($data)) {
814  // We've got stream data
815  $stat = @fstat($data);
816  if($stat) {
817  $this->setHeaders(self::CONTENT_LENGTH, $stat['size']);
818  }
819  }
820  return $this;
821  }
822 
836  public function setUnmaskStatus($status = true)
837  {
838  $this->_unmaskStatus = (BOOL)$status;
839  return $this;
840  }
841 
847  public function getUnmaskStatus()
848  {
849  return $this->_unmaskStatus;
850  }
851 
864  public function resetParameters($clearAll = false)
865  {
866  // Reset parameter data
867  $this->paramsGet = array();
868  $this->paramsPost = array();
869  $this->files = array();
870  $this->raw_post_data = null;
871  $this->enctype = null;
872 
873  if($clearAll) {
874  $this->headers = array();
875  $this->last_request = null;
876  $this->last_response = null;
877  } else {
878  // Clear outdated headers
879  if (isset($this->headers[strtolower(self::CONTENT_TYPE)])) {
880  unset($this->headers[strtolower(self::CONTENT_TYPE)]);
881  }
882  if (isset($this->headers[strtolower(self::CONTENT_LENGTH)])) {
883  unset($this->headers[strtolower(self::CONTENT_LENGTH)]);
884  }
885  }
886 
887  return $this;
888  }
889 
895  public function getLastRequest()
896  {
897  return $this->last_request;
898  }
899 
908  public function getLastResponse()
909  {
910  return $this->last_response;
911  }
912 
923  public function setAdapter($adapter)
924  {
925  if (is_string($adapter)) {
926  try {
928  } catch (Zend_Exception $e) {
930  #require_once 'Zend/Http/Client/Exception.php';
931  throw new Zend_Http_Client_Exception("Unable to load adapter '$adapter': {$e->getMessage()}", 0, $e);
932  }
933 
934  $adapter = new $adapter;
935  }
936 
937  if (! $adapter instanceof Zend_Http_Client_Adapter_Interface) {
939  #require_once 'Zend/Http/Client/Exception.php';
940  throw new Zend_Http_Client_Exception('Passed adapter is not a HTTP connection adapter');
941  }
942 
943  $this->adapter = $adapter;
945  unset($config['adapter']);
946  $this->adapter->setConfig($config);
947  }
948 
954  public function getAdapter()
955  {
956  if (null === $this->adapter) {
957  $this->setAdapter($this->config['adapter']);
958  }
959 
960  return $this->adapter;
961  }
962 
969  public function setStream($streamfile = true)
970  {
971  $this->setConfig(array("output_stream" => $streamfile));
972  return $this;
973  }
974 
979  public function getStream()
980  {
981  return $this->config["output_stream"];
982  }
983 
989  protected function _openTempStream()
990  {
991  $this->_stream_name = $this->config['output_stream'];
992  if(!is_string($this->_stream_name)) {
993  // If name is not given, create temp name
994  $this->_stream_name = tempnam(isset($this->config['stream_tmp_dir'])?$this->config['stream_tmp_dir']:sys_get_temp_dir(),
995  'Zend_Http_Client');
996  }
997 
998  if (false === ($fp = @fopen($this->_stream_name, "w+b"))) {
999  if ($this->adapter instanceof Zend_Http_Client_Adapter_Interface) {
1000  $this->adapter->close();
1001  }
1002  #require_once 'Zend/Http/Client/Exception.php';
1003  throw new Zend_Http_Client_Exception("Could not open temp file {$this->_stream_name}");
1004  }
1005 
1006  return $fp;
1007  }
1008 
1016  public function request($method = null)
1017  {
1018  if (! $this->uri instanceof Zend_Uri_Http) {
1020  #require_once 'Zend/Http/Client/Exception.php';
1021  throw new Zend_Http_Client_Exception('No valid URI has been passed to the client');
1022  }
1023 
1024  if ($method) {
1025  $this->setMethod($method);
1026  }
1027  $this->redirectCounter = 0;
1028  $response = null;
1029 
1030  // Make sure the adapter is loaded
1031  if ($this->adapter == null) {
1032  $this->setAdapter($this->config['adapter']);
1033  }
1034 
1035  // Send the first request. If redirected, continue.
1036  do {
1037  // Clone the URI and add the additional GET parameters to it
1038  $uri = clone $this->uri;
1039  if (! empty($this->paramsGet)) {
1040  $query = $uri->getQuery();
1041  if (! empty($query)) {
1042  $query .= '&';
1043  }
1044  $query .= http_build_query($this->paramsGet, null, '&');
1045  if ($this->config['rfc3986_strict']) {
1046  $query = str_replace('+', '%20', $query);
1047  }
1048 
1049  // @see ZF-11671 to unmask for some services to foo=val1&foo=val2
1050  if ($this->getUnmaskStatus()) {
1051  if ($this->_queryBracketsEscaped) {
1052  $query = preg_replace('/%5B(?:[0-9]|[1-9][0-9]+)%5D=/', '=', $query);
1053  } else {
1054  $query = preg_replace('/\\[(?:[0-9]|[1-9][0-9]+)\\]=/', '=', $query);
1055  }
1056  }
1057 
1058  $uri->setQuery($query);
1059  }
1060 
1061  $body = $this->_prepareBody();
1062  $headers = $this->_prepareHeaders();
1063 
1064  // check that adapter supports streaming before using it
1065  if(is_resource($body) && !($this->adapter instanceof Zend_Http_Client_Adapter_Stream)) {
1067  #require_once 'Zend/Http/Client/Exception.php';
1068  throw new Zend_Http_Client_Exception('Adapter does not support streaming');
1069  }
1070 
1071  // Open the connection, send the request and read the response
1072  $this->adapter->connect($uri->getHost(), $uri->getPort(),
1073  ($uri->getScheme() == 'https' ? true : false));
1074 
1075  if($this->config['output_stream']) {
1076  if($this->adapter instanceof Zend_Http_Client_Adapter_Stream) {
1077  $stream = $this->_openTempStream();
1078  $this->adapter->setOutputStream($stream);
1079  } else {
1081  #require_once 'Zend/Http/Client/Exception.php';
1082  throw new Zend_Http_Client_Exception('Adapter does not support streaming');
1083  }
1084  }
1085 
1086  $this->last_request = $this->adapter->write($this->method,
1087  $uri, $this->config['httpversion'], $headers, $body);
1088 
1089  $response = $this->adapter->read();
1090  if (! $response) {
1092  #require_once 'Zend/Http/Client/Exception.php';
1093  throw new Zend_Http_Client_Exception('Unable to read response, or response is empty');
1094  }
1095 
1096  if($this->config['output_stream']) {
1097  $streamMetaData = stream_get_meta_data($stream);
1098  if ($streamMetaData['seekable']) {
1099  rewind($stream);
1100  }
1101  // cleanup the adapter
1102  $this->adapter->setOutputStream(null);
1104  $response->setStreamName($this->_stream_name);
1105  if(!is_string($this->config['output_stream'])) {
1106  // we used temp name, will need to clean up
1107  $response->setCleanup(true);
1108  }
1109  } else {
1111  }
1112 
1113  if ($this->config['storeresponse']) {
1114  $this->last_response = $response;
1115  }
1116 
1117  // Load cookies into cookie jar
1118  if (isset($this->cookiejar)) {
1119  $this->cookiejar->addCookiesFromResponse($response, $uri, $this->config['encodecookies']);
1120  }
1121 
1122  // If we got redirected, look for the Location header
1123  if ($response->isRedirect() && ($location = $response->getHeader('location'))) {
1124 
1125  // Avoid problems with buggy servers that add whitespace at the
1126  // end of some headers (See ZF-11283)
1127  $location = trim($location);
1128 
1129  // Check whether we send the exact same request again, or drop the parameters
1130  // and send a GET request
1131  if ($response->getStatus() == 303 ||
1132  ((! $this->config['strictredirects']) && ($response->getStatus() == 302 ||
1133  $response->getStatus() == 301))) {
1134 
1135  $this->resetParameters();
1136  $this->setMethod(self::GET);
1137  }
1138 
1139  // If we got a well formed absolute URI
1140  if (($scheme = substr($location, 0, 6)) && ($scheme == 'http:/' || $scheme == 'https:')) {
1141  $this->setHeaders('host', null);
1142  $this->setUri($location);
1143 
1144  } else {
1145 
1146  // Split into path and query and set the query
1147  if (strpos($location, '?') !== false) {
1148  list($location, $query) = explode('?', $location, 2);
1149  } else {
1150  $query = '';
1151  }
1152  $this->uri->setQuery($query);
1153 
1154  // Else, if we got just an absolute path, set it
1155  if(strpos($location, '/') === 0) {
1156  $this->uri->setPath($location);
1157 
1158  // Else, assume we have a relative path
1159  } else {
1160  // Get the current path directory, removing any trailing slashes
1161  $path = $this->uri->getPath();
1162  $path = rtrim(substr($path, 0, strrpos($path, '/')), "/");
1163  $this->uri->setPath($path . '/' . $location);
1164  }
1165  }
1167 
1168  } else {
1169  // If we didn't get any location, stop redirecting
1170  break;
1171  }
1172 
1173  } while ($this->redirectCounter < $this->config['maxredirects']);
1174 
1175  return $response;
1176  }
1177 
1183  protected function _prepareHeaders()
1184  {
1185  $headers = array();
1186 
1187  // Set the host header
1188  if (! isset($this->headers['host'])) {
1189  $host = $this->uri->getHost();
1190 
1191  // If the port is not default, add it
1192  if (! (($this->uri->getScheme() == 'http' && $this->uri->getPort() == 80) ||
1193  ($this->uri->getScheme() == 'https' && $this->uri->getPort() == 443))) {
1194  $host .= ':' . $this->uri->getPort();
1195  }
1196 
1197  $headers[] = "Host: {$host}";
1198  }
1199 
1200  // Set the connection header
1201  if (! isset($this->headers['connection'])) {
1202  if (! $this->config['keepalive']) {
1203  $headers[] = "Connection: close";
1204  }
1205  }
1206 
1207  // Set the Accept-encoding header if not set - depending on whether
1208  // zlib is available or not.
1209  if (! isset($this->headers['accept-encoding'])) {
1210  if (function_exists('gzinflate')) {
1211  $headers[] = 'Accept-encoding: gzip, deflate';
1212  } else {
1213  $headers[] = 'Accept-encoding: identity';
1214  }
1215  }
1216 
1217  // Set the Content-Type header
1218  if (($this->method == self::POST || $this->method == self::PUT) &&
1219  (! isset($this->headers[strtolower(self::CONTENT_TYPE)]) && isset($this->enctype))) {
1220 
1221  $headers[] = self::CONTENT_TYPE . ': ' . $this->enctype;
1222  }
1223 
1224  // Set the user agent header
1225  if (! isset($this->headers['user-agent']) && isset($this->config['useragent'])) {
1226  $headers[] = "User-Agent: {$this->config['useragent']}";
1227  }
1228 
1229  // Set HTTP authentication if needed
1230  if (is_array($this->auth)) {
1231  $auth = self::encodeAuthHeader($this->auth['user'], $this->auth['password'], $this->auth['type']);
1232  $headers[] = "Authorization: {$auth}";
1233  }
1234 
1235  // Load cookies from cookie jar
1236  if (isset($this->cookiejar)) {
1237  $cookstr = $this->cookiejar->getMatchingCookies($this->uri,
1239 
1240  if ($cookstr) {
1241  $headers[] = "Cookie: {$cookstr}";
1242  }
1243  }
1244 
1245  // Add all other user defined headers
1246  foreach ($this->headers as $header) {
1247  list($name, $value) = $header;
1248  if (is_array($value)) {
1249  $value = implode(', ', $value);
1250  }
1251 
1252  $headers[] = "$name: $value";
1253  }
1254 
1255  return $headers;
1256  }
1257 
1264  protected function _prepareBody()
1265  {
1266  // According to RFC2616, a TRACE request should not have a body.
1267  if ($this->method == self::TRACE) {
1268  return '';
1269  }
1270 
1271  if (isset($this->raw_post_data) && is_resource($this->raw_post_data)) {
1272  return $this->raw_post_data;
1273  }
1274  // If mbstring overloads substr and strlen functions, we have to
1275  // override it's internal encoding
1276  if (function_exists('mb_internal_encoding') &&
1277  ((int) ini_get('mbstring.func_overload')) & 2) {
1278 
1279  $mbIntEnc = mb_internal_encoding();
1280  mb_internal_encoding('ASCII');
1281  }
1282 
1283  // If we have raw_post_data set, just use it as the body.
1284  if (isset($this->raw_post_data)) {
1285  $this->setHeaders(self::CONTENT_LENGTH, strlen($this->raw_post_data));
1286  if (isset($mbIntEnc)) {
1287  mb_internal_encoding($mbIntEnc);
1288  }
1289 
1290  return $this->raw_post_data;
1291  }
1292 
1293  $body = '';
1294 
1295  // If we have files to upload, force enctype to multipart/form-data
1296  if (count ($this->files) > 0) {
1297  $this->setEncType(self::ENC_FORMDATA);
1298  }
1299 
1300  // If we have POST parameters or files, encode and add them to the body
1301  if (count($this->paramsPost) > 0 || count($this->files) > 0) {
1302  switch($this->enctype) {
1303  case self::ENC_FORMDATA:
1304  // Encode body as multipart/form-data
1305  $boundary = '---ZENDHTTPCLIENT-' . md5(microtime());
1306  $this->setHeaders(self::CONTENT_TYPE, self::ENC_FORMDATA . "; boundary={$boundary}");
1307 
1308  // Encode all files and POST vars in the order they were given
1309  foreach ($this->body_field_order as $fieldName=>$fieldType) {
1310  switch ($fieldType) {
1311  case self::VTYPE_FILE:
1312  foreach ($this->files as $file) {
1313  if ($file['formname']===$fieldName) {
1314  $fhead = array(self::CONTENT_TYPE => $file['ctype']);
1315  $body .= self::encodeFormData($boundary, $file['formname'], $file['data'], $file['filename'], $fhead);
1316  }
1317  }
1318  break;
1319  case self::VTYPE_SCALAR:
1320  if (isset($this->paramsPost[$fieldName])) {
1321  if (is_array($this->paramsPost[$fieldName])) {
1322  $flattened = self::_flattenParametersArray($this->paramsPost[$fieldName], $fieldName);
1323  foreach ($flattened as $pp) {
1324  $body .= self::encodeFormData($boundary, $pp[0], $pp[1]);
1325  }
1326  } else {
1327  $body .= self::encodeFormData($boundary, $fieldName, $this->paramsPost[$fieldName]);
1328  }
1329  }
1330  break;
1331  }
1332  }
1333 
1334  $body .= "--{$boundary}--\r\n";
1335  break;
1336 
1337  case self::ENC_URLENCODED:
1338  // Encode body as application/x-www-form-urlencoded
1339  $this->setHeaders(self::CONTENT_TYPE, self::ENC_URLENCODED);
1340  $body = http_build_query($this->paramsPost, '', '&');
1341  break;
1342 
1343  default:
1344  if (isset($mbIntEnc)) {
1345  mb_internal_encoding($mbIntEnc);
1346  }
1347 
1349  #require_once 'Zend/Http/Client/Exception.php';
1350  throw new Zend_Http_Client_Exception("Cannot handle content type '{$this->enctype}' automatically." .
1351  " Please use Zend_Http_Client::setRawData to send this kind of content.");
1352  break;
1353  }
1354  }
1355 
1356  // Set the Content-Length if we have a body or if request is POST/PUT
1357  if ($body || $this->method == self::POST || $this->method == self::PUT) {
1358  $this->setHeaders(self::CONTENT_LENGTH, strlen($body));
1359  }
1360 
1361  if (isset($mbIntEnc)) {
1362  mb_internal_encoding($mbIntEnc);
1363  }
1364 
1365  return $body;
1366  }
1367 
1385  protected function _getParametersRecursive($parray, $urlencode = false)
1386  {
1387  // Issue a deprecated notice
1388  trigger_error("The " . __METHOD__ . " method is deprecated and will be dropped in 2.0.",
1389  E_USER_NOTICE);
1390 
1391  if (! is_array($parray)) {
1392  return $parray;
1393  }
1394  $parameters = array();
1395 
1396  foreach ($parray as $name => $value) {
1397  if ($urlencode) {
1398  $name = urlencode($name);
1399  }
1400 
1401  // If $value is an array, iterate over it
1402  if (is_array($value)) {
1403  $name .= ($urlencode ? '%5B%5D' : '[]');
1404  foreach ($value as $subval) {
1405  if ($urlencode) {
1406  $subval = urlencode($subval);
1407  }
1408  $parameters[] = array($name, $subval);
1409  }
1410  } else {
1411  if ($urlencode) {
1412  $value = urlencode($value);
1413  }
1414  $parameters[] = array($name, $value);
1415  }
1416  }
1417 
1418  return $parameters;
1419  }
1420 
1435  protected function _detectFileMimeType($file)
1436  {
1437  $type = null;
1438 
1439  // First try with fileinfo functions
1440  if (function_exists('finfo_open')) {
1441  if (self::$_fileInfoDb === null) {
1442  self::$_fileInfoDb = @finfo_open(FILEINFO_MIME);
1443  }
1444 
1445  if (self::$_fileInfoDb) {
1446  $type = finfo_file(self::$_fileInfoDb, $file);
1447  }
1448 
1449  } elseif (function_exists('mime_content_type')) {
1450  $type = mime_content_type($file);
1451  }
1452 
1453  // Fallback to the default application/octet-stream
1454  if (! $type) {
1455  $type = 'application/octet-stream';
1456  }
1457 
1458  return $type;
1459  }
1460 
1471  public static function encodeFormData($boundary, $name, $value, $filename = null, $headers = array())
1472  {
1473  $ret = "--{$boundary}\r\n" .
1474  'Content-Disposition: form-data; name="' . $name .'"';
1475 
1476  if ($filename) {
1477  $ret .= '; filename="' . $filename . '"';
1478  }
1479  $ret .= "\r\n";
1480 
1481  foreach ($headers as $hname => $hvalue) {
1482  $ret .= "{$hname}: {$hvalue}\r\n";
1483  }
1484  $ret .= "\r\n";
1485 
1486  $ret .= "{$value}\r\n";
1487 
1488  return $ret;
1489  }
1490 
1502  public static function encodeAuthHeader($user, $password, $type = self::AUTH_BASIC)
1503  {
1504  $authHeader = null;
1505 
1506  switch ($type) {
1507  case self::AUTH_BASIC:
1508  // In basic authentication, the user name cannot contain ":"
1509  if (strpos($user, ':') !== false) {
1511  #require_once 'Zend/Http/Client/Exception.php';
1512  throw new Zend_Http_Client_Exception("The user name cannot contain ':' in 'Basic' HTTP authentication");
1513  }
1514 
1515  $authHeader = 'Basic ' . base64_encode($user . ':' . $password);
1516  break;
1517 
1518  //case self::AUTH_DIGEST:
1522  // break;
1523 
1524  default:
1526  #require_once 'Zend/Http/Client/Exception.php';
1527  throw new Zend_Http_Client_Exception("Not a supported HTTP authentication type: '$type'");
1528  }
1529 
1530  return $authHeader;
1531  }
1532 
1547  protected static function _flattenParametersArray($parray, $prefix = null)
1548  {
1549  if (! is_array($parray)) {
1550  return $parray;
1551  }
1552 
1553  $parameters = array();
1554 
1555  foreach($parray as $name => $value) {
1556 
1557  // Calculate array key
1558  if ($prefix) {
1559  if (is_int($name)) {
1560  $key = $prefix . '[]';
1561  } else {
1562  $key = $prefix . "[$name]";
1563  }
1564  } else {
1565  $key = $name;
1566  }
1567 
1568  if (is_array($value)) {
1569  $parameters = array_merge($parameters, self::_flattenParametersArray($value, $key));
1570 
1571  } else {
1572  $parameters[] = array($key, $value);
1573  }
1574  }
1575 
1576  return $parameters;
1577  }
1578 
1586  protected function _validateHeaderValue($value, $recurse = true)
1587  {
1588  if (is_array($value) && $recurse) {
1589  foreach ($value as $v) {
1590  $this->_validateHeaderValue($v, false);
1591  }
1592  return;
1593  }
1594 
1595  // Cast integers and floats to strings for purposes of header representation.
1596  if (is_int($value) || is_float($value)) {
1597  $value = (string) $value;
1598  }
1599 
1600  if (! is_string($value) && (! is_object($value) || ! method_exists($value, '__toString'))) {
1601  #require_once 'Zend/Http/Exception.php';
1602  throw new Zend_Http_Exception('Invalid header value detected');
1603  }
1604 
1606  }
1607 }
getUri($as_string=false)
Definition: Client.php:342
request($method=null)
Definition: Client.php:1016
$response
Definition: 404.php:11
static fromStream($response_str, $stream)
Definition: Stream.php:156
const VTYPE_SCALAR
Definition: Client.php:115
elseif(isset( $params[ 'redirect_parent']))
Definition: iframe.phtml:17
setFileUpload($filename, $formname, $data=null, $ctype=null)
Definition: Client.php:753
static loadClass($class, $dirs=null)
Definition: Loader.php:52
setHeaders($name, $value=null)
Definition: Client.php:433
_detectFileMimeType($file)
Definition: Client.php:1435
setCookie($cookie, $value=null)
Definition: Client.php:680
const ENC_URLENCODED
Definition: Client.php:109
static factory($uri='http', $className=null)
Definition: Uri.php:96
setParameterPost($name, $value=null)
Definition: Client.php:523
_setParameter($type, $name, $value)
Definition: Client.php:543
const AUTH_BASIC
Definition: Client.php:91
setRawData($data, $enctype=null)
Definition: Client.php:809
setConfig($config=array())
Definition: Client.php:358
static encodeFormData($boundary, $name, $value, $filename=null, $headers=array())
Definition: Client.php:1471
const CONTENT_TYPE
Definition: Client.php:103
static fromString($response_str)
Definition: Response.php:693
const HTTP_0
Definition: Client.php:98
$type
Definition: item.phtml:13
setEncType($enctype=self::ENC_URLENCODED)
Definition: Client.php:788
setStream($streamfile=true)
Definition: Client.php:969
static _flattenParametersArray($parray, $prefix=null)
Definition: Client.php:1547
$prefix
Definition: name.phtml:25
$value
Definition: gender.phtml:16
$user
Definition: dummy_user.php:13
const HTTP_1
Definition: Client.php:97
setUnmaskStatus($status=true)
Definition: Client.php:836
$status
Definition: order_status.php:8
setMethod($method=self::GET)
Definition: Client.php:392
const ENC_FORMDATA
Definition: Client.php:110
_getParametersRecursive($parray, $urlencode=false)
Definition: Client.php:1385
setCookieJar($cookiejar=true)
Definition: Client.php:642
getRedirectionsCount()
Definition: Client.php:574
setAdapter($adapter)
Definition: Client.php:923
const OPTIONS
Definition: Client.php:83
static encodeAuthHeader($user, $password, $type=self::AUTH_BASIC)
Definition: Client.php:1502
const CONTENT_LENGTH
Definition: Client.php:104
__construct($uri=null, $config=null)
Definition: Client.php:287
const DELETE
Definition: Client.php:81
setParameterGet($name, $value=null)
Definition: Client.php:504
_validateHeaderValue($value, $recurse=true)
Definition: Client.php:1586
const VTYPE_FILE
Definition: Client.php:116
resetParameters($clearAll=false)
Definition: Client.php:864
const CONNECT
Definition: Client.php:84
static $_fileInfoDb
Definition: Client.php:278
setAuth($user, $password='', $type=self::AUTH_BASIC)
Definition: Client.php:602
getHeader($key)
Definition: Client.php:487
if(!isset($_GET['name'])) $name
Definition: log.php:14