Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Table of Contents
maxLevel2
typeflat

Overview

You can send single events or stream data to your Devo domain over HTTP. Generate a token for your HTTP endpoint in the Devo web application, then use that token to set up event sending from your HTTP endpoint.

...

The recommended way to send events to Devo is by using Syslog. However, there are situations where HTTP ingestion may be preferred, such as when direct TCP connections are not feasible or when clients need to integrate with systems that only support HTTP.

Devo offers two HTTP endpoints or modes for event ingestion:

  • Event mode - Designed to send one event per HTTP request.

  • Stream mode - Designed to send multiple events per HTTP request.

Note

Maximum file size

Note that there’s a limit of 32 MB when you use this sending method.

...

Rw ui steps macro
Rw step

Log in to your Devo domain and go to Administration → Credentials →   Authentication tokens.

Rw step

Click Create token.

Rw step

Enter a descriptive Name and choose the person that will use the token in the Authorized user field. This can be either yourself or a user in your domain.

Rw step

Select the destination Target table/s for the events. These are the tag or tags that will be used by Devo to classify the events. You can use wildcards to send the data to multiple tables. For example, to send the events to all tables that begin with "my.app", you can specify my.app.**. See the Authentication tokens section to learn more about how to use wildcards when identifying target tables.

Note

Note that it is not possible to ingest data to tables that receive events in CEF syslog format using this method.

Rw step

In the Type field, choose HTTP ingestion.

Rw step

Optionally, check the Expiration date field if you want to enter an expiration date for the new token. Choose the required date in the calendar.

Rw step

Click Create. The token is generated and appears in the token list below.

...

Element

Description

<endpoint>

  • USA: https://http-us.devo.io

  • Europe: https://http-eu.devo.io

  • Canada: https://http-ca.devo.io

  • Asia-Pacific (APAC):

    • https://collector-ap.devo.io:8443 to ingest in Singapore datanodes

    • https://collector-ap2.devo.io:8443 to ingest in Sydney datanodes

Use the endpoint that corresponds to the Devo Cloud region you use.

<mode>

This can be one of the following:

  • event - Use this mode to send single events. GET and POST methods are accepted. See some examples in the section below.

  • stream - Use this mode to send multiple events. Only POST is accepted. Use the header Content-Encoding: gzip to send multiple compressed events in your request body. Check an example in the section below.

<domain>

The name of the Devo domain where the events are being sent to.

<token>

The token you generated in Devo to authorize your connection. 

<host>

Specify the required hostname.

<tag>

The Devo tag to be applied to the events. Learn more about tags in About Devo tags.

<message>

The log to be sent. Note that this is only valid if you’re using the event mode, that is to say, you're sending a single event to Devo. In this case, the event is added to the query string.

In case of a POST request in stream mode, events should be added to the request body. See some examples of this in the section below.

Here is an example of an endpoint URL:

Code Block
https://http-us.devo.io/event/myDomain/token!a5370g9e8f7d7edf9d/local1/my.app.http.js?this%20is%20a%20example%20of%20log

...

Table of Contents
maxLevel3
minLevel3

...

Sending a single event

Code Block
import requests
from urllib.parse import quote
devo_endpoint="http://devoEndpoint"
domain="demoDomain"
token="example_token_1234abcd"
hostname="my_src_hostname"
devo_table="my.app.demo.send"
message = quote("test event")
url = f'{devo_endpoint}/event/{domain}/token!{token}/{hostname}/{devo_table}?{message}'
payload={}
headers = {}
requests.request("GET", url, headers=headers, data=payload)

Python - Sending a file with events

Code Block
import requests
with open('filePath', 'rb') as f:
  data = f.read()
devo_endpoint="http://devoEndpoint"
domain="demoDomain"
token="example_token_1234abcd"
hostname="my_src_hostname"
devo_table="my.app.demo.send"
url = f'{devo_endpoint}/stream/{domain}/token!{token}/{hostname}/{devo_table}'
requests.request("POST", url, data=data)

Java

Code Block
package lt.example.http.send;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;

