Requesting webSocketDebuggerUrl from Chrome-Headless in Docker Container - docker

Setup
Trying to run chrome headless as a container (Image: https://hub.docker.com/r/alpeware/chrome-headless-trunk) in my docker-compose and connecting to it from another container.
Problem
To actually connect to chrome inside the container, I first need to retrieve the webSocketDebuggerUrl, which is available at http://0.0.0.0:9222/json/version of the chrome-headless.
The Problem is: my request to this path always fails with
RequestError: Error: connect ECONNREFUSED 0.0.0.0:9222
and cant get the webSocketDebuggerUrl to connect to chrome.
Some more Info
Also if I visit http://0.0.0.0:9222/json/version in my browser myself, copy the url and hardcode it into my puppeteer.connect(), it ONLY works as expected, if I replace the address of '0.0.0.0' to my (linked) container-name (specified in docker-compose): http://chrome:9222/json/version
If I try to request the webSocketDebuggerUrl from /json/version while using container-name address (http://chrome:9222/json/version) i get the error
StatusCodeError: 500 - "Host header is specified and is not an IP address or localhost."
My Code (abstraction)
const rp = require('request-promise')
const puppeteer = require('puppeteer-core')
let url = await rp({uri:'http://0.0.0.0:9222/json/version', json: true }).then(res => res.webSocketDebuggerUrl)
let browser = await puppeteer.connect({ browserWSEndpoint: url })

Well, since the errorMessage from the 500 said "host is specified", ist just set that header to empty, and now I can successfully request the webSocketDebuggerUrl.
The solution feels a bit hacky, so if anyone has a suggestion on how to improve it I'd be happy:
const puppeteer = require('puppeteer-core')
const rp = require('request-promise')
let websocket = await rp({uri:'http://chrome:9222/json/version', json: true, headers: {'Host': ''} })
.then(res => res.webSocketDebuggerUrl.replace('ws://','ws://chrome:9222'))
let browser = await puppeteer.connect({ browserWSEndpoint: websocket })

Related

Using Akka stream sftp to transfer file from local to debian docker container : Connection Timeout

I'm currently trying to establish a connection between my local and docker container to test out transferring files from the local to the docker container. However, I keep getting either Connection Timeout and the server won't connect. Here's one of the functions that raise the error.
In setting up my docker container, I set up ssh and kept the ssh service running. And set up the password for it. Also, for some reason, replacing 0.0.0.0 with localhost causes more problems.
I also got UserAuthentication errors when I added authPassword or authPublicKey after the connect().
Can anyone help me debug this?
val credentials = Ftpcredentials.create("username","password")
val sftpSettings = SftpSettings(InetAddress.getByName("0.0.0.0"))
.withPort(22)
.withCredentials(credentials)
.withStrictHostKeyChecking(false)
val sshClient: SSHClient = new SSHClient(new DefaultConfig)
sshClient.addHostKeyVerifier(new PromiscuousVerifier)
val configuredClient: SftpApi = Sftp(sshClient)
def mkdir(basePath: String, directoryName: String) = {
val tempSink = (Placeholder Sink)
sshClient.connect("0.0.0.0",22)
Await.result(
configuredClient
.ls(basePath, sftpSettings)
.toMat(tempSink)(Keep.right)
.run()
.map(
exists =>
if (!exists) {
configuredClient
.mkdir(basePath, directoryName, sftpSettings)
.run()
}
), Duration(45.0, SECONDS)
)
}

Posting API request from one Docker container to another

I've been following this post on Medium to learn how to create and run a dotnet core console app in a docker container, and post to a dotnet core API in another container.
When I run the two applications side-by-side (without docker, i.e. just debugging in vscode), everything works OK - the console app can post to the API. However, when I run the applications in containers using docker-compose up --build, I get an error when the application tries to post to the api:
Unhandled exception. System.AggregateException: One or more errors occurred. (The SSL connection could not be established, see inner exception.)
System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.
System.IO.IOException: The handshake failed due to an unexpected packet format.
Searching for solutions to this error hasn't helped much, and I feel that the problem may simply be connectivity between the two containers, but I've had no luck trying to resolve it.
My docker-compose file is as follows:
version: '3.4'
services:
publisher_api:
image: my_publisher_api:latest
container_name: my_publisher_api_container
build:
context: ./publisher_api
dockerfile: Dockerfile
worker:
image: my_worker
container_name: my_worker_container
depends_on:
- "publisher_api"
build:
context: ./worker
dockerfile: Dockerfile
My console app code (or at least the relevant part) is:
public static async Task PostMessage(object postData)
{
var json = JsonConvert.SerializeObject(postData);
var content = new StringContent(json, UnicodeEncoding.UTF8, "application/json");
using (var httpClientHandler = new HttpClientHandler())
{
httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return true; };
using (var client = new HttpClient(httpClientHandler))
{
var result = await client.PostAsync("https://my_publisher_api_container:80/values", content);
string resultContent = await result.Content.ReadAsStringAsync();
Console.WriteLine($"Server returned {resultContent}");
}
}
}
I wont post any of the API code, as I dont think any of it should be relevant, but please let me know if you think it would help.
If anyone has any idea on what the cause of this error is or how to resolve it, I'd appreciate the help.
Edit
Thought it would be useful to include the versions being used:
dotnet core: 3.0.101
docker: 19.03.5, build 633a0ea838
Looks like I had mad a couple of fairly obvious mistakes, however they're not so obvious when you're completely new to Docker, like me.
The hostname to post to should be the name of the service, not the container.In my case, I had to change the console app to post to the name of the API service declared in the docker-compose file, publisher_api.
Use HTTP instead of HTTPS. When I debugged the API locally, it launches with HTTPS by default. I assumed I would use HTTPS when running the container in docker, but this doesn't seem to work by default. Changing to HTTP resolved the issue (although this ideally will be a short-term solution).
So just for completeness, here's my updated code. Only the URL that the console app posts to had to change:
public static async Task PostMessage(object postData)
{
var json = JsonConvert.SerializeObject(postData);
var content = new StringContent(json, UnicodeEncoding.UTF8, "application/json");
using (var httpClientHandler = new HttpClientHandler())
{
httpClientHandler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return true; };
using (var client = new HttpClient(httpClientHandler))
{
var result = await client.PostAsync("http://publisher_api80/values", content);
string resultContent = await result.Content.ReadAsStringAsync();
Console.WriteLine($"Server returned {resultContent}");
}
}
}

