diff --git a/docs/api.md b/docs/api.md index c2bdf5f7d27..3731c4e6d45 100644 --- a/docs/api.md +++ b/docs/api.md @@ -215,9 +215,16 @@ * [response.json()](#responsejson) * [response.ok()](#responseok) * [response.request()](#responserequest) + * [response.securityDetails()](#responsesecuritydetails) * [response.status()](#responsestatus) * [response.text()](#responsetext) * [response.url()](#responseurl) +- [class: SecurityDetails](#class-securitydetails) + * [securityDetails.issuer()](#securitydetailsissuer) + * [securityDetails.protocol()](#securitydetailsprotocol) + * [securityDetails.subjectName()](#securitydetailssubjectname) + * [securityDetails.validFrom()](#securitydetailsvalidfrom) + * [securityDetails.validTo()](#securitydetailsvalidto) - [class: Target](#class-target) * [target.createCDPSession()](#targetcreatecdpsession) * [target.page()](#targetpage) @@ -2420,6 +2427,9 @@ Contains a boolean stating whether the response was successful (status in the ra #### response.request() - returns: <[Request]> A matching [Request] object. +#### response.securityDetails() +- returns: <[SecurityDetails]> An object with security details associated with the response. From the original object only the fields `subjectName`, `"issuer"`, `"validFrom"`, `"validTo"`, `"protocol"` are extracted. + #### response.status() - returns: <[number]> @@ -2433,6 +2443,25 @@ Contains the status code of the response (e.g., 200 for a success). Contains the URL of the response. +### class: SecurityDetails + +[SecurityDetails] class represents responses which are received by page. + +#### securityDetails.issuer() +- returns: <[string]> A string with the name of issuer of the certificate. + +#### securityDetails.protocol() +- returns: <[string]> String with the security protocol, eg. "TLS 1.2". + +#### securityDetails.subjectName() +- returns: <[string]> Name of the subject to which the certificate was issued to. + +#### securityDetails.validFrom() +- returns: <[number]> Timestamp stating the start of validity of the certificate. + +#### securityDetails.validTo() +- returns: <[number]> Timestamp stating the end of validity of the certificate. + ### class: Target #### target.createCDPSession() diff --git a/lib/NetworkManager.js b/lib/NetworkManager.js index a9c5d0e0978..c2feb1d81c7 100644 --- a/lib/NetworkManager.js +++ b/lib/NetworkManager.js @@ -253,7 +253,7 @@ class NetworkManager extends EventEmitter { if (!request) return; const response = new Response(this._client, request, event.response.status, event.response.headers, - event.response.fromDiskCache, event.response.fromServiceWorker); + event.response.fromDiskCache, event.response.fromServiceWorker, event.response.securityDetails); request._response = response; this.emit(NetworkManager.Events.Response, response); } @@ -498,10 +498,11 @@ class Response { * @param {!Request} request * @param {number} status * @param {!Object} headers + * @param {!Object} securityDetails * @param {boolean} fromDiskCache * @param {boolean} fromServiceWorker */ - constructor(client, request, status, headers, fromDiskCache, fromServiceWorker) { + constructor(client, request, status, headers, fromDiskCache, fromServiceWorker, securityDetails = null) { this._client = client; this._request = request; this._contentPromise = null; @@ -513,6 +514,15 @@ class Response { this._headers = {}; for (const key of Object.keys(headers)) this._headers[key.toLowerCase()] = headers[key]; + this._securityDetails = {}; + if (securityDetails) { + this._securityDetails = new SecurityDetails( + securityDetails['subjectName'], + securityDetails['issuer'], + securityDetails['validFrom'], + securityDetails['validTo'], + securityDetails['protocol']); + } } /** @@ -543,6 +553,13 @@ class Response { return this._headers; } + /** + * @return {!SecurityDetails|Object} + */ + securityDetails() { + return this._securityDetails; + } + /** * @return {!Promise} */ @@ -631,6 +648,59 @@ function generateRequestHash(request) { return JSON.stringify(hash); } +class SecurityDetails { + /** + * @param {string} subjectName + * @param {string} issuer + * @param {number} validFrom + * @param {number} validTo + * @param {string} protocol + */ + + constructor(subjectName, issuer, validFrom, validTo, protocol) { + this._subjectName = subjectName; + this._issuer = issuer; + this._validFrom = validFrom; + this._validTo = validTo; + this._protocol = protocol; + } + + /** + * @return {string} + */ + subjectName() { + return this._subjectName; + } + + /** + * @return {string} + */ + issuer() { + return this._issuer; + } + + /** + * @return {number} + */ + validFrom() { + return this._validFrom; + } + + /** + * @return {number} + */ + validTo() { + return this._validTo; + } + + /** + * @return {string} + */ + protocol() { + return this._protocol; + } +} + NetworkManager.Events = { Request: 'request', Response: 'response', diff --git a/test/test.js b/test/test.js index 98df734543e..d2a43175493 100644 --- a/test/test.js +++ b/test/test.js @@ -150,6 +150,8 @@ describe('Puppeteer', function() { const response = await page.goto(httpsServer.EMPTY_PAGE).catch(e => error = e); expect(error).toBe(null); expect(response.ok()).toBe(true); + expect(response.securityDetails()).toBeTruthy(); + expect(response.securityDetails().protocol()).toBe('TLS 1.2'); browser.close(); }); it('should reject all promises when browser is closed', async() => {