From acd1290168ab909d8a9416fe6adcdfe35958bf69 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Fri, 30 Aug 2019 22:39:05 +0200 Subject: [PATCH 1/3] fix: Patch downstream responses for unknown upstream protocol --- lib/jsonwp-proxy/protocol-converter.js | 21 ++++++++++++++++ lib/jsonwp-proxy/proxy.js | 34 ++++++-------------------- 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/lib/jsonwp-proxy/protocol-converter.js b/lib/jsonwp-proxy/protocol-converter.js index e598fe34d..56de84a38 100644 --- a/lib/jsonwp-proxy/protocol-converter.js +++ b/lib/jsonwp-proxy/protocol-converter.js @@ -2,6 +2,7 @@ import _ from 'lodash'; import { logger, util } from 'appium-support'; import { duplicateKeys } from '../basedriver/helpers'; import { PROTOCOLS, MJSONWP_ELEMENT_KEY, W3C_ELEMENT_KEY } from '../protocol/protocol'; +import { errors } from '../protocol/errors'; const log = logger.getLogger('Protocol Converter'); @@ -187,6 +188,21 @@ class ProtocolConverter { : await this.proxyFunc(url, method, body); } + async proxyGetStatus (url, method, body) { + const [res, resBodyObj] = await this.proxyFunc(url, method, body); + if (!_.isPlainObject(resBodyObj)) { + return [res, resBodyObj]; + } + const patchedBody = _.clone(resBodyObj); + if (!_.has(resBodyObj, 'status')) { + resBodyObj.status = res.statusCode === 200 ? 0 : errors.UnknownError.code(); + } + if (!_.has(patchedBody, 'sessionId')) { + patchedBody.sessionId = null; + } + return [res, patchedBody]; + } + /** * Handle "crossing" endpoints for the case * when upstream and downstream drivers operate different protocols @@ -199,6 +215,11 @@ class ProtocolConverter { */ async convertAndProxy (commandName, url, method, body) { if (!this.downstreamProtocol) { + if (commandName === 'getStatus') { + // Patch getStatus call for GENERIC protocol + // to preserve the backward compatibility + return await this.proxyGetStatus(url, method, body); + } // There is no point to convert anything if we do not know // for which protocol the conversion should be done return await this.proxyFunc(url, method, body); diff --git a/lib/jsonwp-proxy/proxy.js b/lib/jsonwp-proxy/proxy.js index c9a956165..7c7e4cf6f 100644 --- a/lib/jsonwp-proxy/proxy.js +++ b/lib/jsonwp-proxy/proxy.js @@ -118,28 +118,6 @@ class JWProxy { return proxyBase + remainingUrl; } - syncDownstreamProtocol (resBodyObj, isSessionCreationRequest) { - if (!this.downstreamProtocol) { - this.downstreamProtocol = this.getProtocolFromResBody(resBodyObj); - log.debug(`Determined the downstream protocol as '${this.downstreamProtocol}'`); - } else if (isSessionCreationRequest) { - // It might be that we proxy API calls to the downstream driver - // without creating a session first - // and it responds using the default proto, - // but then after createSession request is sent the internal proto is changed - // to the other one based on the actually provided caps - const previousValue = this.downstreamProtocol; - this.downstreamProtocol = this.getProtocolFromResBody(resBodyObj); - if (previousValue && previousValue !== this.downstreamProtocol) { - log.debug(`Updated the downstream protocol to '${this.downstreamProtocol}' ` + - `as per session creation request`); - } else { - log.debug(`Determined the downstream protocol as '${this.downstreamProtocol}' ` + - `per session creation request`); - } - } - } - async proxy (url, method, body = null) { method = method.toUpperCase(); const newUrl = this.getUrlForProxy(url); @@ -201,12 +179,14 @@ class JWProxy { log.debug(`Got response with status ${res.statusCode}: ${truncateBody(res.body)}`); isResponseLogged = true; const isSessionCreationRequest = /\/session$/.test(url) && method === 'POST'; - if (isSessionCreationRequest && res.statusCode === 200) { - this.sessionId = resBodyObj.sessionId || (resBodyObj.value || {}).sessionId; + if (isSessionCreationRequest) { + if (res.statusCode === 200) { + this.sessionId = resBodyObj.sessionId || (resBodyObj.value || {}).sessionId; + } + this.downstreamProtocol = this.getProtocolFromResBody(resBodyObj); + log.debug(`Determined the downstream protocol as '${this.downstreamProtocol}'`); } - this.syncDownstreamProtocol(resBodyObj, isSessionCreationRequest); - if (res.statusCode < 400 && this.downstreamProtocol === MJSONWP && - _.has(resBodyObj, 'status') && parseInt(resBodyObj.status, 10) !== 0) { + if (res.statusCode < 400 && _.has(resBodyObj, 'status') && parseInt(resBodyObj.status, 10) !== 0) { // Some servers, like chromedriver may return response code 200 for non-zero JSONWP statuses throwProxyError(resBodyObj); } From 2899edd29eb11ea9920fbd27cc8c1a118e611773 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Sat, 31 Aug 2019 07:53:29 +0200 Subject: [PATCH 2/3] Only add status --- lib/jsonwp-proxy/protocol-converter.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/jsonwp-proxy/protocol-converter.js b/lib/jsonwp-proxy/protocol-converter.js index 56de84a38..0a8ca2ba6 100644 --- a/lib/jsonwp-proxy/protocol-converter.js +++ b/lib/jsonwp-proxy/protocol-converter.js @@ -197,9 +197,6 @@ class ProtocolConverter { if (!_.has(resBodyObj, 'status')) { resBodyObj.status = res.statusCode === 200 ? 0 : errors.UnknownError.code(); } - if (!_.has(patchedBody, 'sessionId')) { - patchedBody.sessionId = null; - } return [res, patchedBody]; } From 36946312b6f16f94b93539ad48e3a8289d2245fc Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Sat, 31 Aug 2019 08:00:35 +0200 Subject: [PATCH 3/3] Change the log level --- lib/jsonwp-proxy/proxy.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/jsonwp-proxy/proxy.js b/lib/jsonwp-proxy/proxy.js index 7c7e4cf6f..fc8a51613 100644 --- a/lib/jsonwp-proxy/proxy.js +++ b/lib/jsonwp-proxy/proxy.js @@ -184,7 +184,7 @@ class JWProxy { this.sessionId = resBodyObj.sessionId || (resBodyObj.value || {}).sessionId; } this.downstreamProtocol = this.getProtocolFromResBody(resBodyObj); - log.debug(`Determined the downstream protocol as '${this.downstreamProtocol}'`); + log.info(`Determined the downstream protocol as '${this.downstreamProtocol}'`); } if (res.statusCode < 400 && _.has(resBodyObj, 'status') && parseInt(resBodyObj.status, 10) !== 0) { // Some servers, like chromedriver may return response code 200 for non-zero JSONWP statuses