James Ludlow
James Ludlow

Reputation: 430

CakePHP - CakeResponse::File extremely slow

I need to serve files to authenticated users and recognise that using PHP will include a performance penalty, however what I've experienced so far seems to be unworkable.

I have a very simple controller action which sends the file:

public function view($id = null) {
    $id = $id | $this->params->named['id'];
    if (!$this->Attachment->exists($id)) {
        throw new NotFoundException(__('Invalid attachment'));
    }
    $this->autoRender = false;
    $this->Attachment->recursive = -1;
    $file = $this->Attachment->findById($id);

    $this->response->file(APP . DS . $file['Attachment']['dir']);

    return $this->response;
}

A small (55 KB) PNG file takes 8 seconds to load using this method, where as if I move the file to the webroot directory and load it directly it takes less than 2.5 seconds. From looking at Chrome Dev Tools, the 'Receiving' part of the response is taking > 7s (compared with 1.5s direct).

A medium sized PDF file (2.5MB) takes over 2 minutes through CakeResponse, compared to ~4s directly. Surely I must be missing something in my controller action as this must be unworkable for anyone?

EDIT: CakePHP version is 2.4.1.

Upvotes: 2

Views: 210

Answers (1)

James Ludlow
James Ludlow

Reputation: 430

Thanks to the suggestion to use Xdebug I was able to quickly track down the problem.

In CakeResponse, there is the following function:

/**
 * Flushes the contents of the output buffer
 *
 * @return void
 */
    protected function _flushBuffer() {
        //@codingStandardsIgnoreStart
        @flush();
        @ob_flush();
        //@codingStandardsIgnoreEnd
    }

Obviously with the error suppression operator the calls to flush and ob_flush would not normally cause a problem.

However, I also have Sentry as a remote debugging tool installed. This ignores the error suppression operator, reports that there is no buffer to flush (because ob_start has not been called) and in doing so outputs the contents of the file to the log file!

Upvotes: 3

Related Questions