public class Main {
  // /event/<identity>/token!<signature>/<host>/<tag>?<message>

  public static void main(String[] args) {
    try {
      final String url = generateUrl(
        "http://devoEndpoint",
        "demoDomain",
        "example_token_1234abcd",
        "my_src_hostname",
        "my.app.demo.send",
        encodeToHttp("example_of_log"));

      URL obj = new URL(url);
      HttpURLConnection con = (HttpURLConnection) obj.openConnection();
      con.setRequestMethod("GET");
      int responseCode = con.getResponseCode();
      System.out.println("Response Code : " + responseCode);
      System.out.println("Response: " + con.getResponseMessage());
    } catch (UnsupportedEncodingException e) {
      System.err.println("Cannot encode message: " + e.getMessage());
      e.printStackTrace();
    } catch (IOException e) {
      System.err.println(e.getMessage());
      e.printStackTrace();
    }
  }

  public static String encodeToHttp(String str)
    throws UnsupportedEncodingException {
    return URLEncoder.encode(str, "UTF-8").replace("+","%20");
  }

  public static String generateUrl(String serverPath, String domain,
                                   String token, String hostname,
                                   String tag, String msg) {

    return new StringBuilder(serverPath)
            .append("/event/")
            .append(domain).append("/token!")
            .append(token).append("/")
            .append(hostname).append("/")
            .append(tag).append("?")
            .append(msg)
            .toString();
  }
}

Java (POST example)

Code Block
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.DataOutputStream;

public class Main {
    public static void  main(String[] args) {
        try{
            final String url = generateUrl(
                    "http://devoEndpoint",
                    "demoDomain",
                    "example_token_1234abcd",
                    "my_src_hostname",
                    "my.app.demo.send");

            URL obj = new URL(url);
            HttpURLConnection con = (HttpURLConnection) obj.openConnection();
            con.setRequestMethod("POST");
            con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            con.setRequestProperty("charset", "utf-8");
            con.setDoOutput(true);
            
            String urlParameters;
            DataOutputStream wr = new DataOutputStream(con.getOutputStream());
            
            for (int i = 0; i < 3; i++) {
                urlParameters = "PostExample" + i + "\n"; // \n needed to send multiple events, otherwise the stream will be sent as a single event
                wr.writeBytes(urlParameters);
            }

            wr.flush();
            wr.close();
            int responseCode = con.getResponseCode();
            System.out.println("Response Code : " + responseCode);
            System.out.println("Response: " + con.getResponseMessage());

        } catch (UnsupportedEncodingException e) {
            System.err.println("Cannot encode message: " + e.getMessage());
            e.printStackTrace();
        } catch (IOException e) {
            System.err.println(e.getMessage());
            e.printStackTrace();
        }
    }

    public static String generateUrl(String serverPath, String domain,
                                     String token, String hostname,
                                     String tag) {

        return new StringBuilder(serverPath)
                .append("/stream/")
                .append(domain).append("/token!")
                .append(token).append("/")
                .append(hostname).append("/")
                .append(tag).append("?")
                .toString();
    }
}

HTML - jQuery

Code Block
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Devo: JQuery Example</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script>
    var serverPath = "http://devoEndpoint";
    var domain = "demoDomain";
    var token = "example_token_1234abcd";
    var hostname = "my_src_hostname";
    var tag = "my.app.demo.send";
    var msg = "this is a example of log";

    function generateUrl(domain, token, hostname, tag, msg) {
      return serverPath + "/event/" + domain + "/token!" + token + "/" +
        hostname + "/" + tag + "?" + msg;
    }

    $(document).ready(function() {
      $.get(generateUrl(domain, token, hostname, tag, msg),
        function(data, status) {
          alert("Data: " + data + "\nStatus: " + status);
        });
    });
  </script>
</head>
<body>
  <h1>JQuery Example</h1>
</body>
</html>

HTML - JavaScript

