PHPドライバ1.1.4[Content-Lengthが送られない不具合を修正]

PHPドライバで、cssj_ob_start_main関数を使用して変換した文書を、直接クライアントに送信する場合、元のドキュメントのサイズが大きい場合にContent-Lengthヘッダが送られない不具合がありました。

cssj_ob_start_resourceまたはcssj_ob_start_mainを使用して、パススルーでPDFをブラウザに送るアプリケーションで問題が発生する可能性があります。5月21日に続き頻繁な修正となり申し訳ございませんが、ドライバの更新をお願いいたします。

PHPドライバのダウンロードページからダウンロードしてください。

不具合の詳細

Copper PDFはPHPのoutput bufferを利用して変換元の文書をキャプチャします。以下のような手順で処理しています。

ob_start(コールバック関数, チャンクサイズ);
...変換元の文書の出力...
ob_end_clean();
header("Content-Length: ファイルの大きさ");

コールバック関数はバッファの内容をCopper PDFに送った後消去するため、ob_end_clean()が呼び出されるまでの間、本来であれば何もブラウザに送信しません。

しかし、PHPドライバ1.1.3で大きな文書を処理した場合にバッファが足りなくなる問題を回避するために、チャンクサイズを指定したところ、PHPはバッファの内容が指定したチャンクサイズに達すると、コールバック関数によりバッファの内容が削除されても、データが送信されたものとみなして、HTTPヘッダが送られた状態(headers_sent()がTRUEを返す状態)にしてしまいます(あまり好ましい動作ではなく、PHPのドキュメントにも記述がありませんが、そのような仕様になっているようです)。

PHPドライバ1.1.4では、次の通り二重にバッファリングするようにして回避しました。

ob_start();
ob_start(コールバック関数, チャンクサイズ);
...変換元の文書の出力...
ob_end_clean();
ob_end_clean();
header("Content-Length: ファイルの大きさ");

上記の場合、内側のバッファでデータ送信が行われても、外側のバッファに対して行われるので、外側のバッファが終了しない限り、クライアントに影響することはありません。

対策

ドライバ関係の不具合が起こっている状況を踏まえて、開発中のCopper PDFにドライバの負荷テストに使用するための機能を組み込み、ネットワーク越し、ローカル接続の両方で3種類のドライバの負荷テストを実施しました。

Java, Perlドライバと修正済みのPHPドライバで問題が発生しないことを確認しています。


PDF

Comments are closed.