| Component | Version
|-|-
| Operating system | Ubuntu 16.04
| Node.js | 8.11.1
| Chrome/Chromium/... | 66.0.3359.117
| chrome-remote-interface | 0.25.5
Is Chrome running in a container? YES
Getting the error in the latest version of stable chrome
From the issue template (emphasis of mine):
Alright then, please provide the following information along with a detailed
description of what went wrong.
Should I guess under what circumstances you get that error?
just connect to the chrome running in a container
$ docker pull yukinying/chrome-headless-browser:66.0.3359.26
$ docker run --cap-add=SYS_ADMIN yukinying/chrome-headless-browser:66.0.3359.26
DevTools listening on ws://0.0.0.0:9222/devtools/browser/12544890-20bd-41b7-a74a-bcc35e4c0cce
$ chrome-remote-interface -t 172.17.0.2 inspect
>>> Browser.getVersion()
...
{ protocolVersion: '1.3',
product: 'HeadlessChrome/66.0.3359.26',
revision: '@b3471a2c378d1cfc5be97bb38b9c32038d1aef14',
userAgent: 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/66.0.3359.26 Safari/537.36',
jsVersion: '6.6.346.6' }
if you check from none localhost and different subset, you can set the error,
The issue is clear and has nothing to do with containers, the change has been introduced here and now Chrome doesn't allow that, as the error message says, the host header contains a domain other than localhost, the reason is described in this issue which unfortunately is private.
I can see two possible solutions:
host header and set it to the empty string;The problem with solution 1. is that the host header is is also used by Chrome to craft the webSocketDebuggerUrl and setting the host to the empty string results in the following:
$ curl -H host: localhost:9222/json/list
[ {
"description": "",
"devtoolsFrontendUrl": "/devtools/inspector.html?ws=/devtools/page/A4566872556EA7F94C344A8ABEA30A73",
"id": "A4566872556EA7F94C344A8ABEA30A73",
"title": "about:blank",
"type": "page",
"url": "about:blank",
"webSocketDebuggerUrl": "ws:///devtools/page/A4566872556EA7F94C344A8ABEA30A73"
} ]
And this is something that should be addressed on the Chrome side IMO.
how to override the default host header? if we can regenerated webSocketDebuggerUrl for temporary workaround, can be work?
how to override the default host header?
Like this:
--- a/lib/external-request.js
+++ b/lib/external-request.js
@@ -4,6 +4,7 @@ const REQUEST_TIMEOUT = 10000;
// callback(err, data)
function externalRequest(transport, options, callback) {
+ options.headers = {host: 'localhost'};
const request = transport.get(options, function (response) {
let data = '';
response.on('data', function (chunk) {
if we can regenerated webSocketDebuggerUrl for temporary workaround, can be work?
It could be but since the webSocketDebuggerUrl issue appears to be a bug of Chrome I would wait a response from the Chromium team.
The simplest workaround is IMHO using the IP address directly.
So from now on it should work transparently, CRI will resolve the host and use the IP address directly for the HTTP communication.
the workaround doesn't work when the same ip address use for many subdomains
Yes, I guess you need some intermediate agent to do that. My suggestion is to simply get rid of sub domains/virtual hosts to expose Chrome to the network and just rely on the fact that it listens on a different (than any other server) port. If you have many instances change the port number accordingly.
Unfortunately, this is something that I can't solve from here for every possible case.
If you thoroughly describe your scenario I could be more specific.
Hello,
I was stuck at this problem as well until I found a workaround for it.
so my workaround was to override the host header and set it to localhost the replace the actual host by localhost on webSocketDebuggerUrl
my implementation on Golang for this workaround:
https://github.com/chromedp/chromedp/issues/505#issuecomment-549188061
This makes modern versions of chrome-remote-interface fail with Firefox's implementation of Chrome RDP because Firefox requires the Host header to be localhost:12345 (12345 => remote debugger port). Perhaps a simpler/cleaner workaround would be to set Host header explicitly?
options.headers = {Host: `localhost:${options.port}`}
in lib/external-request.js
@lachesis latest chrome-remote-interface seems to work fine with latest Firefox, what scenario are you referring?
We were receiving 400 errors trying to list available debugger endpoints. Perhaps we were running a slightly outdated version. It was definitely a version with the patch from May 2018, but may be missing some later patches that fixed Firefox compatibility.
We decided not to continue with adding Firefox support to our product as their implementation of the Chrome debug protocol is missing some major methods that we need (DOM.describeNode mostly), so I will not be able to investigate further right now.
In my case, I used k8s service name as the link URL, so I bypass the restriction by using DNS lookup to turn host name to IP address, then use it to connect the headless chrome instance.
const dns = require('dns').promises;
const { address } = await dns.lookup("chrome-service", {
family: 4,
hints: dns.ADDRCONFIG,
});
const browser = await puppeteer.connect({
browserURL: `http://${address}:9222`,
});
It works.
Most helpful comment
Like this:
It could be but since the
webSocketDebuggerUrlissue appears to be a bug of Chrome I would wait a response from the Chromium team.The simplest workaround is IMHO using the IP address directly.