From 78ba3dc4d428032cc51cba0f911f6119cae6725e Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Fri, 20 Oct 2017 11:06:12 +0200 Subject: [PATCH] Monitoring: make use of Buffer while serving CSV refs #13623 --- library/Icinga/File/Csv.php | 59 ++++++++++++++----- .../library/Monitoring/Controller.php | 9 ++- 2 files changed, 52 insertions(+), 16 deletions(-) diff --git a/library/Icinga/File/Csv.php b/library/Icinga/File/Csv.php index 93792417b..a71c36d12 100644 --- a/library/Icinga/File/Csv.php +++ b/library/Icinga/File/Csv.php @@ -3,12 +3,20 @@ namespace Icinga\File; +use Icinga\Util\Buffer; use Traversable; class Csv { protected $query; + /** + * Cache for {@link render()} + * + * @var Buffer|null + */ + protected $renderBuffer; + protected function __construct() { } @@ -22,26 +30,49 @@ class Csv public function dump() { - header('Content-type: text/csv'); - echo (string) $this; + $this->render()->fpassthru(); } public function __toString() { - $first = true; - $csv = ''; - foreach ($this->query as $row) { - if ($first) { - $csv .= implode(',', array_keys((array) $row)) . "\r\n"; - $first = false; + return (string) $this->render(); + } + + /** + * Return the rendered CSV + * + * @return Buffer + */ + protected function render() + { + if ($this->renderBuffer === null) { + $this->renderBuffer = new Buffer(); + $first = true; + foreach ($this->query as $row) { + if ($first) { + $this->renderBuffer->append($this->renderRow(array_keys((array)$row))); + $first = false; + } + $this->renderBuffer->append($this->renderRow(array_values((array)$row))); } - $out = array(); - foreach ($row as & $val) { - $out[] = '"' . $val . '"'; - } - $csv .= implode(',', $out) . "\r\n"; } - return $csv; + return $this->renderBuffer; + } + + /** + * Return a single CSV row string representing the given columns + * + * @param array $columns + * + * @return string + */ + protected function renderRow(array $columns) + { + $quoted = array(); + foreach ($columns as $column) { + $quoted[] = '"' . str_replace('"', '""', $column) . '"'; + } + return implode(',', $quoted) . "\r\n"; } } diff --git a/modules/monitoring/library/Monitoring/Controller.php b/modules/monitoring/library/Monitoring/Controller.php index 0d14b0858..9424110fa 100644 --- a/modules/monitoring/library/Monitoring/Controller.php +++ b/modules/monitoring/library/Monitoring/Controller.php @@ -72,8 +72,13 @@ class Controller extends IcingaWebController 'Content-Disposition', 'attachment; filename=' . $this->getRequest()->getActionName() . '.csv' ) - ->appendBody((string) Csv::fromQuery($query)) - ->sendResponse(); + ->sendHeaders(); + + while (ob_get_level()) { + ob_end_clean(); + } + Csv::fromQuery($query)->dump(); + exit; } }