### 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. --- #### Add the library to your project (Gradle) If you use this repository as a multi-module project, add a dependency on `:lyngio`: ```kotlin 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: ```kotlin 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` - `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` for the first value of each header name and additionally exposes: - `get(name: String): String?` - `getAll(name: String): List` - `names(): List` 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: ```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