2015-06-25 2 views
1

Я использую webkithtmltopdf для создания PDF-файлов & хочу перезаписать любые существующие файлы.Отладочные файлы не обновляются атомарно (возможно, проблема с броузером PDF.js)

Я не уверен, что это гарантирует атомные обновления, или если мы будем использовать другой инструмент PDF в один прекрасный день, поэтому я завернул его в некоторый PHP-код, который использует временный файл. После создания временного файла я использую функцию rename() PHP для перезаписывания фактического файла.

Я обнаружил, что временный файл & существует в том же разделе, однако при запуске моего сценария иногда я получаю сообщение типа «PDF-файл не отображается» из браузера, если я запрашиваю PDF-файл в точный момент его переписывания.

Как я могу попытаться отладить это? Я не вижу ошибок в журнале ошибок Apache. Я вижу запросы «200» и «206» в журналах доступа. Я не уверен, что я ищу на Content-Length, или как pdf.js работает вместе с сервером.

код выглядит следующим образом:

$output = sprintf(__DIR__."/pdfs/%s.pdf", $id); 
$tmpOutput = $output . '.tmp'; 
$cmd = 'wkhtmltopdf '. escapeshellarg($url) . ' ' . escapeshellarg($tmpOutput); 

exec($cmd); 
chmod($tmpOutput, 0777); 
rename($tmpOutput, $output); 
chmod($output, 0777); 

Его стоит упомянуть, я использую CHMOD, чтобы обойти тот факт, я бегу это в Gearman работника, в ведении руководителя, который был начат корнем. Если бы это была проблема разрешения, я бы ожидал ошибки, заявляя, что в журнале ошибок Apache, но нет, и я также ожидал бы код статуса 403 или тому подобное, но все, что я вижу, - 200 или 206 в журналах ,

+1

атомарно? что это значит, как атомы и прочее? – meda

+1

@meda как изменение переменной без изменения других потоков. –

+0

атомно означает, что в любой момент времени любой процесс, считывающий этот путь, должен получить полностью сформированный pdf-файл. Он не должен получать пустой или частичный файл в результате чтения его в тот момент, когда он обновляется. Либо он получает старый файл, либо новый файл. –

ответ

0

Большинство читателей PDF читают PDF-файлы из сетевых фрагментов, это означает, что в нескольких HTTP-запросах используется заголовок Range (указав, какой размер байта из файла, который он хочет, например 1000-5000, поэтому количество байтов 4000). Ответы Webserver с кодом ответа HTTP 206 Partial Content. Если вы измените файл PDF между этими частичными запросами, программа чтения PDF получит поврежденный файл (часть из старого файла, часть из нового файла).

Протокол HTTP должен предотвращать его. При первом запросе читателю PDF следует также получить заголовок ETAg, который является уникальным и изменяется, если файл изменен. При последующих запросах читатель PDF должен отправить заголовок If-Match, чтобы веб-сервер мог сообщить ему, если файл все тот же. Но иногда это не работает. Вы можете отключить Range запросов в конфигурации Apache (или .htaccess файла) с этим:

<Files *.pdf> 
    Header set Accept-Ranges none 
</Files> 

Также убедитесь, что ваш временный файл всегда уникален, так что нет 2 PHP процесса не будет писать в тот же темпе файл в том же время.

Смежные вопросы