Upgrade to Pro — share decks privately, control downloads, hide ads and more …

The HttpKernelInterface is a lie (forumphp)

A4b95be2145cc46f891707b6db9dd82d?s=47 Igor Wiedler
November 21, 2013

The HttpKernelInterface is a lie (forumphp)

A4b95be2145cc46f891707b6db9dd82d?s=128

Igor Wiedler

November 21, 2013
Tweet

Transcript

  1. Stack a PHP interface for framework-­ agnostic code sharing

  2. the HttpKernelInterface is a lie

  3. @igorwesome

  4. None
  5. “Interface” Protocol Communication Message passing

  6. Catherine Please, from The Noun Project

  7. Paulo Sá Ferreira - Purple Matter, from The Noun Project

  8. hi!

  9. None
  10. 10010101110100100

  11. 1001010111010010000110101 Massimiliano Mauro, from The Noun Project

  12. Sergey Shmidt, from The Noun Project aloha!

  13. yay!

  14. 00101000011101100102

  15. None
  16. None
  17. None
  18. None
  19. Universal Interface

  20. None
  21. 10010111001010001011

  22. 1234 4321

  23. foo bar baz foo baz Patrick n Hawaii, from The

    Noun Project
  24. foo moo Anuar Zhumaev, from The Noun Project

  25. find src -name '*.php' | grep -iv tests | cut

    -f2- -d/ | cut -f1 -d\. | awk '{ print length, $0 }' | sort -n | tr / \\ ;
  26. Tim Boelaars, from The Noun Project

  27. None
  28. nc

  29. /\_/\ / 0 0 \ ====v==== \ W / |

    | _ / ___ \ / / / \ \ | (((-----)))-' / ( ___ \__.=|___E /
  30. None
  31. data Dmitry Baranovskiy, from The Noun Project

  32. xinetd

  33. None
  34. /etc/xinet.d/<service> service <service> { disable = no socket_type = stream

    protocol = tcp user = <user> wait = no server = /usr/local/bin/<program> }
  35. /etc/xinet.d/fortune service fortune { disable = no socket_type = stream

    protocol = tcp user = xinetd wait = no server = /usr/local/bin/fortune }
  36. #!/bin/bash fortune | cowsay

  37. $ nc <host> 7777

  38. $ nc <host> 7777 ______________________________________ < Eat right, stay fit,

    and die anyway. > -------------------------------------- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
  39. /etc/xinet.d/cowsay service cowsay { disable = no socket_type = stream

    protocol = tcp user = xinetd wait = no server = /usr/games/cowsay }
  40. $ echo 'moo' | nc <host> 7778

  41. $ echo 'moo' | nc <host> 7778 _____ < moo

    > ----- \ ^__^ \ (oo)\_______ (__)\ )\/\ ||----w | || ||
  42. #!/usr/bin/php <?php ! while (!feof(STDIN)) { echo transform(fgets(STDIN)); }

  43. cgi

  44. The Common Gateway Interface (CGI) [22]! allows an HTTP [1],

    [4] server and a CGI! script to share responsibility for responding! to client requests. RFC 3875
  45. xinetd tcp http httpd

  46. http httpd script cgi

  47. script env vars data headers data

  48. GET / HTTP/1.1 Host: igor.io Accept: */* REQUEST_METHOD = GET

    PATH_INFO = / HTTP_HOST = igor.io HTTP_ACCEPT = */* SERVER_NAME = igor.io
  49. Content-Type: text/html ! <!DOCTYPE html> <html> ... </html>

  50. fcgi

  51. script

  52. sockets are the new pipes

  53. • 1991: HTTP • 1993: CGI • 1995: PHP •

    1996: FastCGI
  54. • 1997: Java Servlet • 2003: Python WSGI • 2007:

    Ruby Rack • 2009: Perl PSGI • 2011: Symfony2 HttpKernelInterface
  55. rack

  56. class HelloWorld def call(env) [ 200, {"Content-Type" => "text/plain"}, ["Hello

    world!"] ] end end
  57. sapi

  58. $_SERVER header echo exit

  59. HttpKernelInterface

  60. interface HttpKernelInterface! {! /*** @return Response */! public function handle(Request

    $request);! }
  61. sapi kernel

  62. None
  63. “legacy” apps: it’s all great until exit;

  64. myths: !

  65. myths: caching

  66. myths: caching (use varnish)

  67. myths: caching (use varnish) functional tests

  68. CgiHttpKernel adapter from kernel to cgi functional test “legacy” apps

  69. kernel CGI

  70. kernel CGI anything!

  71. $kernel = new CgiHttpKernel(__DIR__.'/app'); ! $request = Request::create('/index.php'); $response =

    $kernel->handle($request); ! var_dump($response->getContent());
  72. use Symfony\Component\HttpKernel\Client; ! $client = new Client($kernel); ! $crawler =

    $client->request('GET', '/index.php');
  73. caution: it’s slow (WIP: FcgiHttpKernel)

  74. Where is the value?

  75. REQ REP

  76. fcgi roles

  77. authorizer httpd responder filter

  78. rack middlewares

  79. HttpKernel middlewares

  80. $app = new CallableHttpKernel(function ($request) { return new Response('Hello World!');

    });
  81. class Logger implements HttpKernelInterface { private $app; private $logger; !

    public function __construct(HttpKernelInterface $app, LoggerInterface $logger) { $this->app = $app; $this->logger = $logger; } ! public function handle(Request $request, ...) { $response = $this->app->handle($request, $type, $catch); ! $this->log($request, $response); ! return $response; } ! private function log(Request $request, Response $response) { ... } }
  82. $app = new Logger( $app, new Monolog\Logger() );

  83. use Symfony\Component\HttpKernel\HttpCache\HttpCache; use Symfony\Component\HttpKernel\HttpCache\Store; $app = new HttpCache( $app, new

    Store(__DIR__.'/cache') );
  84. use Symfony\Component\HttpKernel\HttpCache\HttpCache; use Symfony\Component\HttpKernel\HttpCache\Store; $app = new HttpCache( $app, new

    Store(__DIR__.'/cache') ); use varnish!
  85. App Logger Authentication Session

  86. None
  87. do something before or after every request

  88. different take on event listeners

  89. class Foo implements HttpKernelInterface { private $app; ! public function

    __construct(HttpKernelInterface $app) { $this->app = $app; } ! public function handle(Request $request, ...) { $response = $this->app->handle($request, $type, $catch); ! return $response; } } 1 2 3
  90. UrlMap $blog = new Silex\Application(); ! $blog->get('/', function () {

    return 'This is the blog!'; }); ! $app = new Stack\UrlMap($app, [ '/blog' => $blog, ]);
  91. Session $app = new CallableHttpKernel(function ($request) { $session = $request->getSession();

    ... }); ! $app = new Stack\Session($app);
  92. OAuth $app = new Igorw\Stack\OAuth($app, [ 'key' => 'foo', 'secret'

    => 'bar', 'callback_url' => 'http://localhost:8080/auth/verify', 'success_url' => '/', 'failure_url' => '/auth', ]); ! $app = new Stack\Session($app);
  93. OAuth $request->attributes->get('oauth.token');

  94. Composition!

  95. $stack = (new Stack\Builder()) ->push('Stack\Session') ->push('Igorw\Stack\OAuth', [...]) ->push('Foo'); ! $app

    = $stack->resolve($app);
  96. • GeoIp • IpRestrict • Backstage • Basic Authentication •

    Hawk • CORS Community
  97. It doesn’t stop there

  98. • Authentication • Debug toolbar • Injected routes • Signed

    cookies • Asset management • Force SSL • Error handling
  99. ( )

  100. Choose wisely

  101. Michael Rowe, from The Noun Project

  102. • joind.in/9355 • stackphp.com • @stackphp • @igorwesome • github.com/igorw/CgiHttpKernel