Code Block
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Devo: JavaScript Example</title>
  <script>
    var serverPath = "http://devoEndpoint";
    var domain = "demoDomain";
    var token = "example_token_1234abcd";
    var hostname = "my_src_hostname";
    var tag = "my.app.demo.send";
    var msg = "this is a example of log";

    function generateUrl(domain, token, hostname, tag, msg) {
      return serverPath + "/event/" + domain + "/token!" + token + "/" +
        hostname + "/" + tag + "?" + msg;
    }

    var req;

    if (window.XMLHttpRequest) {
      req = new XMLHttpRequest();
    } else if (window.ActiveXObject) {
      try {
        req = new ActiveXObject("Msxml2.XMLHTTP");
      } catch (e) {

        try {
          req = new ActiveXObject("Microsoft.XMLHTTP");
        } catch (e) {}
      }
    }

    req.open("GET", generateUrl(domain, token, hostname, tag, msg), true);
    req.send(null);
  </script>
</head>
<body>
  <h1>JS Example</h1>
</body>
</html>

cURL - Sending a single event

Code Block
curl -v '<DEVO_ENDPOINT>/event/<DOMAIN>/token!<TOKEN>/<HOSTNAME>/<TAG>?this%20is%20a%20example%20of%20log'

cURL - Sending a file with events

Code Block
curl -v --request POST --url '<DEVO_ENDPOINT>/stream/<DOMAIN>/token!<TOKEN>/<HOSTNAME>/<TAG>' --header 'Content-Type:application/x-www-form-urlencoded' --header 'charset:utf-8' --data-binary @<FILE_PATH>

cURL - Sending a file with compressed events

curl -v --request POST --url '<DEVO_ENDPOINT>/stream/<DOMAIN>/token!<TOKEN>/<HOSTNAME>/<TAG>' --header 'Content-Encoding: gzip' --data-binary @<FILE_PATH>
Code Block
Rw ui tabs macro
Rw tab
titleSingle event using GET method

Send a single event in a single HTTP request using the URL query string to encode the event message. This method uses the HTTP GET method.

Anatomy of the request

Code Block
GET <endpoint>/event/<domain>/token!<token>/<host>/<tag>?<message> HTTP/1.1
Host: <host>

Examples

Rw expand
titleJavaScript
Code Block
const https = require('https');

const URL_HOST = process.env.URL_HOST;
const URL_PORT = process.env.URL_PORT || 443;
const TOKEN = process.env.TOKEN;
const DOMAIN = process.env.DOMAIN;
const HOST = process.env.HOST;
const TAG = process.env.TAG;
const ACCEPT_UNAUTHORIZED = process.env.ACCEPT_UNAUTHORIZED !== undefined;

const message = 'This is Sparta!';
const querystring = encodeURIComponent(message);
const options = {
  hostname: URL_HOST,
  port: URL_PORT,
  path: `/event/${DOMAIN}/token!${TOKEN}/${HOST}/${TAG}?${querystring}`,
  method: 'GET',
  headers: {
    'Content-Type': 'text/plain',
  },
  rejectUnauthorized: !ACCEPT_UNAUTHORIZED
};

const req = https.request(options, res => {
  console.log(`statusCode: ${res.statusCode}`);
  res.on('data', chunk => console.log(`Response: ${chunk}`));
});
req.on('error', err => console.error(err));
req.end();
Rw expand
titlePython
Code Block
import http.client
import ssl
import os
import urllib

URL_HOST = os.environ.get("URL_HOST")
URL_PORT = os.environ.get("URL_PORT", 443)
TOKEN = os.environ.get("TOKEN")
DOMAIN = os.environ.get("DOMAIN")
HOST = os.environ.get("HOST")
TAG = os.environ.get("TAG")
ACCEPT_UNAUTHORIZED = os.environ.get("ACCEPT_UNAUTHORIZED")

context = (
    ssl._create_unverified_context()
    if ACCEPT_UNAUTHORIZED
    else ssl.create_default_context()
)
conn = http.client.HTTPSConnection(URL_HOST, URL_PORT, context=context)

message = urllib.parse.quote("This is Sparta!")
path = f"/event/{DOMAIN}/token!{TOKEN}/{HOST}/{TAG}?{message}"
headers = {"Content-Type": "text/plain"}
conn.request("GET", path, headers=headers)

