1

I want to use signald via web. signald is an application that provides a unix socket and communicates in JSON.

I can use nginx to connect to the unix socket via HTTP(S). But signald does not understand HTTP, only pure JSON. It produces errors like the following:

com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'GET': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false') at [Source: (String)"GET / HTTP/1.0"; line: 1, column: 4]

Is there a way to send JSON to my web-forwarded unix socket, just like any API that is served by a web server? I imagine something like nginx <-> http wrapper <-> unix socket.

1 Answers1

1

It took some time, but I found a solution. Basically, you have to use Lua to get the request body, send it to a unix socket, read the line and send it back as server response. Use nginx with lua like this:

First install nginx-extras

Load modules ndk_http_module and ngx_http_lua_module (in this order) in nginx.conf like this:

load_module modules/ndk_http_module.so;
load_module modules/ngx_http_lua_module.so;

This is the location block for your lua-enhanced connection to the unix socket. It will send the request data to the unix socket and read by using tcpsocket:receive(). It will say() the line as response.

    location / {
        content_by_lua_block {
            ngx.req.read_body()
            local body_data = ngx.req.get_body_data()

            local sock = ngx.socket.tcp()
            local ok, err = sock:connect("unix:/var/run/signald/signald.sock")

            local bytes = sock:send(body_data)

            local line, err, part = sock:receive()
            if line then
                ngx.say(line)
            end

            ok, err = sock:close()
        }
    }

Test it with a curl call like this (you don't have to care about Content-Type or method):

curl -d '{"type":"version"}' https://example.com:1234