Merge branch '2.2' into 2.3

* 2.2:
  fixed Client when using the terminable event
  Fix problem with Windows file links (backslash in JavaScript string)
  [Security] fixed wrong phpdoc
  [Routing] removed extra argument
  [HttpFoundation] Header `HTTP_X_FORWARDED_PROTO` can contain various values Some proxies use `ssl` instead of `https`, as well as Lighttpd mod_proxy allows value chaining (`https, http`, where `https` is always first when request is encrypted).
  Added doc comments

Conflicts:
	src/Symfony/Component/HttpFoundation/Request.php
This commit is contained in:
Fabien Potencier 2013-09-29 21:41:41 +02:00
commit bc256f9da4
24 changed files with 117 additions and 20 deletions

View File

@ -160,7 +160,7 @@ class Client extends BaseClient
$profilerCode = '$kernel->getContainer()->get(\'profiler\')->enable();';
}
return <<<EOF
$code = <<<EOF
<?php
if ('$autoloader') {
@ -171,7 +171,10 @@ require_once '$path';
\$kernel = unserialize('$kernel');
\$kernel->boot();
$profilerCode
echo serialize(\$kernel->handle(unserialize('$request')));
\$request = unserialize('$request');
EOF;
return $code.$this->getHandleScript();
}
}

View File

@ -5,7 +5,7 @@
{% if collector.controller.class is defined %}
{% set link = collector.controller.file|file_link(collector.controller.line) %}
<span class="sf-toolbar-info-class sf-toolbar-info-with-next-pointer">{{ collector.controller.class|abbr_class }}</span>
<span class="sf-toolbar-info-method" onclick="{% if link %}window.location='{{link}}';window.event.stopPropagation();return false;{% endif %}">
<span class="sf-toolbar-info-method" onclick="{% if link %}window.location='{{link|e('js')}}';window.event.stopPropagation();return false;{% endif %}">
{{ collector.controller.method }}
</span>
{% else %}

View File

@ -1084,7 +1084,7 @@ class Request
public function isSecure()
{
if (self::$trustedProxies && self::$trustedHeaders[self::HEADER_CLIENT_PROTO] && $proto = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PROTO])) {
return in_array(strtolower($proto), array('https', 'on', '1'));
return in_array(strtolower(current(explode(',', $proto))), array('https', 'on', 'ssl', '1'));
}
return 'on' == strtolower($this->server->get('HTTPS')) || 1 == $this->server->get('HTTPS');

View File

@ -1420,6 +1420,13 @@ class RequestTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(443, $request->getPort());
$this->assertTrue($request->isSecure());
// check various X_FORWARDED_PROTO header values
$request->headers->set('X_FORWARDED_PROTO', 'ssl');
$this->assertTrue($request->isSecure());
$request->headers->set('X_FORWARDED_PROTO', 'https, http');
$this->assertTrue($request->isSecure());
// custom header names
Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, 'X_MY_FOR');
Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, 'X_MY_HOST');

View File

@ -104,7 +104,7 @@ class Client extends BaseClient
$requirePath = str_replace("'", "\\'", $r->getFileName());
$symfonyPath = str_replace("'", "\\'", realpath(__DIR__.'/../../..'));
return <<<EOF
$code = <<<EOF
<?php
require_once '$requirePath';
@ -114,7 +114,22 @@ require_once '$requirePath';
\$loader->register();
\$kernel = unserialize('$kernel');
echo serialize(\$kernel->handle(unserialize('$request')));
\$request = unserialize('$request');
EOF;
return $code.$this->getHandleScript();
}
protected function getHandleScript()
{
return <<<'EOF'
$response = $kernel->handle($request);
if ($kernel instanceof Symfony\Component\HttpKernel\TerminableInterface) {
$kernel->terminate($request, $response);
}
echo serialize($response);
EOF;
}

View File

