| Line 274... |
Line 274... |
| 274 |
private void installResponseCapture(WebDriver driver) {
|
274 |
private void installResponseCapture(WebDriver driver) {
|
| 275 |
try {
|
275 |
try {
|
| 276 |
((JavascriptExecutor) driver).executeScript(
|
276 |
((JavascriptExecutor) driver).executeScript(
|
| 277 |
"if (!window.__rmCapInstalled) {"
|
277 |
"if (!window.__rmCapInstalled) {"
|
| 278 |
+ " window.__rmCapInstalled = true; window.__rmResp = null; window.__rmCaptcha = null; window.__rmSeen = [];"
|
278 |
+ " window.__rmCapInstalled = true; window.__rmResp = null; window.__rmCaptcha = null; window.__rmSeen = [];"
|
| 279 |
// axios can sit on either transport, and realme's page uses fetch --
|
279 |
// Three transports, because realme's page uses all of them and only the
|
| - |
|
280 |
// prototype-level patches are reliable.
|
| - |
|
281 |
//
|
| 280 |
// an XHR-only hook silently captures nothing, which is exactly what
|
282 |
// The lookup goes through Nuxt's $fetch (ofetch), which grabs its
|
| - |
|
283 |
// reference to globalThis.fetch when its bundle is evaluated -- long
|
| - |
|
284 |
// before driver.get() returns and we can wrap window.fetch. So wrapping
|
| - |
|
285 |
// window.fetch NEVER sees /active/check: verified on the live page, the
|
| - |
|
286 |
// same $fetch call is invisible to a window.fetch wrapper and visible to
|
| - |
|
287 |
// a Response.prototype one. That is why 526 solved captchas produced 0
|
| 281 |
// 'no active/check response captured' was reporting.
|
288 |
// rows: the answer arrived and we could not see it.
|
| - |
|
289 |
//
|
| - |
|
290 |
// Response.prototype.json / .text are resolved at call time, so patching
|
| - |
|
291 |
// them catches any client no matter when it took its fetch reference.
|
| 282 |
+ " var O = XMLHttpRequest.prototype.open;"
|
292 |
+ " var O = XMLHttpRequest.prototype.open;"
|
| 283 |
+ " XMLHttpRequest.prototype.open = function(m,u){"
|
293 |
+ " XMLHttpRequest.prototype.open = function(m,u){"
|
| 284 |
+ " this.addEventListener('load', function(){"
|
294 |
+ " this.addEventListener('load', function(){"
|
| 285 |
+ " try { var s=String(u);"
|
295 |
+ " try { var s=String(u);"
|
| 286 |
+ " if (s.indexOf('active/check') !== -1 || s.indexOf('customer-api') !== -1) window.__rmResp = this.responseText;"
|
296 |
+ " if (s.indexOf('active/check') !== -1 || s.indexOf('customer-api') !== -1) window.__rmResp = this.responseText;"
|
| Line 297... |
Line 307... |
| 297 |
+ " try { if (u.indexOf('active/check') !== -1 || u.indexOf('customer-api') !== -1) { r.clone().text().then(function(t){ window.__rmResp = t; }); }"
|
307 |
+ " try { if (u.indexOf('active/check') !== -1 || u.indexOf('customer-api') !== -1) { r.clone().text().then(function(t){ window.__rmResp = t; }); }"
|
| 298 |
+ " else if (window.__rmSeen.length < 12) window.__rmSeen.push('F ' + u.slice(0,80)); } catch(e){}"
|
308 |
+ " else if (window.__rmSeen.length < 12) window.__rmSeen.push('F ' + u.slice(0,80)); } catch(e){}"
|
| 299 |
+ " return r;"
|
309 |
+ " return r;"
|
| 300 |
+ " });"
|
310 |
+ " });"
|
| 301 |
+ " }; }"
|
311 |
+ " }; }"
|
| - |
|
312 |
// Read the body off the Response itself. Must use the ORIGINAL reader on
|
| - |
|
313 |
// the clone -- calling the patched one recurses forever (it hangs the page).
|
| - |
|
314 |
+ " ['json','text'].forEach(function(name){"
|
| - |
|
315 |
+ " var orig = Response.prototype[name];"
|
| - |
|
316 |
+ " if (!orig) return;"
|
| - |
|
317 |
+ " Response.prototype[name] = function(){"
|
| - |
|
318 |
+ " try { var u = this.url || '';"
|
| - |
|
319 |
+ " if ((u.indexOf('active/check') !== -1 || u.indexOf('customer-api') !== -1) && !this.__rmSeenBody) {"
|
| - |
|
320 |
+ " var c = this.clone(); c.__rmSeenBody = 1;"
|
| - |
|
321 |
+ " orig.call(c).then(function(t){ window.__rmResp = (typeof t === 'string') ? t : JSON.stringify(t); });"
|
| - |
|
322 |
+ " } else if (u && window.__rmSeen.length < 12 && u.indexOf('captcha') === -1) {"
|
| - |
|
323 |
+ " window.__rmSeen.push('R ' + u.slice(0,80));"
|
| - |
|
324 |
+ " } } catch(e){}"
|
| - |
|
325 |
+ " return orig.apply(this, arguments);"
|
| - |
|
326 |
+ " };"
|
| - |
|
327 |
+ " });"
|
| 302 |
+ "}");
|
328 |
+ "}");
|
| 303 |
} catch (Exception e) {
|
329 |
} catch (Exception e) {
|
| 304 |
LOGGER.warn("Could not install the response capture hook: " + e.getMessage());
|
330 |
LOGGER.warn("Could not install the response capture hook: " + e.getMessage());
|
| 305 |
}
|
331 |
}
|
| 306 |
}
|
332 |
}
|