Permalink
Browse files

Changing `\action\Request` to extend `\net\http\Request`, and overrid…

…ing `to()` method to correct how URLs are generated. Adding documentation. Fixes #336.
  • Loading branch information...
1 parent 8f1d9dc commit 621ef25877cfefa88fa971c3518bef211bf212a1 @nateabele nateabele committed Apr 17, 2011
@@ -25,7 +25,7 @@
* @see lithium\net\http\Route
* @see lithium\action\Request::__get()
*/
-class Request extends \lithium\net\http\Message {
+class Request extends \lithium\net\http\Request {
/**
* Current url of request.
@@ -501,9 +501,8 @@ public function detect($flag, $detector = null) {
* @param string $default Default URL to use if HTTP_REFERER cannot be read from headers.
* @param boolean $local If true, restrict referring URLs to local server.
* @return string Referring URL.
- * @todo Rewrite me to remove constant dependencies.
*/
- function referer($default = null, $local = false) {
+ public function referer($default = null, $local = false) {
if ($ref = $this->env('HTTP_REFERER')) {
if (!$local) {
return $ref;
@@ -516,6 +515,26 @@ function referer($default = null, $local = false) {
}
/**
+ * Overrides `lithium\net\http\Request::to()` to provide the correct options for generating
+ * URLs. For information about this method, see the parent implementation.
+ *
+ * @see lithium\net\http\Request::to()
+ * @param string $format The format to convert to.
+ * @param array $options Override options.
+ * @return mixed The return value type depends on `$format`.
+ */
+ public function to($format, array $options = array()) {
+ $defaults = array(
+ 'scheme' => $this->env('HTTPS') ? 'https' : 'http',
+ 'host' => $this->env('HTTP_HOST'),
+ 'path' => $this->_base . $this->url,
+ 'query' => $this->query
+ );
+ $options += $defaults;
+ return parent::to($format, $options);
+ }
+
+ /**
* @todo Replace string directory names with configuration.
* @return void
*/
@@ -8,6 +8,9 @@
namespace lithium\net;
+use ReflectionClass;
+use ReflectionProperty;
+
/**
* Base message class for any URI based request/response.
* @see http://tools.ietf.org/html/rfc3986#section-1.1.1
@@ -117,8 +120,9 @@ public function to($format, array $options = array()) {
switch ($format) {
case 'array':
$array = array();
- $r = new \ReflectionClass(get_class($this));
- foreach ($r->getProperties(\ReflectionProperty::IS_PUBLIC) as $prop) {
+ $class = new ReflectionClass(get_class($this));
+
+ foreach ($class->getProperties(ReflectionProperty::IS_PUBLIC) as $prop) {
$array[$prop->getName()] = $prop->getValue($this);
}
return $array;
@@ -121,31 +121,68 @@ public function queryString($params = array(), $format = "{:key}={:value}&") {
/**
* Converts the data in the record set to a different format, i.e. an array. Available
- * options: array, url, context, or string.
+ * options: array, URL, stream context configuration, or string.
*
- * @param string $format Format to convert to.
- * @param array $options
- * @return mixed
+ * @see lithium\net\Message::to()
+ * @param string $format Format to convert to. Should be either `'url'`, which returns a string
+ * representation of the URL that this request points to, or `'context'`, which
+ * returns an array usable with PHP's `stream_context_create()` function. For
+ * more available formats, see the parent method, `lithium\net\Message::to()`.
+ * @param array $options Allows overriding of specific portions of the URL, as follows. These
+ * options should only be specified if you intend to replace the values that are
+ * already in the `Request` object.
+ * - `'scheme'` _string_: The protocol scheme of the URL.
+ * - `'method'` _string_: If applicable, the HTTP method to use in the request.
+ * Mainly applies to the `'context'` format.
+ * - `'host'` _string_: The host name the request is pointing at.
+ * - `'port'` _string_: The host port, if any. If specified, should be prefixed
+ * with `':'`.
+ * - `'path'` _string_: The URL path.
+ * - `'query'` _mixed_: The query string of the URL as a string or array. If passed
+ * as a string, should be prefixed with `'?'`.
+ * - `'auth'` _string_: Authentication information. See the constructor for
+ * details.
+ * - `'content'` _string_: The body of the request.
+ * - `'headers'` _array_: The request headers.
+ * - `'version'` _string_: The HTTP version of the request, where applicable.
+ * @return mixed Varies; see the `$format` parameter for possible return values.
*/
public function to($format, array $options = array()) {
+ $defaults = array(
+ 'method' => $this->method,
+ 'scheme' => $this->scheme,
+ 'host' => $this->host,
+ 'port' => $this->port ? ":{$this->port}" : '',
+ 'path' => $this->path,
+ 'query' => $this->queryString(),
+ 'auth' => $this->_config['auth'],
+ 'content' => $this->body(),
+ 'headers' => $this->headers(),
+ 'version' => $this->version,
+ );
+ $options += $defaults;
+
+ if ($options['query'] && is_array($options['query'])) {
+ $options['query'] = $this->queryString($options['query']);
+ }
+
switch ($format) {
case 'url':
- $query = $this->queryString();
- $host = $this->host . ($this->port ? ":{$this->port}" : '');
- return "{$this->scheme}://{$host}{$this->path}{$query}";
+ return String::insert("{:scheme}://{:host}{:port}{:path}{:query}", $options);
case 'context':
- if ($this->_config['auth']) {
+ if ($options['auth']) {
$auth = base64_encode("{$this->username}:{$this->password}");
- $this->headers('Authorization', "{$this->_config['auth']} {$auth}");
+ $this->headers('Authorization', "{$options['auth']} {$auth}");
}
- $content = $this->body();
- $this->headers('Content-Length', strlen($content));
- $defaults = array(
- 'method' => $this->method,
- 'header' => $this->headers(), 'content' => $content,
- 'protocol_version' => $this->version, 'ignore_errors' => true
+ $this->headers('Content-Length', strlen($options['content']));
+ $base = array(
+ 'content' => $options['content'],
+ 'method' => $options['method'],
+ 'header' => $options['headers'],
+ 'protocol_version' => $options['version'],
+ 'ignore_errors' => true
);
- return array('http' => $options + $defaults);
+ return array('http' => array_diff_key($options, $defaults) + $base);
default:
return parent::to($format, $options);
}
@@ -940,6 +940,21 @@ public function testAcceptSingleContentType() {
$this->assertEqual(array('text/html'), $request->accepts(true));
$this->assertEqual('html', $request->accepts());
}
+
+ /**
+ * Tests that `action\Request` correctly inherits the functionality of the `to()` method
+ * inherited from `lithium\net\http\Request`.
+ */
+ public function testConvertToUrl() {
+ $request = new Request(array(
+ 'env' => array('HTTP_HOST' => 'foo.com', 'HTTPS' => 'on'),
+ 'base' => '/the/base/path',
+ 'url' => '/the/url',
+ 'query' => array('some' => 'query', 'parameter' => 'values')
+ ));
+ $expected = 'https://foo.com/the/base/path/the/url?some=query&parameter=values';
+ $this->assertEqual($expected, $request->to('url'));
+ }
}
?>

0 comments on commit 621ef25

Please sign in to comment.