Skip to content
This repository has been archived by the owner on Oct 20, 2023. It is now read-only.

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
steinkel committed Mar 12, 2019
0 parents commit d336cc2
Show file tree
Hide file tree
Showing 12 changed files with 384 additions and 0 deletions.
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/tmp
/vendor
/.idea
composer.lock
.php_cs*
/coverage
rr
5 changes: 5 additions & 0 deletions .semver
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
:major: 0
:minor: 0
:patch: 1
:special: ''
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Changelog
=========

* 0.0.1
* Initial release
4 changes: 4 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Contributing
============

This repository follows the [CakeDC Plugin Standard](https://www.cakedc.com/plugin-standard). If you'd like to contribute new features, enhancements or bug fixes to the plugin, please read our [Contribution Guidelines](https://www.cakedc.com/contribution-guidelines) for detailed instructions.
26 changes: 26 additions & 0 deletions LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
The MIT License

Copyright 2009-2019
Cake Development Corporation
1785 E. Sahara Avenue, Suite 490-423
Las Vegas, Nevada 89104
Phone: +1 702 425 5085
https://www.cakedc.com

Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
109 changes: 109 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
Roadrunner for CakePHP
===================

[![Build Status](https://secure.travis-ci.org/cakedc/cakephp-roadrunner.png?branch=master)](http://travis-ci.org/cakedc/cakephp-roadrunner)
[![Coverage Status](https://img.shields.io/codecov/c/gh/cakedc/cakephp-roadrunner.svg?style=flat-square)](https://codecov.io/gh/cakedc/cakephp-roadrunner)
[![Downloads](https://poser.pugx.org/cakedc/cakephp-roadrunner/d/total.png)](https://packagist.org/packages/cakedc/cakephp-roadrunner)
[![Latest Version](https://poser.pugx.org/cakedc/cakephp-roadrunner/v/stable.png)](https://packagist.org/packages/cakedc/cakephp-roadrunner)
[![License](https://poser.pugx.org/cakedc/cakephp-roadrunner/license.svg)](https://packagist.org/packages/cakedc/cakephp-roadrunner)


Requirements
------------

* CakePHP 3.4.0+
* PHP 7.1+

Setup
-----

* `composer require cakedc/cakephp-roadrunner`
* Download roadrunner binary and place the file in your filesystem, for example under `/usr/local/bin/rr`
* Create a RoadRunner worker file, or use the example worker provided

```bash
cp vendor/cakedc/cakephp-roadrunner/worker/* .
```

Note the configuration is stored in .rr.json file, check all possible keys here
https://github.com/spiral/roadrunner/wiki/Configuration

* Start the server, either using your own configuration or the sample configuration provided in the plugin

`/usr/local/bin/rr serve`

* If you need sessions
* Ensure you add the following to your session config in your CakePHP `config/app.php`

```php
'Session' => [
'defaults' => 'php',
'ini' => [
'session.use_trans_sid' => false,
'session.use_cookies' => false,
'session.use_only_cookies' => true,
'session.cache_limiter' => '',
'session.save_handler' => 'user',
],
],
```

* Add the session middleware to your `src/Application.php` middleware queue

```php
->add(new \Relay\Middleware\SessionHeadersHandler())
```

* Nginx proxy

You'll possibly need to configure a webserver to handle requests, serve static assets etc.
Use this sample config virtualhost for nginx:

```
server {
listen 80;
server_name example.com;
root /var/virtual/example.com/webroot;
location / {
try_files $uri @backend8080;
}
location @backend8080 {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}
```

Documentation
-------------

For documentation, as well as tutorials, see the [Docs](Docs/Home.md) directory of this repository.

Support
-------

For bugs and feature requests, please use the [issues](https://github.com/cakedc/cakephp-roadrunner/issues) section of this repository.

Commercial support is also available, [contact us](https://www.cakedc.com/contact) for more information.

Contributing
------------

This repository follows the [CakeDC Plugin Standard](https://www.cakedc.com/plugin-standard). If you'd like to contribute new features, enhancements or bug fixes to the plugin, please read our [Contribution Guidelines](https://www.cakedc.com/contribution-guidelines) for detailed instructions.

License
-------

Copyright 2019 Cake Development Corporation (CakeDC). All rights reserved.

Licensed under the [MIT](http://www.opensource.org/licenses/mit-license.php) License. Redistributions of the source code included in this repository must retain the copyright notice found in each file.

Todo
----
* Existing issue setting cookies like $this->response = $this->response->withHeader('head', 'one'); conflicts with session cookie generation
25 changes: 25 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "cakedc/cakephp-roadrunner",
"description": "Roadrunner bridge and worker for CakePHP",
"type": "cakephp-plugin",
"license": "MIT",
"require": {
"cakephp/cakephp": "^3.6",
"spiral/roadrunner": "^1.3",
"relay/middleware": "^1.2"
},
"require-dev": {
"phpunit/phpunit": "^5.7|^6.0"
},
"autoload": {
"psr-4": {
"CakeDC\\Roadrunner\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"CakeDC\\Roadrunner\\Test\\": "tests",
"Cake\\Test\\": "./vendor/cakephp/cakephp/tests"
}
}
}
117 changes: 117 additions & 0 deletions src/Bridge.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
<?php
namespace CakeDC\Roadrunner;

use Cake\Http\Cookie\Cookie;
use CakeDC\Roadrunner\Http\ServerRequestFactory;

class Bridge
{
/**
* @var Server
*/
protected $server;

/**
* @var string root path
*/
protected $root;

public function __construct($root = null)
{
$this->root = $root;
if ($root === null) {
$this->root = dirname(__DIR__, 4);
}
}

/**
* Bootstrap an application
*
* @param string|null $appBootstrap The environment your application will use to bootstrap (if any)
* @param string $appenv
* @param bool $debug If debug is enabled
*/
public function bootstrap($appBootstrap, $appenv, $debug)
{
require $this->root . '/config/requirements.php';
require $this->root . '/vendor/autoload.php';
$this->application = new \App\Application($this->root . '/config');
$this->application->bootstrap();

if ($this->application instanceof \Cake\Core\PluginApplicationInterface) {
$this->application->pluginBootstrap();
}
$this->server = new \Cake\Http\Server($this->application);
}

/**
* Handle the request and return a response.
*
* @param ServerRequestInterface $request
*
* @return ResponseInterface
*/
public function handle(\Psr\Http\Message\ServerRequestInterface $request)
{
$response = new \Cake\Http\Response();
$request = $this->convertRequest($request);
$middleware = $this->application->middleware(new \Cake\Http\MiddlewareQueue());
if ($this->application instanceof \Cake\Core\PluginApplicationInterface) {
$middleware = $this->application->pluginMiddleware($middleware);
}

if (!($middleware instanceof \Cake\Http\MiddlewareQueue)) {
throw new \RuntimeException('The application `middleware` method did not return a middleware queue.');
}
$this->server->dispatchEvent('Server.buildMiddleware', ['middleware' => $middleware]);
$middleware->add($this->application);
$runner = new \Cake\Http\Runner();
$response = $runner->run($middleware, $request, $response);
$cookies = [];
foreach ($response->getCookieCollection() as $cookie) {
/**
* @var Cookie $cookie
*/
if ($cookie->getExpiresTimestamp() === '0') {
$cookie = $cookie->withNeverExpire();
}
$cookies[] = $cookie->toHeaderValue();
}
if (!empty($cookies)) {
$response = $response->withHeader('Set-Cookie', $cookies);
}
if (!($response instanceof \Psr\Http\Message\ResponseInterface)) {
throw new \RuntimeException(sprintf(
'Application did not create a response. Got "%s" instead.',
is_object($response) ? get_class($response) : $response
));
}

session_write_close();

return $response;
}

protected function convertRequest(\Zend\Diactoros\ServerRequest $request) : \Cake\Http\ServerRequest
{
$server = $request->getServerParams();
$server['REQUEST_TIME'] = time();
$server['REQUEST_TIME_FLOAT'] = microtime(true);
$server['REMOTE_ADDR'] = '127.0.0.1';
$server['SERVER_PROTOCOL'] = $request->getUri()->getScheme();
$server['REQUEST_METHOD'] = $request->getMethod();
$server['SERVER_NAME'] = $request->getUri()->getHost();
$server['SERVER_PORT'] = $request->getUri()->getPort();
$server['REQUEST_URI'] = $request->getUri()->getPath();

$query = $request->getQueryParams();
$body = $request->getParsedBody();
$cookies = $request->getCookieParams();
$files = $request->getUploadedFiles();

$cakeRequest = ServerRequestFactory::fromGlobals($server, $query, $body, $cookies, $files);
$cakeRequest->trustProxy = true;

return $cakeRequest;
}
}
41 changes: 41 additions & 0 deletions src/Http/ServerRequestFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php
namespace CakeDC\Roadrunner\Http;

use Cake\Core\Configure;
use Cake\Error\Debugger;
use Cake\Http\ServerRequest;

class ServerRequestFactory extends \Cake\Http\ServerRequestFactory
{
/**
* override and inject a custom Session instance, until we get the ref. PR merged
*/
public static function fromGlobals(
array $server = null,
array $query = null,
array $body = null,
array $cookies = null,
array $files = null
) {
$server = static::normalizeServer($server ?: $_SERVER);
$uri = static::createUri($server);
$sessionConfig = (array)Configure::read('Session') + [
'defaults' => 'php',
'cookiePath' => $uri->webroot
];
$session = Session::create($sessionConfig);
$request = new ServerRequest([
'environment' => $server,
'uri' => $uri,
'files' => $files ?: $_FILES,
'cookies' => $cookies ?: $_COOKIE,
'query' => $query ?: $_GET,
'post' => $body ?: $_POST,
'webroot' => $uri->webroot,
'base' => $uri->base,
'session' => $session,
]);

return $request;
}
}
22 changes: 22 additions & 0 deletions src/Http/Session.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php
namespace CakeDC\Roadrunner\Http;

/**
* Override CakePHP Session to set isCli to false and manage sessions
*
* @package CakeDC\Roadrunner\Http
*/
class Session extends \Cake\Http\Session
{
/**
* Override the cli fixed session
*
* @return bool
*/
public function start()
{
$this->_isCLI = false;

return parent::start();
}
}
11 changes: 11 additions & 0 deletions worker/.rr.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"http": {
"address": "0.0.0.0:8080",
"workers": {
"command": "php cakephp-worker.php",
"pool": {
"numWorkers": 8
}
}
}
}
12 changes: 12 additions & 0 deletions worker/cakephp-worker.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php
require __DIR__ . "/vendor/autoload.php";
$bridge = new \CakeDC\Roadrunner\Bridge(__DIR__);
$bridge->bootstrap(null, null, null);
$relay = new \Spiral\Goridge\StreamRelay(STDIN, STDOUT);
$psr7 = new \Spiral\RoadRunner\PSR7Client(new \Spiral\RoadRunner\Worker($relay));

while ($req = $psr7->acceptRequest()) {
// \CakeDC\Api\Service\ServiceRegistry::getServiceLocator()->clear(); // reset API cache if you're using CakeDC/Api plugin
$psr7response = $bridge->handle($req);
$psr7->respond($psr7response);
}

0 comments on commit d336cc2

Please sign in to comment.