I'm running PIWIK on a VPS with Ubuntu 15.04, HHVM 3.12.0 and NGINX 1.9.10. I have both PHP 5.6.4 and HHVM installed on that server. I use PHP to serve old web applications and HHVM for modern ones.
PIWIK works great under HHVM and reduces CPU load but PDF reports cannot be generated under HHVM.
I created a personal daily, weekly and monthly email report for one of my tracking sites under my account. On the reports table, there is an option to download the PDF.
When it is clicked this is the error message that comes up:
When I switch from HHVM to PHP, the PDF works flawlessly.
Seems that when using HHVM, Piwik's API renderer sets wrong response format (XML).
PDF file format requires
EOF to be used as file trailer, on the last line of the content.
This is done in https://github.com/tecnickcom/TCPDF/blob/develop/tcpdf.php#L9988
Piwik's API renderer appends XML response to valid PDF content, resulting in garbaged output:
... PDF content 0000413826 00000 n 0000414317 00000 n 0000414489 00000 n 0000414685 00000 n 0000414750 00000 n 0000414950 00000 n 0000419257 00000 n trailer << /Size 24 /Root 23 0 R /Info 21 0 R /ID [ <8aeb203749d4538ab33be9cb9db12ceb> <8aeb203749d4538ab33be9cb9db12ceb> ] >> startxref 419506 %%EOF <?xml version="1.0" encoding="utf-8" ?> <result></result>
Therefore, the browser cannot show the PDF content correctly, and shows you the XML error message instead.
Furthermore, when using HHVM instead of PHP engine, even though TCPDF is already setting correct
Content-Type header when generating inline browser output (https://github.com/tecnickcom/TCPDF/blob/6.2.12/tcpdf.php#L7624), the actual header's value being sent is
Content-Type: text/xml; charset=utf-8 X-Powered-By: HHVM/3.12.1 Cache-Control: private, must-revalidate, post-check=0, pre-check=0, max-age=1 Content-Disposition: inline; filename="All_Websites_-_Sunday_March_20_2016_-_test.pdf"
Correct response headers using PHP 5.6.19:
Content-Type: application/pdf Cache-Control: private, must-revalidate, post-check=0, pre-check=0, max-age=1 Content-Disposition: inline; filename="All_Websites_-_Sunday_March_20_2016_-_test.pdf"
You can bypass this behaviour by appending
&format=original parameter into the PDF report URI. That will show the report in your browser correctly, by setting correct
Content-Type response header and also disabling the additional XML output being appended.
This issue requires thorough investigation, but from what I can see so far, here would be some proposed solutions:
That way we would ensure that there is no extra content appended to the inline browser PDF output.
@emirb thank you a lot for investigating and giving us insights into the problem. :+1: :+1:
I haven't tried to reproduce it but wonder if this PR maybe kind of fixed the content type issue: https://github.com/piwik/piwik/pull/9700