@ -232,7 +232,7 @@ class Router implements RouterInterface
$class = $this->options['matcher_cache_class'];
$cache = new ConfigCache($this->options['cache_dir'].'/'.$class.'.php', $this->options['debug']);
if (!$cache->isFresh($class)) {
if (!$cache->isFresh()) {
$dumper = new $this->options['matcher_dumper_class']($this->getRouteCollection());
$options = array(
@ -264,7 +264,7 @@ class Router implements RouterInterface
} else {
$class = $this->options['generator_cache_class'];
$cache = new ConfigCache($this->options['cache_dir'].'/'.$class.'.php', $this->options['debug']);
if (!$cache->isFresh($class)) {
if (!$cache->isFresh()) {
$dumper = new $this->options['generator_dumper_class']($this->getRouteCollection());
$options = array(

View File

@ -36,6 +36,9 @@ class AccessMap implements AccessMapInterface
$this->map[] = array($requestMatcher, $roles, $channel);
}
/**
* {@inheritDoc}
*/
public function getPatterns(Request $request)
{
foreach ($this->map as $elements) {

View File

@ -64,7 +64,7 @@ class DefaultAuthenticationFailureHandler implements AuthenticationFailureHandle
{
if ($failureUrl = $request->get($this->options['failure_path_parameter'], null, true)) {
$this->options['failure_path'] = $failureUrl;
}
}
if (null === $this->options['failure_path']) {
$this->options['failure_path'] = $this->options['login_path'];

View File

@ -12,6 +12,7 @@
namespace Symfony\Component\Security\Http\Authorization;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\HttpFoundation\Response;

View File

@ -30,6 +30,9 @@ class BasicAuthenticationEntryPoint implements AuthenticationEntryPointInterface
$this->realmName = $realmName;
}
/**
* {@inheritdoc}
*/
public function start(Request $request, AuthenticationException $authException = null)
{
$response = new Response();

View File

@ -38,6 +38,9 @@ class DigestAuthenticationEntryPoint implements AuthenticationEntryPointInterfac
$this->logger = $logger;
}
/**
* {@inheritdoc}
*/
public function start(Request $request, AuthenticationException $authException = null)
{
$expiryTime = microtime(true) + $this->nonceValiditySeconds * 1000;
@ -62,11 +65,17 @@ class DigestAuthenticationEntryPoint implements AuthenticationEntryPointInterfac
return $response;
}
/**
* @return string
*/
public function getKey()
{
return $this->key;
}
/**
* @return string
*/
public function getRealmName()
{
return $this->realmName;

View File

@ -30,7 +30,7 @@ class FormAuthenticationEntryPoint implements AuthenticationEntryPointInterface
private $httpUtils;
/**
* Constructor
* Constructor.
*
* @param HttpKernelInterface $kernel
* @param HttpUtils $httpUtils An HttpUtils instance

View File

@ -34,6 +34,9 @@ class RetryAuthenticationEntryPoint implements AuthenticationEntryPointInterface
$this->httpsPort = $httpsPort;
}
/**
* {@inheritdoc}
*/
public function start(Request $request, AuthenticationException $authException = null)
{
$scheme = $request->isSecure() ? 'http' : 'https';

View File

@ -15,10 +15,14 @@ use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
/**
* InteractiveLoginEvent
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class InteractiveLoginEvent extends Event
{
private $request;
private $authenticationToken;
/**

View File

@ -15,10 +15,14 @@ use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\EventDispatcher\Event;
/**
* SwitchUserEvent
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class SwitchUserEvent extends Event
{
private $request;
private $targetUser;
public function __construct(Request $request, UserInterface $targetUser)
@ -27,11 +31,17 @@ class SwitchUserEvent extends Event
$this->targetUser = $targetUser;
}
/**
* @return Request
*/
public function getRequest()
{
return $this->request;
}
/**
* @return UserInterface
*/
public function getTargetUser()
{
return $this->targetUser;

View File

@ -71,6 +71,9 @@ class Firewall implements EventSubscriberInterface
}
}
/**
* {@inheritDoc}
*/
public static function getSubscribedEvents()
{
return array(KernelEvents::REQUEST => array('onKernelRequest', 8));

View File

@ -161,6 +161,13 @@ class ExceptionListener
$event->setResponse($response);
}
/**
* @param Request $request
* @param AuthenticationException $authException
*
* @return Response
* @throws AuthenticationException
*/
private function startAuthentication(Request $request, AuthenticationException $authException)
{
if (null === $this->authenticationEntryPoint) {
@ -181,6 +188,9 @@ class ExceptionListener
return $this->authenticationEntryPoint->start($request, $authException);
}
/**
* @param Request $request
*/
protected function setTargetPath(Request $request)
{
// session isn't required when using http basic authentication mechanism for example

View File

@ -37,7 +37,7 @@ class LogoutListener implements ListenerInterface
private $csrfProvider;
/**
* Constructor
* Constructor.
*
* @param SecurityContextInterface $securityContext
* @param HttpUtils $httpUtils An HttpUtilsInterface instance
@ -77,9 +77,8 @@ class LogoutListener implements ListenerInterface
*
* @param GetResponseEvent $event A GetResponseEvent instance
*
* @throws InvalidCsrfTokenException if the CSRF token is invalid
* @throws LogoutException if the CSRF token is invalid
* @throws \RuntimeException if the LogoutSuccessHandlerInterface instance does not return a response
* @throws LogoutException
*/
public function handle(GetResponseEvent $event)
{

View File

@ -35,7 +35,7 @@ class RememberMeListener implements ListenerInterface
private $dispatcher;
/**
* Constructor
* Constructor.
*
* @param SecurityContextInterface $securityContext
* @param RememberMeServicesInterface $rememberMeServices

View File

@ -36,6 +36,9 @@ class X509AuthenticationListener extends AbstractPreAuthenticatedListener
$this->credentialKey = $credentialKey;
}
/**
* {@inheritdoc}
*/
protected function getPreAuthenticatedData(Request $request)
{
if (!$request->server->has($this->userKey)) {

View File

@ -25,11 +25,19 @@ class FirewallMap implements FirewallMapInterface
{
private $map = array();
/**
* @param RequestMatcherInterface $requestMatcher
* @param array $listeners
* @param ExceptionListener $exceptionListener
*/
public function add(RequestMatcherInterface $requestMatcher = null, array $listeners = array(), ExceptionListener $exceptionListener = null)
{
$this->map[] = array($requestMatcher, $listeners, $exceptionListener);
}
/**
* {@inheritDoc}
*/
public function getListeners(Request $request)
{
foreach ($this->map as $elements) {

View File

@ -20,7 +20,6 @@ use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component\HttpFoundation\Response;
/**
* Encapsulates the logic needed to create sub-requests, redirect the user, and match URLs.
@ -37,6 +36,8 @@ class HttpUtils
*
* @param UrlGeneratorInterface $urlGenerator A UrlGeneratorInterface instance
* @param UrlMatcherInterface|RequestMatcherInterface $urlMatcher The Url or Request matcher
*
* @throws \InvalidArgumentException
*/
public function __construct(UrlGeneratorInterface $urlGenerator = null, $urlMatcher = null)
{
@ -54,7 +55,7 @@ class HttpUtils
* @param string $path A path (an absolute path (/foo), an absolute URL (http://...), or a route name (foo))
* @param integer $status The status code
*
* @return Response A RedirectResponse instance
* @return RedirectResponse A RedirectResponse instance
*/
public function createRedirectResponse(Request $request, $path, $status = 302)
{
@ -123,9 +124,11 @@ class HttpUtils
* Generates a URI, based on the given path or absolute URL.
*
* @param Request $request A Request instance
* @param string $path A path (an absolute path (/foo), an absolute URL (http://...), or a route name (foo))
* @param string $path A path (an absolute path (/foo), an absolute URL (http://...), or a route name (foo))
*
* @return string An absolute URL
*
* @throws \LogicException
*/
public function generateUri($request, $path)
{

View File

@ -40,7 +40,7 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
private $userProviders;
/**
* Constructor
* Constructor.
*
* @param array $userProviders
* @param string $key
@ -80,6 +80,9 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
return $this->options['remember_me_parameter'];
}
/**
* @return string
*/
public function getKey()
{
return $this->key;
@ -94,6 +97,7 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
* @return TokenInterface|null
*
* @throws CookieTheftException
* @throws \RuntimeException
*/
final public function autoLogin(Request $request)
{
@ -219,6 +223,9 @@ abstract class AbstractRememberMeServices implements RememberMeServicesInterface
*/
abstract protected function processAutoLoginCookie(array $cookieParts, Request $request);
/**
* @param Request $request
*/
protected function onLoginFail(Request $request)
{
}

View File

@ -22,6 +22,9 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface;
*/
class ResponseListener implements EventSubscriberInterface
{
/**
* @param FilterResponseEvent $event
*/
public function onKernelResponse(FilterResponseEvent $event)
{
$request = $event->getRequest();
@ -32,6 +35,9 @@ class ResponseListener implements EventSubscriberInterface
}
}
/**
* {@inheritDoc}
*/
public static function getSubscribedEvents()
{
return array(KernelEvents::RESPONSE => 'onKernelResponse');