Flutter HTTP Get Request Wrong Port

i try to perform a GET request to my localhost server. i run the flutter application on a external device with android studio and the XAMPP/php server with the endpoint run on the pc too. now is the problem every time i run the GET request it run on a wrong port. i write in the url port 80 but flutter perform it on 53555 or other 53...
i try to change the url but nothing changed.
here is the code and the error message
var url = new Uri.http("192.168.2.23:80", "/login", {"username":username,"password":password});
print(url);
var client = http.Client();
http.Response response = await client.get(url);
print('Response status: ${response.statusCode}');
print('Response body: ${response.body}');
this is the error
[ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: SocketException: OS Error: Connection timed out, errno = 110, address = 192.168.2.23, port = 53695

Unexpected HTTP Request: POST /mqtt/auth

I am new to emqtt. I am trying to use emq_auth_http but it is not working.
I have these 3 requests to console some data and send data back with status 200.
app.post('/mqtt/auth', function(req, res) {
console.log('This is body ', req.body);
res.status(200).send(req.body);
});
app.post('/mqtt/superuser', function(req, res) {
console.log('This is body in superuser ', req.body);
res.status(200).send(req.body);
});
app.get('/mqtt/acl', function(req, res) {
console.log('This is params in acl ', req.params);
res.status(200).send(req.body);
});
Requests are working fine on postman.
I have configured my emqtt on windows with docker. I have placed my config file in /etc/plugins/emq_auth_http.conf.
This is my config file
## Variables: %u = username, %c = clientid, %a = ipaddress, %P = password, %t = topic
auth.http.auth_req = http://127.0.0.1:3000/mqtt/auth
auth.http.auth_req.method = post
auth.http.auth_req.params = clientid=%c,username=%u,password=%P
auth.http.super_req = http://127.0.0.1:3000/mqtt/superuser
auth.http.super_req.method = post
auth.http.super_req.params = clientid=%c,username=%u
## 'access' parameter: sub = 1, pub = 2
auth.http.acl_req = http://127.0.0.1:3000/mqtt/acl
auth.http.acl_req.method = get
auth.http.acl_req.params =
access=%A,username=%u,clientid=%c,ipaddr=%a,topic=%t
Then I enabled emq_auth_http from dashboard
Now when I tried to connect my mqtt client to my server it is not calling the api. It logs
09:28:29.642 [error] Unexpected HTTP Request: POST /mqtt/auth
09:28:29.644 [error] Client(19645050-9d1b-4c50-acf9-
c1fe7e69eea8#172.17.0.1:60968): Username 'username' login failed for 404
Is there anything I missed? Why it is not working?
Thanks
127.0.0.1 in a container refers to the container itself and not the host machine. you should set the host machine ip,you can obtain the host machine ip from a container by issuing the command /sbin/ip route|awk '/default/ { print $3 }' which could be found here
ps: this way you can get the ip of docker machine and not the host ,if your service is served by windows you can reach the ip of host machine from the container which is 10.0.75.1. you can find it in
How to connect to docker host from container on Windows 10 (Docker for Windows)

Jupyter: XSRF cookie does not match POST

I am trying to transfert files using a python program running on a local Anaconda to a local Jupyter within a docker container using the Jupyter rest API.
I managed already to execute a requests.get() succesfully after muddling-through a bit on how to input the token.
Now I would like now to execute a requests.post() command to transfert the files.
Configuration:
local docker container running on docker toolbox for windows
docker version 17.04.0-ce, build 4845c56
tensorflow/tensorflow incl. Jupyter latest version install
jupyter_kernel_gateway==0.3.1
local Anaconda v. 4.3.14 running on a windows 10 machine
Code:
token = token_code_provided_by_jupyter_at_startup
api_url = "http://192.168.99.100:8888/api/contents"
# getting the file's data from disk and converting into a json file
cwd = os.getcwd()
file_location = cwd+r'\Resources\Test\test_post.py'
payload = open(file_location, 'r').read()
b64payload = base64.encodestring(payload)
body = json.dumps({
'content':b64payload,
'name': 'test_post.py',
'path': '/api/contents/',
'format': 'base64',
'type':'file'
})
# getting the xsrf cookie
client = requests.session()
client.get('http://192.168.99.100:8888/')
csrftoken = client.cookies['_xsrf']
headers ={'Content-type': 'application/json', 'X-CSRFToken':csrftoken, 'Referer':'http://192.168.99.100:8888/api/contents', 'token':token}
response = requests.post(api_url, data=body, headers=headers, verify=True)
Error returned
[W 12:22:36.710 NotebookApp] 403 POST /api/contents (192.168.99.1): XSRF cookie does not match POST argument
[W 12:22:36.713 NotebookApp] 403 POST /api/contents (192.168.99.1) 4.17ms referer=http://192.168.99.100:8888/api/contents
My solution is inspired by #SaintNazaire. In my Chrome browser, I opened the cookie folder and found the repeated _xsrf items in Cookies. I removed all of them and refreshed the Jupyter, and then everything went well.
Actually there is no need for xsrf cookie when using header token for authentification.
headers = {'Authorization': 'token ' + token}
Reference is made to the Jupyter notebook documentation.
http://jupyter-notebook.readthedocs.io/en/latest/security.html

Resources