response = conn.getresponse()
print(response.status)
print(response.read().decode())
conn.close()
Rw expand
titleBash
Code Block
#!/usr/bin/env bash

if [[ -z "$URL_HOST" || -z "$TOKEN" || -z "$DOMAIN" || -z "$HOST" || -z "$TAG" ]]; then
    echo "Please set all required environment variables: URL_HOST, TOKEN, DOMAIN, HOST, TAG"
    exit 1
fi
URL_PORT="${URL_PORT:-443}"

MESSAGE="This is Sparta!"
URL="https://$URL_HOST:$URL_PORT/event/$DOMAIN/token!$TOKEN/$HOST/$TAG"
curl -v -G --data-urlencode "$MESSAGE" "$URL"
Rw tab
titleSingle event using POST method

Send a single event in a single HTTP request using the body to encode the event message. This method uses the HTTP POST method.

Anatomy of the request

Code Block
POST <endpoint>/event/<domain>/token!<token>/<host>/<tag> HTTP/1.1
Host: <host>
Content-Length: <message length>

<message>

Examples

Rw expand
titleJavaScript
Code Block
const https = require('https');

const URL_HOST = process.env.URL_HOST;
const URL_PORT = process.env.URL_PORT || 443;
const TOKEN = process.env.TOKEN;
const DOMAIN = process.env.DOMAIN;
const HOST = process.env.HOST;
const TAG = process.env.TAG;
const ACCEPT_UNAUTHORIZED = process.env.ACCEPT_UNAUTHORIZED !== undefined;

const options = {
  hostname: URL_HOST,
  port: URL_PORT,
  path: `/event/${DOMAIN}/token!${TOKEN}/${HOST}/${TAG}`,
  method: 'POST',
  headers: {
    'Content-Type': 'text/plain',
  },
  rejectUnauthorized: !ACCEPT_UNAUTHORIZED
};

const req = https.request(options, res => {
  console.log(`statusCode: ${res.statusCode}`);
  res.on('data', chunk => console.log(`Response: ${chunk}`));
});
req.on('error', err => console.error(err));

const message = 'This is Sparta!';
req.end(message);
Rw expand
titlePython
Code Block
import http.client
import ssl
import os

URL_HOST = os.environ.get("URL_HOST")
URL_PORT = os.environ.get("URL_PORT", 443)
TOKEN = os.environ.get("TOKEN")
DOMAIN = os.environ.get("DOMAIN")
HOST = os.environ.get("HOST")
TAG = os.environ.get("TAG")
ACCEPT_UNAUTHORIZED = os.environ.get("ACCEPT_UNAUTHORIZED")

context = (
    ssl._create_unverified_context()
    if ACCEPT_UNAUTHORIZED
    else ssl.create_default_context()
)
conn = http.client.HTTPSConnection(URL_HOST, URL_PORT, context=context)

path = f"/event/{DOMAIN}/token!{TOKEN}/{HOST}/{TAG}"
headers = {"Content-Type": "text/plain"}
body = "This is Sparta!".encode("utf-8")
conn.request("POST", path, body=body, headers=headers)

response = conn.getresponse()
print(response.status)
print(response.read().decode())
conn.close()
Rw expand
titleBash
Code Block
#!/usr/bin/env bash

if [[ -z "$URL_HOST" || -z "$TOKEN" || -z "$DOMAIN" || -z "$HOST" || -z "$TAG" ]]; then
    echo "Please set all required environment variables: URL_HOST, TOKEN, DOMAIN, HOST, TAG"
    exit 1
fi
URL_PORT="${URL_PORT:-443}"

MESSAGE="This is Sparta!"
URL="https://$URL_HOST:$URL_PORT/event/$DOMAIN/token!$TOKEN/$HOST/$TAG"
curl -v --data "$MESSAGE" "$URL"

Sending multiple events

The stream mode sends multiple events in a single HTTP request. The events must be encoded in the body of the HTTP request using \n as a separator between event messages.

Rw ui tabs macro
Rw tab
titleBatch of events

