Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Unix Domain Sockets #120

Merged
merged 1 commit into from
Aug 30, 2023
Merged

Conversation

JurajKubelka
Copy link
Contributor

@JurajKubelka JurajKubelka commented Aug 30, 2023

Introduction

The aim of the presented changes is to be able to communicate with HTTP servers over Unix Domain Sockets.

For example to communicate with a Docker Engine, the following code can be executed from a terminal:

curl --unix-socket /var/run/docker.sock http://localhost/v1.43/containers/json

This pull request implements a ZnUnixSocketClient that can be used as follows:

ZnUnixSocketClient new 
	beOneShot;
	unixSocket: '/var/run/docker.sock';
	get: 'http://localhost/v1.43/containers/json'

ZnUnixSocketClient is a subclass of ZnClient and placed in a Zinc-HTTP-UnixSocket package.

Implementation details

  • implement ZnUnixSocketClient
  • implement ZnUnixSocketClientTest
  • add the Zinc-HTTP-UnixSocket package to a baseline.

@svenvc svenvc marked this pull request as ready for review August 30, 2023 12:40
@svenvc svenvc merged commit a1e4d39 into svenvc:master Aug 30, 2023
5 checks passed
@svenvc
Copy link
Owner

svenvc commented Aug 30, 2023

I am merging this: this is clean extension code in a separate package.

I wil now try to run it myself.

@svenvc
Copy link
Owner

svenvc commented Aug 30, 2023

(continuing our email conversation)

Netcat is nc, I think it is standard on macOS and Linux.

I was able to start a server using

$ sudo nc -v -l -U /var/run/test.sock

and connect to it using

$ sudo telnet -u /var/run/test.sock

just type something and hit return.

Here are some links with more info

This is not enough to build a real unit test, but it should allow users to run something.

@svenvc
Copy link
Owner

svenvc commented Aug 30, 2023

Now, when I try the above, I get an error: it seems the method connectTo: on Socket is not in my Pharo 11 image as called from unixSocketOnFile:

Is that something you added and forgot to include ?

@svenvc
Copy link
Owner

svenvc commented Sep 4, 2023

OK, with the missing connectTo: method I can run the code, I can connect with the client to a unix socket (provided I own it) on macOS. The HTTP comes through, but I need to figure out how to answer.

@JurajKubelka
Copy link
Contributor Author

Thank you! Do you think that we can make the ZnServer to listen to the unix socket? I have looked at the server code, but I was not sure about it.

@svenvc
Copy link
Owner

svenvc commented Sep 4, 2023

I don't know.

But the first problem is that I think something is wrong with the reading part in Pharo.

If you try with the nc/telnet example (BTW, you have to delete the socket to start over), you can send data from telnet to nc and back.

The following would be a correct HTTP response:

HTTP/1.1 200 OK
Server: Zinc HTTP Components 1.0 (Pharo/11.0)
Date: Mon, 04 Sep 2023 14:12:57 GMT
Content-Type: text/plain;charset=utf-8
Content-Length: 2

OK

which goes back to telnet, but never to Pharo.

Oh, you also need a unix socket that you own yourself.

Are you sure reading works ? It seems to be stuck in waiting for data.

@JurajKubelka
Copy link
Contributor Author

I am not sure it is correct. I have tested it against Docker unix socket and it works (Pharo 10 and GToolkit based on Pharo 10). There is an example of the Docker answer:

Screenshot 2023-09-04 at 11 22 46

@JurajKubelka
Copy link
Contributor Author

BTW: The Unix Socket implementation is taken from here: https://samadhiweb.com/blog/2013.07.27.unixdomainsockets.html

@svenvc
Copy link
Owner

svenvc commented Sep 4, 2023

Ah OK, that is great.

I guess it should be possible to run nginx locally, serving on a unix domain socket. I would like to see that first.

@JurajKubelka
Copy link
Contributor Author

It is good idea to use nginx. I will try.

Does it work for you on Pharo 11? I can

Screenshot 2023-09-04 at 11 30 53

It works for me on Pharo 10:
Screenshot 2023-09-04 at 11 34 03

@svenvc
Copy link
Owner

svenvc commented Sep 4, 2023

I am on Pharo 11

I had to use a socket like this /Users/sven/tmp/test.sock (one that is owned by my user)

I am trying to configure nginx under brew BTW

@svenvc
Copy link
Owner

svenvc commented Sep 4, 2023

I got it to work!

Installed nginx via brew and edited /usr/local/etc/nginx/nginx.conf

    server {
        listen       8080;
	listen       unix:/Users/sven/tmp/nginx.sock;
        server_name  localhost;

        location / {
            root   html;
            index  index.html index.htm;
        }
       ...
   }

Now I can do

telnet -u /Users/sven/tmp/nginx.sock
GET /

curl --unix-socket /Users/sven/tmp/nginx.sock http://localhost

and I get HTML back.
In Pharo I can then do:

ZnUnixSocketClient new
	unixSocket: '/Users/sven/tmp/nginx.sock';
	get: 'http://localhost/'.

And I get the same HTML.

Now we can start thinking about the server side, maybe simple socket server would better to start with.

I am still not sure how the socket permissions have to be.

@svenvc
Copy link
Owner

svenvc commented Sep 4, 2023

But now that I am home, I also get a NetNameResolver error, where it worked before. So maybe somehow this works only once. Restarting the image does not help.

@svenvc
Copy link
Owner

svenvc commented Sep 4, 2023

OK, I think I found it, NetNameResolver initializeNetwork is missing (see the last comment at the end of https://samadhiweb.com/blog/2013.07.27.unixdomainsockets.html)

@JurajKubelka
Copy link
Contributor Author

JurajKubelka commented Sep 4, 2023

I see. Will you commit the change in ZnNetworkingUtils>>#unixSocketOnFile:?

BTW. Now it works for me in both, Pharo 10 and 11.

@svenvc
Copy link
Owner

svenvc commented Sep 5, 2023

Hi @JurajKubelka

I did a small refactoring (as per the blog post), it feels cleaner to me.

a6f7fa3

Sven

@JurajKubelka
Copy link
Contributor Author

Hi @svenvc,

thank you for the refactoring. It looks better now.

Juraj

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants