(url, method, body = null)
| 136 | } |
| 137 | |
| 138 | async proxy (url, method, body = null) { |
| 139 | method = method.toUpperCase(); |
| 140 | const newUrl = this.getUrlForProxy(url); |
| 141 | const truncateBody = (content) => _.truncate( |
| 142 | _.isString(content) ? content : JSON.stringify(content), |
| 143 | { length: MAX_LOG_BODY_LENGTH }); |
| 144 | const reqOpts = { |
| 145 | url: newUrl, |
| 146 | method, |
| 147 | headers: { |
| 148 | 'content-type': 'application/json; charset=utf-8', |
| 149 | 'user-agent': 'appium', |
| 150 | accept: 'application/json, */*', |
| 151 | }, |
| 152 | proxy: false, |
| 153 | timeout: this.timeout, |
| 154 | httpAgent: this.httpAgent, |
| 155 | httpsAgent: this.httpsAgent, |
| 156 | }; |
| 157 | // GET methods shouldn't have any body. Most servers are OK with this, but WebDriverAgent throws 400 errors |
| 158 | if (util.hasValue(body) && method !== 'GET') { |
| 159 | if (typeof body !== 'object') { |
| 160 | try { |
| 161 | reqOpts.data = JSON.parse(body); |
| 162 | } catch (e) { |
| 163 | throw new Error(`Cannot interpret the request body as valid JSON: ${truncateBody(body)}`); |
| 164 | } |
| 165 | } else { |
| 166 | reqOpts.data = body; |
| 167 | } |
| 168 | } |
| 169 | |
| 170 | log.debug(`Proxying [${method} ${url || '/'}] to [${method} ${newUrl}] ` + |
| 171 | (reqOpts.data ? `with body: ${truncateBody(reqOpts.data)}` : 'with no body')); |
| 172 | |
| 173 | const throwProxyError = (error) => { |
| 174 | const err = new Error(`The request to ${url} has failed`); |
| 175 | err.response = { |
| 176 | data: error, |
| 177 | status: 500 |
| 178 | }; |
| 179 | throw err; |
| 180 | }; |
| 181 | let isResponseLogged = false; |
| 182 | try { |
| 183 | const {data, status, headers} = await this.request(reqOpts); |
| 184 | // `data` might be really big |
| 185 | // Be careful while handling it to avoid memory leaks |
| 186 | if (!_.isPlainObject(data)) { |
| 187 | // The response should be a valid JSON object |
| 188 | // If it cannot be coerced to an object then the response is wrong |
| 189 | throwProxyError(data); |
| 190 | } |
| 191 | log.debug(`Got response with status ${status}: ${truncateBody(data)}`); |
| 192 | isResponseLogged = true; |
| 193 | const isSessionCreationRequest = /\/session$/.test(url) && method === 'POST'; |
| 194 | if (isSessionCreationRequest) { |
| 195 | if (status === 200) { |
no test coverage detected