Send a batch of events in a single HTTP request. Recommended when the client knows in advance the number of events to send.

Anatomy of the request

Code Block
POST <endpoint>/stream/<domain>/token!<token>/<host>/<tag> HTTP/1.1
Host: <host>
Content-Length: <body length>

<message 1>\n
<message 2>\n
...
<message n>\n

Examples

Rw expand
titleJavaScript
Code Block
const https = require('https');

const URL_HOST = process.env.URL_HOST;
const URL_PORT = process.env.URL_PORT || 443;
const TOKEN = process.env.TOKEN;
const DOMAIN = process.env.DOMAIN;
const HOST = process.env.HOST;
const TAG = process.env.TAG;
const ACCEPT_UNAUTHORIZED = process.env.ACCEPT_UNAUTHORIZED !== undefined;

const options = {
  hostname: URL_HOST,
  port: URL_PORT,
  path: `/stream/${DOMAIN}/token!${TOKEN}/${HOST}/${TAG}`,
  method: 'POST',
  headers: {
    'Content-Type': 'text/plain',
  },
  rejectUnauthorized: !ACCEPT_UNAUTHORIZED
};

const req = https.request(options, res => {
  console.log(`statusCode: ${res.statusCode}`);
  res.on('data', chunk => console.log(`Response: ${chunk}`));
});
req.on('error', err => console.error(err));

const batch = createBatch('This is Sparta!', 10);
req.end(batch);

function createBatch(message, n) {
  return Array.from({length: n}, (_, i) => `${message} ${i + 1}`).join(`\n`);
}
Rw expand
titlePython
Code Block
import http.client
import ssl
import os

URL_HOST = os.environ.get("URL_HOST")
URL_PORT = os.environ.get("URL_PORT", 443)
TOKEN = os.environ.get("TOKEN")
DOMAIN = os.environ.get("DOMAIN")
HOST = os.environ.get("HOST")
TAG = os.environ.get("TAG")
ACCEPT_UNAUTHORIZED = os.environ.get("ACCEPT_UNAUTHORIZED")

def createBatch(message, n):
    return '\n'.join([f"{message} {i}" for i in range(1, n + 1)])

context = (
    ssl._create_unverified_context()
    if ACCEPT_UNAUTHORIZED
    else ssl.create_default_context()
)
conn = http.client.HTTPSConnection(URL_HOST, URL_PORT, context=context)

path = f"/stream/{DOMAIN}/token!{TOKEN}/{HOST}/{TAG}"
headers = {"Content-Type": "text/plain"}
body = createBatch("This is Sparta!", 10).encode("utf-8")
conn.request("POST", path, body=body, headers=headers)

response = conn.getresponse()
print(response.status)
print(response.read().decode())
conn.close()
Rw expand
titleBash
Code Block
#!/usr/bin/env bash

if [[ -z "$URL_HOST" || -z "$TOKEN" || -z "$DOMAIN" || -z "$HOST" || -z "$TAG" ]]; then
    echo "Please set all required environment variables: URL_HOST, TOKEN, DOMAIN, HOST, TAG"
    exit 1
fi
URL_PORT="${URL_PORT:-443}"

create_batch() {
    local message="$1"
    local n="$2"
    local batch=""

    for i in $(seq 1 $n)
    do
        batch+="\n$message $i"
    done

    printf "${batch:2}"
}

URL="https://$URL_HOST:$URL_PORT/stream/$DOMAIN/token!$TOKEN/$HOST/$TAG"
create_batch "This is Sparta!" 10 | curl -v --data-binary @- "$URL"
Rw tab
titleBatch of events with gzip compression

Sending a batch of events compressed with gzip in a single HTTP request can be useful for reducing the size of the data transmitted over the network (bandwidth), especially if the events are already compressed at the source.

Anatomy of the request

Code Block
POST <endpoint>/stream/<domain>/token!<token>/<host>/<tag> HTTP/1.1
Host: <host>
Content-Encoding: gzip
Content-Length: <body length>

<compressed body>

Examples

Rw expand
titleJavaScript
Code Block
const https = require('https');
const zlib = require('zlib');

