summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuca Lusso2018-07-24 08:52:36 (GMT)
committerLuca Lusso2018-07-24 08:52:36 (GMT)
commite0498e13e0d154254795e32cb5c52acc77336392 (patch)
tree3cbff15faab73877f92c64838714c193b4d52771
parent74e53a7075b329c2e0fe8636f58e09981663e9cc (diff)
Issue #2847714: Compatibility with big pipe
-rw-r--r--webprofiler/src/EventSubscriber/ProfilerSubscriber.php118
-rw-r--r--webprofiler/webprofiler.services.yml2
2 files changed, 119 insertions, 1 deletions
diff --git a/webprofiler/src/EventSubscriber/ProfilerSubscriber.php b/webprofiler/src/EventSubscriber/ProfilerSubscriber.php
new file mode 100644
index 0000000..d3f3124
--- /dev/null
+++ b/webprofiler/src/EventSubscriber/ProfilerSubscriber.php
@@ -0,0 +1,118 @@
+<?php
+
+namespace Drupal\webprofiler\EventSubscriber;
+
+use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
+use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
+use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
+use Symfony\Component\HttpKernel\KernelEvents;
+use Symfony\Component\HttpKernel\Profiler\Profiler;
+use Symfony\Component\HttpFoundation\RequestMatcherInterface;
+use Symfony\Component\HttpFoundation\RequestStack;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+class ProfilerSubscriber implements EventSubscriberInterface {
+
+ protected $profiler;
+
+ protected $matcher;
+
+ protected $onlyException;
+
+ protected $onlyMasterRequests;
+
+ protected $exception;
+
+ protected $profiles;
+
+ protected $requestStack;
+
+ protected $parents;
+
+ /**
+ * @param Profiler $profiler A Profiler instance
+ * @param RequestStack $requestStack A RequestStack instance
+ * @param RequestMatcherInterface|null $matcher A RequestMatcher instance
+ * @param bool $onlyException True if the profiler only collects data when an
+ * exception occurs, false otherwise
+ * @param bool $onlyMasterRequests True if the profiler only collects data
+ * when the request is a master request, false otherwise
+ */
+ public function __construct(Profiler $profiler, RequestStack $requestStack, RequestMatcherInterface $matcher = NULL, $onlyException = FALSE, $onlyMasterRequests = FALSE) {
+ $this->profiler = $profiler;
+ $this->matcher = $matcher;
+ $this->onlyException = (bool) $onlyException;
+ $this->onlyMasterRequests = (bool) $onlyMasterRequests;
+ $this->profiles = new \SplObjectStorage();
+ $this->parents = new \SplObjectStorage();
+ $this->requestStack = $requestStack;
+ }
+
+ /**
+ * Handles the onKernelException event.
+ */
+ public function onKernelException(GetResponseForExceptionEvent $event) {
+ if ($this->onlyMasterRequests && !$event->isMasterRequest()) {
+ return;
+ }
+
+ $this->exception = $event->getException();
+ }
+
+ /**
+ * Handles the onKernelResponse event.
+ */
+ public function onKernelResponse(FilterResponseEvent $event) {
+ $master = $event->isMasterRequest();
+ if ($this->onlyMasterRequests && !$master) {
+ return;
+ }
+
+ if ($this->onlyException && NULL === $this->exception) {
+ return;
+ }
+
+ $request = $event->getRequest();
+ $exception = $this->exception;
+ $this->exception = NULL;
+
+ if (NULL !== $this->matcher && !$this->matcher->matches($request)) {
+ return;
+ }
+
+ if (!$profile = $this->profiler->collect($request, $event->getResponse(), $exception)) {
+ return;
+ }
+
+ $this->profiles[$request] = $profile;
+
+ $this->parents[$request] = $this->requestStack->getParentRequest();
+ }
+
+ public function onKernelFinishRequest(FinishRequestEvent $event) {
+ // attach children to parents
+ foreach ($this->profiles as $request) {
+ if (NULL !== $parentRequest = $this->parents[$request]) {
+ if (isset($this->profiles[$parentRequest])) {
+ $this->profiles[$parentRequest]->addChild($this->profiles[$request]);
+ }
+ }
+ }
+
+ // save profiles
+ foreach ($this->profiles as $request) {
+ $this->profiler->saveProfile($this->profiles[$request]);
+ }
+
+ $this->profiles = new \SplObjectStorage();
+ $this->parents = new \SplObjectStorage();
+ }
+
+ public static function getSubscribedEvents() {
+ return [
+ KernelEvents::RESPONSE => ['onKernelResponse', -100],
+ KernelEvents::EXCEPTION => 'onKernelException',
+ KernelEvents::FINISH_REQUEST => ['onKernelFinishRequest', -1024],
+ ];
+ }
+}
diff --git a/webprofiler/webprofiler.services.yml b/webprofiler/webprofiler.services.yml
index 6332fef..5052792 100644
--- a/webprofiler/webprofiler.services.yml
+++ b/webprofiler/webprofiler.services.yml
@@ -46,7 +46,7 @@ services:
# event subscribers
webprofiler.profiler_listener:
- class: Symfony\Component\HttpKernel\EventListener\ProfilerListener
+ class: Drupal\webprofiler\EventSubscriber\ProfilerSubscriber
arguments: ['@profiler', '@request_stack', '@?webprofiler.matcher', '%webprofiler.only_exceptions%', '%webprofiler.only_master_requests%']
tags:
- { name: event_subscriber }