feat(page): move page.pdf to protocol streams (#4587)

This lets transferring massive PDF files over the protocol.

Fix #4563
This commit is contained in:
Andrey Lushnikov 2019-06-14 22:36:06 -07:00 committed by GitHub
parent 6c2007f1e3
commit 955e7cb6fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 39 additions and 39 deletions

View File

@ -924,6 +924,7 @@ class Page extends EventEmitter {
const marginRight = convertPrintParameterToInches(margin.right) || 0; const marginRight = convertPrintParameterToInches(margin.right) || 0;
const result = await this._client.send('Page.printToPDF', { const result = await this._client.send('Page.printToPDF', {
transferMode: 'ReturnAsStream',
landscape, landscape,
displayHeaderFooter, displayHeaderFooter,
headerTemplate, headerTemplate,
@ -939,10 +940,7 @@ class Page extends EventEmitter {
pageRanges, pageRanges,
preferCSSPageSize preferCSSPageSize
}); });
const buffer = Buffer.from(result.data, 'base64'); return await helper.readProtocolStream(this._client, result.stream, path);
if (path !== null)
await writeFileAsync(path, buffer);
return buffer;
} }
/** /**

View File

@ -14,11 +14,6 @@
* limitations under the License. * limitations under the License.
*/ */
const {helper, assert} = require('./helper'); const {helper, assert} = require('./helper');
const fs = require('fs');
const openAsync = helper.promisify(fs.open);
const writeAsync = helper.promisify(fs.write);
const closeAsync = helper.promisify(fs.close);
class Tracing { class Tracing {
/** /**
@ -66,40 +61,12 @@ class Tracing {
let fulfill; let fulfill;
const contentPromise = new Promise(x => fulfill = x); const contentPromise = new Promise(x => fulfill = x);
this._client.once('Tracing.tracingComplete', event => { this._client.once('Tracing.tracingComplete', event => {
this._readStream(event.stream, this._path).then(fulfill); helper.readProtocolStream(this._client, event.stream, this._path).then(fulfill);
}); });
await this._client.send('Tracing.end'); await this._client.send('Tracing.end');
this._recording = false; this._recording = false;
return contentPromise; return contentPromise;
} }
/**
* @param {string} handle
* @param {?string} path
*/
async _readStream(handle, path) {
let eof = false;
let file;
if (path)
file = await openAsync(path, 'w');
const bufs = [];
while (!eof) {
const response = await this._client.send('IO.read', {handle});
eof = response.eof;
bufs.push(Buffer.from(response.data));
if (path)
await writeAsync(file, response.data);
}
if (path)
await closeAsync(file);
await this._client.send('IO.close', {handle});
let resultBuffer = null;
try {
resultBuffer = Buffer.concat(bufs);
} finally {
return resultBuffer;
}
}
} }
module.exports = Tracing; module.exports = Tracing;

View File

@ -14,8 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
const {TimeoutError} = require('./Errors'); const {TimeoutError} = require('./Errors');
const debugError = require('debug')(`puppeteer:error`); const debugError = require('debug')(`puppeteer:error`);
const fs = require('fs');
class Helper { class Helper {
/** /**
@ -221,8 +221,43 @@ class Helper {
clearTimeout(timeoutTimer); clearTimeout(timeoutTimer);
} }
} }
/**
* @param {!Puppeteer.CDPSession} client
* @param {string} handle
* @param {?string} path
* @return {!Promise<!Buffer>}
*/
static async readProtocolStream(client, handle, path) {
let eof = false;
let file;
if (path)
file = await openAsync(path, 'w');
const bufs = [];
while (!eof) {
const response = await client.send('IO.read', {handle});
eof = response.eof;
const buf = Buffer.from(response.data, response.base64Encoded ? 'base64' : undefined);
bufs.push(buf);
if (path)
await writeAsync(file, buf);
}
if (path)
await closeAsync(file);
await client.send('IO.close', {handle});
let resultBuffer = null;
try {
resultBuffer = Buffer.concat(bufs);
} finally {
return resultBuffer;
}
}
} }
const openAsync = Helper.promisify(fs.open);
const writeAsync = Helper.promisify(fs.write);
const closeAsync = Helper.promisify(fs.close);
/** /**
* @param {*} value * @param {*} value
* @param {string=} message * @param {string=} message