const URL_HOST = process.env.URL_HOST;
const URL_PORT = process.env.URL_PORT || 443;
const TOKEN = process.env.TOKEN;
const DOMAIN = process.env.DOMAIN;
const HOST = process.env.HOST;
const TAG = process.env.TAG;
const ACCEPT_UNAUTHORIZED = process.env.ACCEPT_UNAUTHORIZED !== undefined;

const options = {
  hostname: URL_HOST,
  port: URL_PORT,
  path: `/stream/${DOMAIN}/token!${TOKEN}/${HOST}/${TAG}`,
  method: 'POST',
  headers: {
    'Content-Type': 'text/plain',
    'Content-Encoding': 'gzip'
  },
  rejectUnauthorized: !ACCEPT_UNAUTHORIZED
};

const req = https.request(options, res => {
  console.log(`statusCode: ${res.statusCode}`);
  res.on('data', chunk => console.log(`Response: ${chunk}`));
});
req.on('error', err => console.error(err));

const batch = createBatch('This is Sparta!', 10);
const payload = zlib.gzipSync(batch);
req.end(payload);

function createBatch(message, n) {
  return Array.from({length: n}, (_, i) => `${message} ${i + 1}`).join(`\n`);
}
Rw expand
titlePython
Code Block
import http.client
import ssl
import os
import gzip

URL_HOST = os.environ.get("URL_HOST")
URL_PORT = os.environ.get("URL_PORT", 443)
TOKEN = os.environ.get("TOKEN")
DOMAIN = os.environ.get("DOMAIN")
HOST = os.environ.get("HOST")
TAG = os.environ.get("TAG")
ACCEPT_UNAUTHORIZED = os.environ.get("ACCEPT_UNAUTHORIZED")

def createBatch(message, n):
    return '\n'.join([f"{message} {i}" for i in range(1, n + 1)])

context = (
    ssl._create_unverified_context()
    if ACCEPT_UNAUTHORIZED
    else ssl.create_default_context()
)
conn = http.client.HTTPSConnection(URL_HOST, URL_PORT, context=context)

path = f"/stream/{DOMAIN}/token!{TOKEN}/{HOST}/{TAG}"
headers = {
    "Content-Type": "text/plain",
    "Content-Encoding": "gzip"
}
body = createBatch("This is Sparta!", 10).encode("utf-8")
body = gzip.compress(body)
conn.request("POST", path, body=body, headers=headers)

response = conn.getresponse()
print(response.status)
print(response.read().decode())
conn.close()
Rw expand
titleBash
Code Block
#!/usr/bin/env bash

if [[ -z "$URL_HOST" || -z "$TOKEN" || -z "$DOMAIN" || -z "$HOST" || -z "$TAG" ]]; then
    echo "Please set all required environment variables: URL_HOST, TOKEN, DOMAIN, HOST, TAG"
    exit 1
fi
URL_PORT="${URL_PORT:-443}"

create_batch() {
    local message="$1"
    local n="$2"
    local batch=""

    for i in $(seq 1 $n)
    do
        batch+="\n$message $i"
    done

    printf "${batch:2}"
}

URL="https://$URL_HOST:$URL_PORT/stream/$DOMAIN/token!$TOKEN/$HOST/$TAG"
create_batch "This is Sparta!" 10 \
| gzip \
| curl -v --data-binary @- --header "Content-Encoding: gzip" "$URL"
Rw tab
titleStream of events

Send a stream of events in a single HTTP request. Useful when the client does not know in advance the number of events to send.

This method uses chunked transfer encoding to stream events using the body of the HTTP request.

Anatomy of the request

Code Block
POST <endpoint>/stream/<domain>/token!<token>/<host>/<tag> HTTP/1.1
Host: <host>
Transfer-Encoding: chunked

<chunk 1 size>\r\n
<chunk 1>\r\n
<chunk 2 size>\r\n
<chunk 2>\r\n
...
<chunk n size>\r\n
<chunk n>\r\n
0\r\n\r\n

Examples

