How to handle http requests which not ends (with (-out bearer) token)

Hello,

i have a device which streams the status line by line (at connection and if changed) but does not end the connection.
I tried the http-request node and the www-request node but both will get only timeouts without send the already gotten message.
Here a example of the never ending connection with curl:

user@host:~$ ${CURL_EXE} -X GET http://${ANTHOST}/api/v1/miner/status -H "Authorization: ${TOKEN}" -H "Content-Type: application/json"
{"status":3}
{"status":2}
{"status":3}

I must kill the curl to get it back.
Normally I want only the first line and then the connection could be closed. But also a never closed connection is ok as long each json line will result in a messag on the output node.

I tried it by injecting the complete parameters to the input node. With other api targets which will closed after response I have no problem.

How can I handle such a connection and which module can I use?
The authentification is also a little bit tricky because the token will expire after some time so a hard stored value is not possible (it's not a Bearing token because Bearing word is not allowed, check the curl line for details).

Any idea?

Gemini was helping me after I ask to use the tcp request node. It has a limit feature which I used ( 2000 ms) and I added simply a function node with a simple line by line exception json parser code. The preparation for the input was a little bit more complex. That works for me.

I'm glad you found a solution.

You didn't give much in the way of details but it does sound like something that should be possible with the standard nodes and without writing a custom json parser.

Oh it's really simple in this way so you will not get an warning or error:

I get this answer from the tcp node:
{"payload":"HTTP/1.1 200 OK\r\nconnection: close\r\ntransfer-encoding: chunked\r\ndate: Fri, 24 Jul 2026 17:28:33 GMT\r\n\r\nD\r\n{\"status\":3}\n\r\n","_msgid":"0eddd21306c59baf","url":"http://192.168.16.165/api/v1/auth/login","method":"POST","statusCode":200,"headers":{"content-type":"application/json","content-length":"45","date":"Fri, 24 Jul 2026 17:28:32 GMT","x-node-red-request-node":"e67885d2"},"responseUrl":"http://192.168.16.165/api/v1/auth/login","redirectList":[],"retry":0,"host":"192.168.16.165","port":80}

Simply split is by lines with a loop line by line put each to the json parser.
Catch the expeption to do nothing.
If a json is found make whatever you want with it like store them in the msg.payload

let rawData = msg.payload;

if (rawData && typeof rawData === 'string') {
    // In einzelne Zeilen zerlegen
    let lines = rawData.split('\n');

    for (let line of lines) {
        line = line.trim();
        if (!line) continue;

        // Versuchen, jede Zeile direkt als JSON zu parsen
        try {
            let data = JSON.parse(line);

            // Prüfen, ob das geparste JSON unsere "status"-Eigenschaft enthält
            if (data && data.status !== undefined) {
                let statusVal = data.status;

                // Status im Context speichern
                flow.set('miner_status_code', statusVal);
                
                let statusText = (statusVal === 2 ? "normal" : (statusVal === 3 ? "paused" : `status_${statusVal}`));
                flow.set('miner_api_status', statusText);

                // Visuelles Feedback am Node
                let timeStr = new Date().toLocaleTimeString();
                node.status({
                    fill: (statusVal === 2 ? "green" : "yellow"),
                    shape: "dot",
                    text: `Status: ${statusVal} (${statusText}) [${timeStr}]`
                });

                // Geparstes JSON als Payload ausgeben
                msg.payload = data;
                return msg;
            }
        } catch (e) {
            // Header, Chunk-Größen (wie "D") etc. schlagen fehl und werden einfach übersprungen
        }
    }
}

return null;

Here the preparation code for the tcp node:

let minerIp = flow.get('miner_ip');
let token = flow.get('miner_token');

if (!token) {
    node.error("Kein miner_token im Flow-Kontext vorhanden!");
    return null;
}

// HTTP/1.1 Request Header manuell zusammensetzen
// Wichtig: \r\n als Zeilenumbruch und \r\n\r\n am Ende des Headers!
let rawHttpRequest = 
    `GET /api/v1/miner/status HTTP/1.1\r\n` +
    `Host: ${minerIp}\r\n` +
    `User-Agent: Node-RED\r\n` +
    `Authorization: ${token}\r\n` +
    `Content-Type: application/json\r\n` +
    `Connection: close\r\n` +
    `\r\n`;

msg.host = minerIp;
msg.port = 80;
msg.payload = rawHttpRequest;

return msg;

The tcp node is configured: