/** * Attempt to turn a relative URI into an absolute URI */ protected function _absolutiseUri($link, $uri = null) { if (!Uri\Url::validate($link)) { if ($uri !== null) { $uri = new Uri\Url($uri); if ($link[0] !== '/') { $link = $uri->getPath() . '/' . $link; } $link = $uri->getScheme() . '://' . $uri->getHost() . '/' . $this->_canonicalizePath($link); if (!URI\URL::validate($link)) { $link = null; } } } return $link; }
/** * Get a specific cookie according to a URI and name * * @param \Zend\Uri\Url|string $uri The uri (domain and path) to match * @param string $cookie_name The cookie's name * @param int $ret_as Whether to return cookies as objects of \Zend\Http\Cookie or as strings * @return \Zend\Http\Cookie|string */ public function getCookie($uri, $cookie_name, $ret_as = self::COOKIE_OBJECT) { if (is_string($uri)) { $uri = new Uri\Url($uri); } if (! $uri instanceof Uri\Url) { throw new Exception\InvalidArgumentException('Invalid URI specified'); } $host = $uri->getHost(); if (empty($host)) { throw new Exception\InvalidArgumentException('Invalid URI specified; host missing'); } // Get correct cookie path $path = $uri->getPath(); $path = substr($path, 0, strrpos($path, '/')); if (! $path) $path = '/'; if (isset($this->cookies[$uri->getHost()][$path][$cookie_name])) { $cookie = $this->cookies[$uri->getHost()][$path][$cookie_name]; switch ($ret_as) { case self::COOKIE_OBJECT: return $cookie; break; case self::COOKIE_STRING_ARRAY: case self::COOKIE_STRING_CONCAT: return $cookie->__toString(); break; default: throw new Exception\InvalidArgumentException("Invalid value passed for \$ret_as: {$ret_as}"); break; } } else { return false; } }
/** * Ensures that successive slashes are considered valid * * @return void */ public function testSuccessiveSlashes() { $url = new Url('http://example.com/foo//bar/baz//fob/'); $this->assertTrue($url->isValid()); $this->assertEquals('/foo//bar/baz//fob/', $url->getPath()); }
/** * Generate a new Cookie object from a cookie string * (for example the value of the Set-Cookie HTTP header) * * @param string $cookieStr * @param \Zend\Uri\Url|string $refUri Reference URI for default values (domain, path) * @param boolean $encodeValue Weither or not the cookie's value should be * passed through urlencode/urldecode * @return \Zend\Http\Cookie A new \Zend\Http\Cookie object or false on failure. */ public static function fromString($cookieStr, $refUri = null, $encodeValue = true) { // Set default values if (is_string($refUri)) { $refUri = new Uri\Url($refUri); } $name = ''; $value = ''; $domain = ''; $path = ''; $expires = null; $secure = false; $parts = explode(';', $cookieStr); // If first part does not include '=', fail if (strpos($parts[0], '=') === false) { return false; } // Get the name and value of the cookie list($name, $value) = explode('=', trim(array_shift($parts)), 2); $name = trim($name); if ($encodeValue) { $value = urldecode(trim($value)); } // Set default domain and path if ($refUri instanceof Uri\Url) { $domain = $refUri->getHost(); $path = $refUri->getPath(); $path = substr($path, 0, strrpos($path, '/')); } // Set other cookie parameters foreach ($parts as $part) { $part = trim($part); if (strtolower($part) == 'secure') { $secure = true; continue; } $keyValue = explode('=', $part, 2); if (count($keyValue) == 2) { list($k, $v) = $keyValue; switch (strtolower($k)) { case 'expires': if (($expires = strtotime($v)) === false) { /** * The expiration is past Tue, 19 Jan 2038 03:14:07 UTC * the maximum for 32-bit signed integer. Zend_Date * can get around that limit. */ $expireDate = new \Zend\Date\Date($v); $expires = $expireDate->getTimestamp(); } break; case 'path': $path = $v; break; case 'domain': $domain = $v; break; default: break; } } } if ($name !== '') { $ret = new self($name, $value, $domain, $expires, $path, $secure); $ret->encodeValue = $encodeValue ? true : false; return $ret; } else { return false; } }
/** * Send request to the remote server * * @param string $method * @param \Zend\Uri\Url $uri * @param string $http_ver * @param array $headers * @param string $body * @return string Request as string */ public function write($method, $uri, $http_ver = '1.1', $headers = array(), $body = '') { $host = $uri->getHost(); $host = (strtolower($uri->getScheme()) == 'https' ? 'sslv2://' . $host : $host); // Build request headers $path = $uri->getPath(); if (empty($path)) { $path = '/'; } if ($uri->getQuery()) $path .= '?' . $uri->getQuery(); $request = "{$method} {$path} HTTP/{$http_ver}\r\n"; foreach ($headers as $k => $v) { if (is_string($k)) $v = ucfirst($k) . ": $v"; $request .= "$v\r\n"; } // Add the request body $request .= "\r\n" . $body; // Do nothing - just return the request as string return $request; }
/** * Send request to the remote server * * @param string $method * @param \Zend\Uri\Url $uri * @param string $http_ver * @param array $headers * @param string $body * @return string Request as string */ public function write($method, $uri, $http_ver = '1.1', $headers = array(), $body = '') { // Make sure we're properly connected if (!$this->socket) { throw new Exception('Trying to write but we are not connected'); } $host = $uri->getHost(); $host = (strtolower($uri->getScheme()) == 'https' ? $this->config['ssltransport'] : 'tcp') . '://' . $host; if ($this->connected_to[0] != $host || $this->connected_to[1] != $uri->getPort()) { throw new Exception('Trying to write but we are connected to the wrong host'); } // Save request method for later $this->method = $method; // Build request headers $path = $uri->getPath(); if ($uri->getQuery()) { $path .= '?' . $uri->getQuery(); } $request = "{$method} {$path} HTTP/{$http_ver}\r\n"; foreach ($headers as $k => $v) { if (is_string($k)) { $v = ucfirst($k) . ": {$v}"; } $request .= "{$v}\r\n"; } if (is_resource($body)) { $request .= "\r\n"; } else { // Add the request body $request .= "\r\n" . $body; } // Send the request if (!@fwrite($this->socket, $request)) { throw new Exception('Error writing request to server'); } if (is_resource($body)) { if (stream_copy_to_stream($body, $this->socket) == 0) { throw new Exception('Error writing request to server'); } } return $request; }
/** * Constructor * * If a $uri is passed, the object will attempt to populate itself using * that information. * * @param string|\Zend\Uri\Uri $uri * @return void * @throws \Zend\Controller\Request\Exception when invalid URI passed */ public function __construct($uri = null) { if (null !== $uri) { if (!$uri instanceof Uri\Url) { $uri = new Uri\Url($uri); } if ($uri->isValid()) { $path = $uri->getPath(); $query = $uri->getQuery(); if (!empty($query)) { $path .= '?' . $query; } $this->setRequestUri($path); } else { throw new Exception('Invalid URI provided to constructor'); } } else { $this->setRequestUri(); } }
/** * Send the HTTP request and return an HTTP response object * * @param string $method * @return \Zend\Http\Response * @throws \Zend\Http\Client\Exception */ public function request($method = null) { if (!$this->uri instanceof Uri\Url) { throw new Client\Exception('No valid URI has been passed to the client'); } if ($method) { $this->setMethod($method); } $this->redirectCounter = 0; $response = null; // Make sure the adapter is loaded if ($this->adapter == null) { $this->setAdapter($this->config['adapter']); } // Send the first request. If redirected, continue. do { // Clone the URI and add the additional GET parameters to it $uri = clone $this->uri; if (!empty($this->paramsGet)) { $query = $uri->getQuery(); if (!empty($query)) { $query .= '&'; } $query .= http_build_query($this->paramsGet, null, '&'); $uri->setQuery($query); } $body = $this->_prepareBody(); $headers = $this->_prepareHeaders(); // check that adapter supports streaming before using it if (is_resource($body) && !$this->adapter instanceof Client\Adapter\Stream) { throw new Client\Exception('Adapter does not support streaming'); } // Open the connection, send the request and read the response $this->adapter->connect($uri->getHost(), $uri->getPort(), $uri->getScheme() == 'https' ? true : false); if ($this->config['output_stream']) { if ($this->adapter instanceof Client\Adapter\Stream) { $stream = $this->_openTempStream(); $this->adapter->setOutputStream($stream); } else { throw new Client\Exception('Adapter does not support streaming'); } } $this->last_request = $this->adapter->write($this->method, $uri, $this->config['httpversion'], $headers, $body); $response = $this->adapter->read(); if (!$response) { throw new Client\Exception('Unable to read response, or response is empty'); } if ($this->config['output_stream']) { rewind($stream); // cleanup the adapter $this->adapter->setOutputStream(null); $response = Response\Stream::fromStream($response, $stream); $response->setStreamName($this->_stream_name); if (!is_string($this->config['output_stream'])) { // we used temp name, will need to clean up $response->setCleanup(true); } } else { $response = Response::fromString($response); } if ($this->config['storeresponse']) { $this->last_response = $response; } // Load cookies into cookie jar if (isset($this->cookiejar)) { $this->cookiejar->addCookiesFromResponse($response, $uri); } // If we got redirected, look for the Location header if ($response->isRedirect() && ($location = $response->getHeader('location'))) { // Check whether we send the exact same request again, or drop the parameters // and send a GET request if ($response->getStatus() == 303 || !$this->config['strictredirects'] && ($response->getStatus() == 302 || $response->getStatus() == 301)) { $this->resetParameters(); $this->setMethod(self::GET); } // If we got a well formed absolute URI $url = new Uri\Url($location); if ($url->isValid()) { $this->setHeaders('host', null); $this->setUri($location); } else { // Split into path and query and set the query if (strpos($location, '?') !== false) { list($location, $query) = explode('?', $location, 2); } else { $query = ''; } $this->uri->setQuery($query); // Else, if we got just an absolute path, set it if (strpos($location, '/') === 0) { $this->uri->setPath($location); // Else, assume we have a relative path } else { // Get the current path directory, removing any trailing slashes $path = $this->uri->getPath(); $path = rtrim(substr($path, 0, strrpos($path, '/')), "/"); $this->uri->setPath($path . '/' . $location); } } ++$this->redirectCounter; } else { // If we didn't get any location, stop redirecting break; } } while ($this->redirectCounter < $this->config['maxredirects']); return $response; }