diff --git a/composer.lock b/composer.lock
index a406a5d..922f725 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,10 +4,53 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "hash": "dac77f10c1f7585fd1f7344c6a376338",
-    "content-hash": "73cbcb262208c5d802cb528279f2a95c",
+    "hash": "bc5342cdc5fafb76287d4c8bbe657cb3",
+    "content-hash": "debc103be6ccb0ebd9b1acc3fd0d63b2",
     "packages": [
         {
+            "name": "asm89/stack-cors",
+            "version": "0.2.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/asm89/stack-cors.git",
+                "reference": "2d77e77251a434e4527315313a672f5801b29fa2"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/asm89/stack-cors/zipball/2d77e77251a434e4527315313a672f5801b29fa2",
+                "reference": "2d77e77251a434e4527315313a672f5801b29fa2",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.2",
+                "symfony/http-foundation": "~2.1",
+                "symfony/http-kernel": "~2.1"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-0": {
+                    "Asm89\\Stack": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Alexander",
+                    "email": "iam.asm89@gmail.com"
+                }
+            ],
+            "description": "Cross-origin resource sharing library and stack middleware",
+            "homepage": "https://github.com/asm89/stack-cors",
+            "keywords": [
+                "cors",
+                "stack"
+            ],
+            "time": "2014-07-28 07:22:35"
+        },
+        {
             "name": "composer/installers",
             "version": "v1.0.21",
             "source": {
@@ -2578,7 +2621,7 @@
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/jcalderonzumba/gastonjs/zipball/5e231b4df98275c404e1371fc5fadd34f6a121ad",
+                "url": "https://api.github.com/repos/jcalderonzumba/gastonjs/zipball/21bebb8ca03eb0f93ec2f3fad61192fb079e2622",
                 "reference": "5e231b4df98275c404e1371fc5fadd34f6a121ad",
                 "shasum": ""
             },
diff --git a/core/composer.json b/core/composer.json
index 1eabf49..55bbb49 100644
--- a/core/composer.json
+++ b/core/composer.json
@@ -29,6 +29,7 @@
     "masterminds/html5": "~2.1",
     "symfony/psr-http-message-bridge": "v0.2",
     "zendframework/zend-diactoros": "~1.1",
+    "asm89/stack-cors": "~0.2",
     "composer/semver": "~1.0"
   },
   "require-dev": {
diff --git a/core/core.services.yml b/core/core.services.yml
index afccb31..2eec9ae 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -33,6 +33,14 @@ parameters:
     - sftp
     - webcal
     - rtsp
+  cors.config:
+    enabled: false
+    allowedHeaders: []
+    allowedMethods: []
+    allowedOrigins: ['*']
+    exposedHeaders: false
+    maxAge: false
+    supportsCredentials: false
 services:
   # Simple cache contexts, directly derived from the request context.
   cache_context.ip:
@@ -689,6 +697,11 @@ services:
       - { name: http_middleware, priority: 50 }
     calls:
       - [setContainer, ['@service_container']]
+  http_middleware.cors:
+     class: Asm89\Stack\Cors
+     arguments: ['%cors.config%']
+     tags:
+       - { name: http_middleware }
   psr7.http_foundation_factory:
     class: Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory
   psr7.http_message_factory:
diff --git a/core/lib/Drupal/Core/CoreServiceProvider.php b/core/lib/Drupal/Core/CoreServiceProvider.php
index 82e8bd5..6f32adc 100644
--- a/core/lib/Drupal/Core/CoreServiceProvider.php
+++ b/core/lib/Drupal/Core/CoreServiceProvider.php
@@ -10,6 +10,7 @@
 use Drupal\Core\Cache\Context\CacheContextsPass;
 use Drupal\Core\Cache\ListCacheBinsPass;
 use Drupal\Core\DependencyInjection\Compiler\BackendCompilerPass;
+use Drupal\Core\DependencyInjection\Compiler\CorsCompilerPass;
 use Drupal\Core\DependencyInjection\Compiler\GuzzleMiddlewarePass;
 use Drupal\Core\DependencyInjection\Compiler\ContextProvidersPass;
 use Drupal\Core\DependencyInjection\Compiler\ProxyServicesPass;
@@ -68,6 +69,8 @@ public function register(ContainerBuilder $container) {
 
     $container->addCompilerPass(new BackendCompilerPass());
 
+    $container->addCompilerPass(new CorsCompilerPass());
+
     $container->addCompilerPass(new StackedKernelPass());
 
     $container->addCompilerPass(new StackedSessionHandlerPass());
diff --git a/core/lib/Drupal/Core/DependencyInjection/Compiler/CorsCompilerPass.php b/core/lib/Drupal/Core/DependencyInjection/Compiler/CorsCompilerPass.php
new file mode 100644
index 0000000..3c66ad6
--- /dev/null
+++ b/core/lib/Drupal/Core/DependencyInjection/Compiler/CorsCompilerPass.php
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\DependencyInjection\Compiler\CorsCompilerPass.
+ */
+
+namespace Drupal\Core\DependencyInjection\Compiler;
+
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+
+/**
+ * Provides a compiler pass which disables the CORS middleware in case disabled.
+ *
+ * @see services.yml
+ */
+class CorsCompilerPass implements CompilerPassInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function process(ContainerBuilder $container) {
+    $enabled = FALSE;
+
+    if ($cors_config = $container->getParameter('cors.config')) {
+      $enabled = !empty($cors_config['enabled']);
+    }
+
+    // Remove the CORS middleware completly in case it was not enabled.
+    if (!$enabled) {
+      $container->removeDefinition('http_middleware.cors');
+    }
+  }
+
+}
diff --git a/core/tests/Drupal/KernelTests/Core/HttpKernel/CorsIntegrationTest.php b/core/tests/Drupal/KernelTests/Core/HttpKernel/CorsIntegrationTest.php
new file mode 100644
index 0000000..01433b6
--- /dev/null
+++ b/core/tests/Drupal/KernelTests/Core/HttpKernel/CorsIntegrationTest.php
@@ -0,0 +1,89 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\KernelTests\Core\HttpKernel\CorsIntegrationTest.
+ */
+
+namespace Drupal\KernelTests\Core\HttpKernel;
+
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\Core\DependencyInjection\ServiceModifierInterface;
+use Drupal\KernelTests\KernelTestBase;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+
+/**
+ * Tests CORS provided by Drupal.
+ *
+ * @see sites/default/default.services.yml
+ * @see \Asm89\Stack\Cors
+ * @see \Asm89\Stack\CorsService
+ *
+ * @group Http
+ */
+class CorsIntegrationTest extends KernelTestBase implements ServiceModifierInterface {
+
+  /**
+   * The cors container configuration.
+   *
+   * @var null|array
+   */
+  protected $corsConfig = NULL;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['system', 'test_page_test'];
+
+  protected function setUp() {
+    parent::setUp();
+
+    $this->installSchema('system', 'router');
+    \Drupal::service('router.builder')->rebuild();
+  }
+
+  public function testCrossSiteRequest() {
+
+    // Test default parameters.
+    $cors_config = $this->container->getParameter('cors.config');
+    $this->assertSame(FALSE, $cors_config['enabled']);
+    $this->assertSame([], $cors_config['allowedHeaders']);
+    $this->assertSame([], $cors_config['allowedMethods']);
+    $this->assertSame(['*'], $cors_config['allowedOrigins']);
+
+    $this->assertSame(FALSE, $cors_config['exposedHeaders']);
+    $this->assertSame(FALSE, $cors_config['maxAge']);
+    $this->assertSame(FALSE, $cors_config['supportsCredentials']);
+
+    // Configure the CORS stack to allow a specific set of origins, but don't
+    // specify an origin header.
+    $request = Request::create('/test-page');
+    $request->headers->set('Origin', '');
+    $cors_config['enabled'] = TRUE;
+    $cors_config['allowedOrigins'] = array('http://example.com');
+
+    $this->corsConfig = $cors_config;
+    $this->container->get('kernel')->rebuildContainer();
+
+    /** @var \Symfony\Component\HttpFoundation\Response $response */
+    $response = $this->container->get('http_kernel')->handle($request);
+    $this->assertEquals(Response::HTTP_FORBIDDEN, $response->getStatusCode());
+    $this->assertEquals('Not allowed.', $response->getContent());
+
+    // Specify a valid origin.
+    $request->headers->set('Origin', 'http://example.com');
+    $response = $this->container->get('http_kernel')->handle($request);
+    $this->assertEquals(Response::HTTP_OK, $response->getStatusCode());
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function alter(ContainerBuilder $container) {
+    if (isset($this->corsConfig)) {
+      $container->setParameter('cors.config', $this->corsConfig);
+    }
+  }
+
+}
diff --git a/sites/default/default.services.yml b/sites/default/default.services.yml
index 23f6483..511d25c 100644
--- a/sites/default/default.services.yml
+++ b/sites/default/default.services.yml
@@ -153,3 +153,19 @@ parameters:
     - sftp
     - webcal
     - rtsp
+
+   # Configure Cross-Site HTTP requests (CORS).
+   # Read https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
+   # for more information about the topic in general.
+   # Note: By default the configuration is disabled.
+   cors.config:
+     enabled: false
+     # Specify allowed headers, like 'x-allowed-header'.
+     allowedHeaders: []
+     # Specify allowed request methods, specify '*' to allow all possible ones.
+     allowedMethods: []
+     # Configure requests allowed from specific origins.
+     allowedOrigins: ['*']
+     exposedHeaders: false
+     maxAge: false
+     supportsCredentials: false
diff --git a/vendor/asm89/stack-cors/.travis.yml b/vendor/asm89/stack-cors/.travis.yml
new file mode 100644
index 0000000..ddb1058
--- /dev/null
+++ b/vendor/asm89/stack-cors/.travis.yml
@@ -0,0 +1,10 @@
+language: php
+
+php:
+  - 5.3
+  - 5.4
+  - 5.5
+
+before_script: composer install --dev
+
+script: phpunit
diff --git a/vendor/asm89/stack-cors/README.md b/vendor/asm89/stack-cors/README.md
new file mode 100644
index 0000000..dea18a8
--- /dev/null
+++ b/vendor/asm89/stack-cors/README.md
@@ -0,0 +1,59 @@
+# Stack/Cors
+
+Library and middleware enabling cross-origin resource sharing for your
+http-{foundation,kernel} using application. It attempts to implement the
+[W3C Candidate Recommendation] for cross-origin resource sharing.
+
+[W3C Candidate Recommendation]: http://www.w3.org/TR/cors/
+
+Master [![Build Status](https://secure.travis-ci.org/asm89/stack-cors.png?branch=master)](http://travis-ci.org/asm89/stack-cors)
+Develop [![Build Status](https://secure.travis-ci.org/asm89/stack-cors.png?branch=develop)](http://travis-ci.org/asm89/stack-cors)
+
+## Installation
+
+Require `asm89/stack-cors` using composer.
+
+## Usage
+
+Stack middleware:
+
+```php
+<?php
+
+use Asm89\Stack\Cors;
+
+$app = new Cors($app, array(
+    // you can use array('*') to allow any headers
+    'allowedHeaders'      => array('x-allowed-header', 'x-other-allowed-header'),
+    // you can use array('*') to allow any methods
+    'allowedMethods'      => array('DELETE', 'GET', 'POST', 'PUT'),
+    // you can use array('*') to allow requests from any origin
+    'allowedOrigins'      => array('localhost'),
+    'exposedHeaders'      => false,
+    'maxAge'              => false,
+    'supportsCredentials' => false,
+));
+```
+
+Or use the library:
+
+```php
+<?php
+
+use Asm89\Stack\CorsService;
+
+$cors = new CorsService(array(
+    'allowedHeaders'      => array('x-allowed-header', 'x-other-allowed-header'),
+    'allowedMethods'      => array('DELETE', 'GET', 'POST', 'PUT'),
+    'allowedOrigins'      => array('localhost'),
+    'exposedHeaders'      => false,
+    'maxAge'              => false,
+    'supportsCredentials' => false,
+));
+
+$cors->addActualRequestHeaders(Response $response, $origin);
+$cors->handlePreflightRequest(Request $request);
+$cors->isActualRequestAllowed(Request $request);
+$cors->isCorsRequest(Request $request);
+$cors->isPreflightRequest(Request $request);
+```
diff --git a/vendor/asm89/stack-cors/composer.json b/vendor/asm89/stack-cors/composer.json
new file mode 100644
index 0000000..f8be507
--- /dev/null
+++ b/vendor/asm89/stack-cors/composer.json
@@ -0,0 +1,22 @@
+{
+    "name": "asm89/stack-cors",
+    "description": "Cross-origin resource sharing library and stack middleware",
+    "keywords": ["stack", "cors"],
+    "homepage": "https://github.com/asm89/stack-cors",
+    "type": "library",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Alexander",
+            "email": "iam.asm89@gmail.com"
+        }
+    ],
+    "require": {
+        "php": ">=5.3.2",
+        "symfony/http-foundation": "~2.1",
+        "symfony/http-kernel": "~2.1"
+    },
+    "autoload": {
+        "psr-0": { "Asm89\\Stack": "src/" }
+    }
+}
diff --git a/vendor/asm89/stack-cors/phpunit.xml.dist b/vendor/asm89/stack-cors/phpunit.xml.dist
new file mode 100644
index 0000000..1959e53
--- /dev/null
+++ b/vendor/asm89/stack-cors/phpunit.xml.dist
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit backupGlobals="false"
+         backupStaticAttributes="false"
+         colors="true"
+         convertErrorsToExceptions="true"
+         convertNoticesToExceptions="true"
+         convertWarningsToExceptions="true"
+         processIsolation="false"
+         stopOnFailure="false"
+         syntaxCheck="false"
+         bootstrap="test/bootstrap.php"
+>
+  <testsuites>
+    <testsuite name="Stack Cors Test Suite">
+      <directory>./test/Asm89/</directory>
+    </testsuite>
+  </testsuites>
+
+  <filter>
+    <whitelist>
+      <directory suffix=".php">./src/</directory>
+    </whitelist>
+  </filter>
+
+</phpunit>
diff --git a/vendor/asm89/stack-cors/src/Asm89/Stack/Cors.php b/vendor/asm89/stack-cors/src/Asm89/Stack/Cors.php
new file mode 100755
index 0000000..a5e81ce
--- /dev/null
+++ b/vendor/asm89/stack-cors/src/Asm89/Stack/Cors.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace Asm89\Stack;
+
+use Symfony\Component\HttpKernel\HttpKernelInterface;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+
+class Cors implements HttpKernelInterface
+{
+    /**
+     * @var \Symfony\Component\HttpKernel\HttpKernelInterface
+     */
+    private $app;
+
+    /**
+     * @var \Asm89\Stack\CorsService
+     */
+    private $cors;
+
+    private $defaultOptions = array(
+        'allowedHeaders'      => array(),
+        'allowedMethods'      => array(),
+        'allowedOrigins'      => array(),
+        'exposedHeaders'      => false,
+        'maxAge'              => false,
+        'supportsCredentials' => false,
+    );
+
+    public function __construct(HttpKernelInterface $app, array $options = array())
+    {
+        $this->app  = $app;
+        $this->cors = new CorsService(array_merge($this->defaultOptions, $options));
+
+    }
+
+    public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
+    {
+        if ( ! $this->cors->isCorsRequest($request)) {
+            return $this->app->handle($request, $type, $catch);
+        }
+
+        if ($this->cors->isPreflightRequest($request)) {
+            return $this->cors->handlePreflightRequest($request);
+        }
+
+        if ( ! $this->cors->isActualRequestAllowed($request)) {
+            return new Response('Not allowed.', 403);
+        }
+
+        $response = $this->app->handle($request, $type, $catch);
+
+        return $this->cors->addActualRequestHeaders($response, $request);
+    }
+}
diff --git a/vendor/asm89/stack-cors/src/Asm89/Stack/CorsService.php b/vendor/asm89/stack-cors/src/Asm89/Stack/CorsService.php
new file mode 100755
index 0000000..339256b
--- /dev/null
+++ b/vendor/asm89/stack-cors/src/Asm89/Stack/CorsService.php
@@ -0,0 +1,178 @@
+<?php
+
+namespace Asm89\Stack;
+
+use Symfony\Component\HttpKernel\HttpKernelInterface;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+
+class CorsService
+{
+    private $options;
+
+    public function __construct(array $options = array())
+    {
+        $this->options = $this->normalizeOptions($options);
+    }
+
+    private function normalizeOptions(array $options = array())
+    {
+
+        $options += array(
+            'allowedOrigins' => array(),
+            'supportsCredentials' => false,
+            'allowedHeaders' => array(),
+            'exposedHeaders' => array(),
+            'allowedMethods' => array(),
+            'maxAge' => 0,
+        );
+
+        // normalize array('*') to true
+        if (in_array('*', $options['allowedOrigins'])) {
+          $options['allowedOrigins'] = true;
+        }
+        if (in_array('*', $options['allowedHeaders'])) {
+          $options['allowedHeaders'] = true;
+        } else {
+          $options['allowedHeaders'] = array_map('strtolower', $options['allowedHeaders']);
+        }
+
+        if (in_array('*', $options['allowedMethods'])) {
+          $options['allowedMethods'] = true;
+        } else {
+          $options['allowedMethods'] = array_map('strtoupper', $options['allowedMethods']);
+        }
+
+        return $options;
+    }
+
+    public function isActualRequestAllowed(Request $request)
+    {
+        return $this->checkOrigin($request);
+    }
+
+    public function isCorsRequest(Request $request)
+    {
+        return $request->headers->has('Origin');
+    }
+
+    public function isPreflightRequest(Request $request)
+    {
+        return $this->isCorsRequest($request)
+            &&$request->getMethod() === 'OPTIONS'
+            && $request->headers->has('Access-Control-Request-Method');
+    }
+
+    public function addActualRequestHeaders(Response $response, Request $request)
+    {
+        if ( ! $this->checkOrigin($request)) {
+            return $response;
+        }
+
+        $response->headers->set('Access-Control-Allow-Origin', $request->headers->get('Origin'));
+
+        if ( ! $response->headers->has('Vary')) {
+            $response->headers->set('Vary', 'Origin');
+        } else {
+            $response->headers->set('Vary', $response->headers->get('Vary') . ', Origin');
+        }
+
+        if ($this->options['supportsCredentials']) {
+            $response->headers->set('Access-Control-Allow-Credentials', 'true');
+        }
+
+        if ($this->options['exposedHeaders']) {
+            $response->headers->set('Access-Control-Expose-Headers', implode(', ', $this->options['exposedHeaders']));
+        }
+
+        return $response;
+    }
+
+    public function handlePreflightRequest(Request $request)
+    {
+        if (true !== $check = $this->checkPreflightRequestConditions($request)) {
+            return $check;
+        }
+
+        return $this->buildPreflightCheckResponse($request);
+    }
+
+    private function buildPreflightCheckResponse(Request $request)
+    {
+        $response = new Response();
+
+        if ($this->options['supportsCredentials']) {
+            $response->headers->set('Access-Control-Allow-Credentials', 'true');
+        }
+
+        $response->headers->set('Access-Control-Allow-Origin', $request->headers->get('Origin'));
+
+        if ($this->options['maxAge']) {
+            $response->headers->set('Access-Control-Max-Age', $this->options['maxAge']);
+        }
+
+        $allowMethods = $this->options['allowedMethods'] === true
+            ? strtoupper($request->headers->get('Access-Control-Request-Method'))
+            : implode(', ', $this->options['allowedMethods']);
+        $response->headers->set('Access-Control-Allow-Methods', $allowMethods);
+
+        $allowHeaders = $this->options['allowedHeaders'] === true
+            ? strtoupper($request->headers->get('Access-Control-Request-Headers'))
+            : implode(', ', $this->options['allowedHeaders']);
+        $response->headers->set('Access-Control-Allow-Headers', $allowHeaders);
+
+        return $response;
+    }
+
+    private function checkPreflightRequestConditions(Request $request)
+    {
+        if ( ! $this->checkOrigin($request)) {
+            return $this->createBadRequestResponse(403, 'Origin not allowed');
+        }
+
+        if ( ! $this->checkMethod($request)) {
+            return $this->createBadRequestResponse(405, 'Method not allowed');
+        }
+
+        $requestHeaders = array();
+        // if allowedHeaders has been set to true ('*' allow all flag) just skip this check
+        if ($this->options['allowedHeaders'] !== true && $request->headers->has('Access-Control-Request-Headers')) {
+            $headers        = strtolower($request->headers->get('Access-Control-Request-Headers'));
+            $requestHeaders = explode(',', $headers);
+
+            foreach ($requestHeaders as $header) {
+                if ( ! in_array(trim($header), $this->options['allowedHeaders'])) {
+                    return $this->createBadRequestResponse(403, 'Header not allowed');
+                }
+            }
+        }
+
+        return true;
+    }
+
+    private function createBadRequestResponse($code, $reason = '')
+    {
+        return new Response($reason, $code);
+    }
+
+    private function checkOrigin(Request $request) {
+        if ($this->options['allowedOrigins'] === true) {
+            // allow all '*' flag
+            return true;
+        }
+        $origin = $request->headers->get('Origin');
+
+        return in_array($origin, $this->options['allowedOrigins']);
+    }
+
+    private function checkMethod(Request $request) {
+        if ($this->options['allowedMethods'] === true) {
+            // allow all '*' flag
+            return true;
+        }
+
+        $requestMethod = strtoupper($request->headers->get('Access-Control-Request-Method'));
+        return in_array($requestMethod, $this->options['allowedMethods']);
+    }
+
+}
diff --git a/vendor/asm89/stack-cors/test/Asm89/Stack/CorsTest.php b/vendor/asm89/stack-cors/test/Asm89/Stack/CorsTest.php
new file mode 100755
index 0000000..1493c46
--- /dev/null
+++ b/vendor/asm89/stack-cors/test/Asm89/Stack/CorsTest.php
@@ -0,0 +1,395 @@
+<?php
+
+namespace Asm89\Stack;
+
+use PHPUnit_Framework_TestCase;
+use Symfony\Component\HttpKernel\HttpKernelInterface;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+
+class CorsTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @test
+     */
+    public function it_does_not_modify_on_a_request_without_origin()
+    {
+        $app                = $this->createStackedApp();
+        $unmodifiedResponse = new Response();
+
+        $response = $app->handle(new Request());
+
+        $this->assertEquals($unmodifiedResponse->headers, $response->headers);
+    }
+
+    /**
+     * @test
+     */
+    public function it_returns_403_on_valid_actual_request_with_origin_not_allowed()
+    {
+        $app      = $this->createStackedApp(array('allowedOrigins' => array('notlocalhost')));
+        $request  = $this->createValidActualRequest();
+
+        $response = $app->handle($request);
+
+        $this->assertEquals(403, $response->getStatusCode());
+    }
+
+    /**
+     * @test
+     */
+    public function it_returns_allow_origin_header_on_valid_actual_request()
+    {
+        $app      = $this->createStackedApp();
+        $request  = $this->createValidActualRequest();
+
+        $response = $app->handle($request);
+
+        $this->assertTrue($response->headers->has('Access-Control-Allow-Origin'));
+        $this->assertEquals('localhost', $response->headers->get('Access-Control-Allow-Origin'));
+    }
+
+    /**
+     * @test
+     */
+    public function it_returns_allow_origin_header_on_allow_all_origin_request()
+    {
+        $app      = $this->createStackedApp(array('allowedOrigins' => array('*')));
+        $request  = new Request();
+        $request->headers->set('Origin', 'http://localhost');
+
+        $response = $app->handle($request);
+
+        $this->assertEquals(200, $response->getStatusCode());
+        $this->assertTrue($response->headers->has('Access-Control-Allow-Origin'));
+        $this->assertEquals('http://localhost', $response->headers->get('Access-Control-Allow-Origin'));
+    }
+
+    /**
+     * @test
+     */
+    public function it_returns_allow_headers_header_on_allow_all_headers_request()
+    {
+        $app     = $this->createStackedApp(array('allowedHeaders' => array('*')));
+        $request = $this->createValidPreflightRequest();
+        $request->headers->set('Access-Control-Request-Headers', 'Foo, BAR');
+
+        $response = $app->handle($request);
+
+        $this->assertEquals(200, $response->getStatusCode());
+        $this->assertEquals('FOO, BAR', $response->headers->get('Access-Control-Allow-Headers'));
+    }
+
+    /**
+     * @test
+     */
+    public function it_does_not_return_allow_origin_header_on_valid_actual_request_with_origin_not_allowed()
+    {
+        $app      = $this->createStackedApp(array('allowedOrigins' => array('notlocalhost')));
+        $request  = $this->createValidActualRequest();
+
+        $response = $app->handle($request);
+
+        $this->assertFalse($response->headers->has('Access-Control-Allow-Origin'));
+    }
+
+    /**
+     * @test
+     */
+    public function it_sets_allow_credentials_header_when_flag_is_set_on_valid_actual_request()
+    {
+        $app     = $this->createStackedApp(array('supportsCredentials' => true));
+        $request = $this->createValidActualRequest();
+
+        $response = $app->handle($request);
+
+        $this->assertTrue($response->headers->has('Access-Control-Allow-Credentials'));
+        $this->assertEquals('true', $response->headers->get('Access-Control-Allow-Credentials'));
+    }
+
+    /**
+     * @test
+     */
+    public function it_does_not_set_allow_credentials_header_when_flag_is_not_set_on_valid_actual_request()
+    {
+        $app     = $this->createStackedApp();
+        $request = $this->createValidActualRequest();
+
+        $response = $app->handle($request);
+
+        $this->assertFalse($response->headers->has('Access-Control-Allow-Credentials'));
+    }
+
+    /**
+     * @test
+     */
+    public function it_sets_exposed_headers_when_configured_on_actual_request()
+    {
+        $app     = $this->createStackedApp(array('exposedHeaders' => array('x-exposed-header', 'x-another-exposed-header')));
+        $request = $this->createValidActualRequest();
+
+        $response = $app->handle($request);
+
+        $this->assertTrue($response->headers->has('Access-Control-Expose-Headers'));
+        $this->assertEquals('x-exposed-header, x-another-exposed-header', $response->headers->get('Access-Control-Expose-Headers'));
+    }
+
+    /**
+     * @test
+     * @see http://www.w3.org/TR/cors/index.html#resource-implementation
+     */
+    public function it_adds_a_vary_header()
+    {
+        $app      = $this->createStackedApp();
+        $request  = $this->createValidActualRequest();
+
+        $response = $app->handle($request);
+
+        $this->assertTrue($response->headers->has('Vary'));
+        $this->assertEquals('Origin', $response->headers->get('Vary'));
+    }
+
+    /**
+     * @test
+     * @see http://www.w3.org/TR/cors/index.html#resource-implementation
+     */
+    public function it_appends_an_existing_vary_header()
+    {
+        $app      = $this->createStackedApp(array(), array('Vary' => 'Content-Type'));
+        $request  = $this->createValidActualRequest();
+
+        $response = $app->handle($request);
+
+        $this->assertTrue($response->headers->has('Vary'));
+        $this->assertEquals('Content-Type, Origin', $response->headers->get('Vary'));
+    }
+
+    /**
+     * @test
+     */
+    public function it_returns_access_control_headers_on_cors_request()
+    {
+        $app      = $this->createStackedApp();
+        $request  = new Request();
+        $request->headers->set('Origin', 'localhost');
+
+        $response = $app->handle($request);
+
+        $this->assertTrue($response->headers->has('Access-Control-Allow-Origin'));
+        $this->assertEquals('localhost', $response->headers->get('Access-Control-Allow-Origin'));
+    }
+
+    /**
+     * @test
+     */
+    public function it_returns_access_control_headers_on_valid_preflight_request()
+    {
+        $app     = $this->createStackedApp();
+        $request = $this->createValidPreflightRequest();
+
+        $response = $app->handle($request);
+
+        $this->assertTrue($response->headers->has('Access-Control-Allow-Origin'));
+        $this->assertEquals('localhost', $response->headers->get('Access-Control-Allow-Origin'));
+    }
+
+    /**
+     * @test
+     */
+    public function it_returns_403_on_valid_preflight_request_with_origin_not_allowed()
+    {
+        $app     = $this->createStackedApp(array('allowedOrigins' => array('notlocalhost')));
+        $request = $this->createValidPreflightRequest();
+
+        $response = $app->handle($request);
+
+        $this->assertEquals(403, $response->getStatusCode());
+    }
+
+    /**
+     * @test
+     */
+    public function it_does_not_modify_request_with_origin_not_allowed()
+    {
+        $passedOptions = array(
+          'allowedOrigins' => array('notlocalhost'),
+        );
+
+        $service  = new CorsService($passedOptions);
+        $request  = $this->createValidActualRequest();
+        $response = new Response();
+        $service->addActualRequestHeaders($response, $request);
+
+        $this->assertEquals($response, new Response());
+    }
+
+    /**
+     * @test
+     */
+    public function it_returns_405_on_valid_preflight_request_with_method_not_allowed()
+    {
+        $app     = $this->createStackedApp(array('allowedMethods' => array('put')));
+        $request = $this->createValidPreflightRequest();
+
+        $response = $app->handle($request);
+
+        $this->assertEquals(405, $response->getStatusCode());
+    }
+
+    /**
+     * @test
+     */
+    public function it_allow_methods_on_valid_preflight_request()
+    {
+        $app     = $this->createStackedApp(array('allowedMethods' => array('get', 'put')));
+        $request = $this->createValidPreflightRequest();
+
+        $response = $app->handle($request);
+
+        $this->assertTrue($response->headers->has('Access-Control-Allow-Methods'));
+        // it will uppercase the methods
+        $this->assertEquals('GET, PUT', $response->headers->get('Access-Control-Allow-Methods'));
+    }
+
+    /**
+     * @test
+     */
+    public function it_returns_valid_preflight_request_with_allow_methods_all()
+    {
+        $app     = $this->createStackedApp(array('allowedMethods' => array('*')));
+        $request = $this->createValidPreflightRequest();
+
+        $response = $app->handle($request);
+
+        $this->assertTrue($response->headers->has('Access-Control-Allow-Methods'));
+        // it will return the Access-Control-Request-Method pass in the request
+        $this->assertEquals('GET', $response->headers->get('Access-Control-Allow-Methods'));
+    }
+
+    /**
+     * @test
+     */
+    public function it_returns_403_on_valid_preflight_request_with_one_of_the_requested_headers_not_allowed()
+    {
+        $app     = $this->createStackedApp();
+        $request = $this->createValidPreflightRequest();
+        $request->headers->set('Access-Control-Request-Headers', 'x-not-allowed-header');
+
+        $response = $app->handle($request);
+
+        $this->assertEquals(403, $response->getStatusCode());
+    }
+
+    /**
+     * @test
+     */
+    public function it_returns_ok_on_valid_preflight_request_with_requested_headers_allowed()
+    {
+        $app            = $this->createStackedApp();
+        $requestHeaders = 'X-Allowed-Header, x-other-allowed-header';
+        $request        = $this->createValidPreflightRequest();
+        $request->headers->set('Access-Control-Request-Headers', $requestHeaders);
+
+        $response = $app->handle($request);
+
+        $this->assertEquals(200, $response->getStatusCode());
+
+        $this->assertTrue($response->headers->has('Access-Control-Allow-Headers'));
+        // the response will have the "allowedHeaders" value passed to Cors rather than the request one
+        $this->assertEquals('x-allowed-header, x-other-allowed-header', $response->headers->get('Access-Control-Allow-Headers'));
+    }
+
+    /**
+     * @test
+     */
+    public function it_sets_allow_credentials_header_when_flag_is_set_on_valid_preflight_request()
+    {
+        $app     = $this->createStackedApp(array('supportsCredentials' => true));
+        $request = $this->createValidPreflightRequest();
+
+        $response = $app->handle($request);
+
+        $this->assertTrue($response->headers->has('Access-Control-Allow-Credentials'));
+        $this->assertEquals('true', $response->headers->get('Access-Control-Allow-Credentials'));
+    }
+
+    /**
+     * @test
+     */
+    public function it_does_not_set_allow_credentials_header_when_flag_is_not_set_on_valid_preflight_request()
+    {
+        $app     = $this->createStackedApp();
+        $request = $this->createValidPreflightRequest();
+
+        $response = $app->handle($request);
+
+        $this->assertFalse($response->headers->has('Access-Control-Allow-Credentials'));
+    }
+
+    /**
+     * @test
+     */
+    public function it_sets_max_age_when_set()
+    {
+        $app     = $this->createStackedApp(array('maxAge' => 42));
+        $request = $this->createValidPreflightRequest();
+
+        $response = $app->handle($request);
+
+        $this->assertTrue($response->headers->has('Access-Control-Max-Age'));
+        $this->assertEquals(42, $response->headers->get('Access-Control-Max-Age'));
+    }
+
+    private function createValidActualRequest()
+    {
+        $request  = new Request();
+        $request->headers->set('Origin', 'localhost');
+
+        return $request;
+    }
+
+    private function createValidPreflightRequest()
+    {
+        $request  = new Request();
+        $request->headers->set('Origin', 'localhost');
+        $request->headers->set('Access-Control-Request-Method', 'get');
+        $request->setMethod('OPTIONS');
+
+        return $request;
+    }
+
+    private function createStackedApp(array $options = array(), array $responseHeaders = array())
+    {
+        $passedOptions = array_merge(array(
+                'allowedHeaders'      => array('x-allowed-header', 'x-other-allowed-header'),
+                'allowedMethods'      => array('delete', 'get', 'post', 'put'),
+                'allowedOrigins'      => array('localhost'),
+                'exposedHeaders'      => false,
+                'maxAge'              => false,
+                'supportsCredentials' => false,
+            ),
+            $options
+        );
+
+        return new Cors(new MockApp($responseHeaders), $passedOptions);
+    }
+}
+
+class MockApp implements HttpKernelInterface
+{
+    private $responseHeaders;
+
+    public function __construct(array $responseHeaders)
+    {
+        $this->responseHeaders = $responseHeaders;
+    }
+
+    public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
+    {
+        $response = new Response();
+
+        $response->headers->add($this->responseHeaders);
+
+        return $response;
+    }
+}
diff --git a/vendor/asm89/stack-cors/test/bootstrap.php b/vendor/asm89/stack-cors/test/bootstrap.php
new file mode 100644
index 0000000..deb617f
--- /dev/null
+++ b/vendor/asm89/stack-cors/test/bootstrap.php
@@ -0,0 +1,10 @@
+<?php
+
+if (file_exists($file = __DIR__.'/../vendor/autoload.php')) {
+    $loader = require_once $file;
+    $loader->add('Asm89\Stack', __DIR__);
+    $loader->add('Asm89\Stack', __DIR__ . '/../src');
+} else {
+    throw new RuntimeException('Install dependencies to run test suite.');
+}
+
diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php
index bb43043..5df820a 100644
--- a/vendor/composer/autoload_namespaces.php
+++ b/vendor/composer/autoload_namespaces.php
@@ -21,4 +21,5 @@
     'Doctrine\\Common\\Annotations\\' => array($vendorDir . '/doctrine/annotations/lib'),
     'Doctrine\\Common\\' => array($vendorDir . '/doctrine/common/lib'),
     'Composer\\Installers\\' => array($vendorDir . '/composer/installers/src'),
+    'Asm89\\Stack' => array($vendorDir . '/asm89/stack-cors/src'),
 );
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
index e2b7991..23c73a9 100644
--- a/vendor/composer/installed.json
+++ b/vendor/composer/installed.json
@@ -2687,7 +2687,7 @@
         },
         "dist": {
             "type": "zip",
-            "url": "https://api.github.com/repos/jcalderonzumba/gastonjs/zipball/5e231b4df98275c404e1371fc5fadd34f6a121ad",
+            "url": "https://api.github.com/repos/jcalderonzumba/gastonjs/zipball/21bebb8ca03eb0f93ec2f3fad61192fb079e2622",
             "reference": "5e231b4df98275c404e1371fc5fadd34f6a121ad",
             "shasum": ""
         },
@@ -3857,5 +3857,50 @@
             "phantomjs",
             "testing"
         ]
+    },
+    {
+        "name": "asm89/stack-cors",
+        "version": "0.2.1",
+        "version_normalized": "0.2.1.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/asm89/stack-cors.git",
+            "reference": "2d77e77251a434e4527315313a672f5801b29fa2"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/asm89/stack-cors/zipball/2d77e77251a434e4527315313a672f5801b29fa2",
+            "reference": "2d77e77251a434e4527315313a672f5801b29fa2",
+            "shasum": ""
+        },
+        "require": {
+            "php": ">=5.3.2",
+            "symfony/http-foundation": "~2.1",
+            "symfony/http-kernel": "~2.1"
+        },
+        "time": "2014-07-28 07:22:35",
+        "type": "library",
+        "installation-source": "dist",
+        "autoload": {
+            "psr-0": {
+                "Asm89\\Stack": "src/"
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "Alexander",
+                "email": "iam.asm89@gmail.com"
+            }
+        ],
+        "description": "Cross-origin resource sharing library and stack middleware",
+        "homepage": "https://github.com/asm89/stack-cors",
+        "keywords": [
+            "cors",
+            "stack"
+        ]
     }
 ]
