lyng/docs/lyng.io.http.md
2026-04-29 22:39:43 +03:00

5.2 KiB

lyng.io.http — HTTP/HTTPS client for Lyng scripts

This module provides a compact HTTP client API for Lyng scripts. It is implemented in lyngio and backed by Ktor on supported runtimes.

Note: lyngio is a separate library module. It must be explicitly added as a dependency to your host application and initialized in your Lyng scopes.

Shared type note: HttpHeaders is also available from lyng.io.http.types when host code wants the reusable value type without relying on the HTTP client module itself.


Add the library to your project (Gradle)

If you use this repository as a multi-module project, add a dependency on :lyngio:

dependencies {
    implementation("net.sergeych:lyngio:0.0.1-SNAPSHOT")
}

For external projects, ensure you also use the Lyng Maven repository described in lyng.io.fs.


Install the module into a Lyng session

The HTTP module is not installed automatically. Install it into the session scope and provide a policy.

Kotlin (host) bootstrap example:

import net.sergeych.lyng.EvalSession
import net.sergeych.lyng.Scope
import net.sergeych.lyng.io.http.createHttpModule
import net.sergeych.lyngio.http.security.PermitAllHttpAccessPolicy

suspend fun bootstrapHttp() {
    val session = EvalSession()
    val scope: Scope = session.getScope()
    createHttpModule(PermitAllHttpAccessPolicy, scope)
    session.eval("import lyng.io.http")
}

Using from Lyng scripts

Simple GET:

import lyng.io.http

val r = Http.get(HTTP_TEST_URL + "/hello")
[r.status, r.text()]
>>> [200,hello from test]

Headers and response header access:

import lyng.io.http

val r = Http.get(HTTP_TEST_URL + "/headers")
[r.headers["X-Reply"], r.headers.getAll("X-Reply").size, r.text()]
>>> [one,2,header demo]

Programmatic request object:

import lyng.io.http

val q = HttpRequest()
q.method = "POST"
q.url = HTTP_TEST_URL + "/echo"
q.headers = Map("Content-Type" => "text/plain")
q.bodyText = "ping"

val r = Http.request(q)
r.text()
>>> "POST:ping"

HTTPS GET:

import lyng.io.http

val r = Http.get(HTTPS_TEST_URL + "/hello")
[r.status, r.text()]
>>> [200,hello from test]

API reference

Http (static methods)

  • isSupported(): Bool — Whether HTTP client support is available on the current runtime.
  • request(req: HttpRequest): HttpResponse — Execute a request described by a mutable request object.
  • get(url: String, headers...): HttpResponse — Convenience GET request.
  • post(url: String, bodyText: String = "", contentType: String? = null, headers...): HttpResponse — Convenience text POST request.
  • postBytes(url: String, body: Buffer, contentType: String? = null, headers...): HttpResponse — Convenience binary POST request.

For convenience methods, headers... accepts:

  • MapEntry, e.g. "Accept" => "text/plain"
  • 2-item lists, e.g. ["Accept", "text/plain"]

HttpRequest

  • method: String
  • url: String
  • headers: Map<String, String>
  • bodyText: String?
  • bodyBytes: Buffer?
  • timeoutMillis: Int?

Only one of bodyText and bodyBytes should be set.

HttpResponse

  • status: Int
  • statusText: String
  • headers: HttpHeaders
  • text(): String
  • bytes(): Buffer

Response body decoding is cached inside the response object.

HttpHeaders

HttpHeaders behaves like Map<String, String> for the first value of each header name and additionally exposes:

  • get(name: String): String?
  • getAll(name: String): List<String>
  • names(): List<String>

Header lookup is case-insensitive.


Security policy

The module uses HttpAccessPolicy to authorize requests before they are sent.

  • HttpAccessPolicy — interface for custom policies
  • PermitAllHttpAccessPolicy — allows all requests
  • HttpAccessOp.Request(method, url) — operation checked by the policy

Example restricted policy in Kotlin:

import net.sergeych.lyngio.fs.security.AccessContext
import net.sergeych.lyngio.fs.security.AccessDecision
import net.sergeych.lyngio.fs.security.Decision
import net.sergeych.lyngio.http.security.HttpAccessOp
import net.sergeych.lyngio.http.security.HttpAccessPolicy

val allowLocalOnly = object : HttpAccessPolicy {
    override suspend fun check(op: HttpAccessOp, ctx: AccessContext): AccessDecision =
        when (op) {
            is HttpAccessOp.Request ->
                if (
                    op.url.startsWith("http://127.0.0.1:") ||
                    op.url.startsWith("https://127.0.0.1:") ||
                    op.url.startsWith("http://localhost:") ||
                    op.url.startsWith("https://localhost:")
                )
                    AccessDecision(Decision.Allow)
                else
                    AccessDecision(Decision.Deny, "only local HTTP/HTTPS requests are allowed")
        }
}

Platform support

  • JVM: supported
  • Android: supported via the Ktor CIO client backend
  • JS: supported via the Ktor JS client backend
  • Linux native: supported via the Ktor Curl client backend
  • Windows native: supported via the Ktor WinHttp client backend
  • Apple native: supported via the Ktor Darwin client backend
  • Other targets: may report unsupported; use Http.isSupported() before relying on it