Rw expand
titleJavaScript
Code Block
const https = require('https');

const URL_HOST = process.env.URL_HOST;
const URL_PORT = process.env.URL_PORT || 443;
const TOKEN = process.env.TOKEN;
const DOMAIN = process.env.DOMAIN;
const HOST = process.env.HOST;
const TAG = process.env.TAG;
const ACCEPT_UNAUTHORIZED = process.env.ACCEPT_UNAUTHORIZED !== undefined;

const options = {
  hostname: URL_HOST,
  port: URL_PORT,
  path: `/stream/${DOMAIN}/token!${TOKEN}/${HOST}/${TAG}`,
  method: 'POST',
  headers: {
    'Content-Type': 'text/plain',
    'Transfer-Encoding': 'chunked'
  },
  rejectUnauthorized: !ACCEPT_UNAUTHORIZED
};

const req = https.request(options, res => {
  console.log(`statusCode: ${res.statusCode}`);
  res.on('data', chunk => console.log(`Response: ${chunk}`));
});
req.on('error', err => console.error(err));

async function main() {
  const stream = createStream('This is Sparta!', 10);
  for await (const message of stream) {
    req.write(message);
  }
  req.end();
}
main();

async function* createStream(message, n, delay = 1000) {
  for (let i = 1; i <= n; i++) {
    yield `${message} ${i}\n`;
    await new Promise(resolve => setTimeout(resolve, delay));
  }
}
Rw expand
titlePython
Code Block
import http.client
import ssl
import time
import os

URL_HOST = os.environ.get("URL_HOST")
URL_PORT = os.environ.get("URL_PORT", 443)
TOKEN = os.environ.get("TOKEN")
DOMAIN = os.environ.get("DOMAIN")
HOST = os.environ.get("HOST")
TAG = os.environ.get("TAG")
ACCEPT_UNAUTHORIZED = os.environ.get("ACCEPT_UNAUTHORIZED")

def createChunk(message):
    data = message.encode("utf-8")
    size = format(len(data), 'x').encode("utf-8")
    return b"%b\r\n%b\r\n" % (size, data)

def endChunk():
    return b"0\r\n\r\n"

def createStream(message, n, delay=1000):
    for i in range(1, n + 1):
        yield f"{message} {i}\n"
        time.sleep(delay / 1000)

context = (
    ssl._create_unverified_context()
    if ACCEPT_UNAUTHORIZED
    else ssl.create_default_context()
)
conn = http.client.HTTPSConnection(URL_HOST, URL_PORT, context=context)

path = f"/stream/{DOMAIN}/token!{TOKEN}/{HOST}/{TAG}"
headers = {"Content-Type": "text/plain", "Transfer-Encoding": "chunked"}
conn.request("POST", path, headers=headers)

for message in createStream("This is Sparta!", 10):
    print(message)
    conn.send(createChunk(message))
conn.send(endChunk())

response = conn.getresponse()
print(response.status)
print(response.read().decode())
conn.close()
Rw expand
titleBash
Code Block
#!/usr/bin/env bash

if [[ -z "$URL_HOST" || -z "$TOKEN" || -z "$DOMAIN" || -z "$HOST" || -z "$TAG" ]]; then
    echo "Please set all required environment variables: URL_HOST, TOKEN, DOMAIN, HOST, TAG"
    exit 1
fi
URL_PORT="${URL_PORT:-443}"

create_stream() {
    local message="$1"
    local n="$2"

    for i in $(seq 1 $n)
    do
        printf "$message $i\n"
        sleep 1
    done
}

URL="https://$URL_HOST:$URL_PORT/stream/$DOMAIN/token!$TOKEN/$HOST/$TAG"
# It appears that curl buffers the chunks and sends them once all messages
# are generated as a single chunk. This behavior likely occurs because
# curl has an internal buffer, and when all messages are combined, they
# do not exceed this buffer limit.
create_stream "This is Sparta!" 10 \
| curl -v --data-binary @- --header "Transfer-Encoding: chunked" "$URL"

Response codes

Take into consideration the following points related to the response codes returned by the HTTP API:

...