Fetch an HTTP response with an explicit limit
The embedded kinmokusei/http client keeps transport policy and response size visible. This example supplies an in-memory Go http.RoundTripper, so the complete response path executes without opening a socket or depending on an external service.
Source
import { sendWith } from "kinmokusei/http";
import go fmt from "fmt";
import go http from "net/http";
import go io from "io";
import go strings from "strings";
class StaticTransport implements http.RoundTripper {
public function roundTrip(request: *http.Request): Result<*http.Response> {
const headers: http.Header = makeMap[bstring, bstring[]]();
headers.Set("X-Source", "warm");
const response = http.Response{
StatusCode: http.StatusOK,
Header: headers,
Body: io.NopCloser(strings.NewReader("hello")),
Request: request,
};
return ok(&response);
}
}
function main(): void {
const client = http.Client{Transport: new StaticTransport()};
const [request, requestErr] = http.NewRequest(
http.MethodGet,
"http://fixture.invalid",
nil,
);
if (requestErr !== nil) {
fmt.Println("unexpected:", requestErr.Error());
return;
}
const [response, err] = sendWith(&client, request, int64(5));
if (err !== nil) {
fmt.Println("unexpected:", err.Error());
return;
}
const [text, textErr] = response.text();
if (textErr !== nil) { fmt.Println(textErr); return; }
fmt.Println(
response.status,
response.ok(),
response.header("X-Source"),
text,
);
const bodyCopy = response.bytes();
bodyCopy[0] = byte(88);
fmt.Println(bstring(bodyCopy), response.rawText());
const [_, limitErr] = sendWith(&client, request, int64(4));
fmt.Println(limitErr !== nil);
}Run
keika check bounded-http-fetch.km
keika run bounded-http-fetch.kmExpected output:
200 true warm hello
Xello hello
trueSuccess path
StaticTransport is a Kinmokusei class that explicitly implements the imported Go http.RoundTripper interface. Its roundTrip method returns a normal *http.Response through Result, which lowers to the interface's (*http.Response, error) method shape.
sendWith uses the caller-owned http.Client, reads and closes the response body, clones the response headers, and returns a Response value. The limit is measured in response-body bytes; the five-byte body hello fits an int64(5) limit exactly.
response.ok() means the status is from 200 through 299. Other HTTP statuses still produce a successful Response; transport, request construction, body reading, cancellation, and configured-limit failures use the Result<Response> error path.
response.text() returns Result<string> after UTF-8 validation. The example handles its error explicitly. response.bytes() returns a new slice; changing its first byte produces Xello, while response.rawText() still returns hello. Callers cannot mutate the stored body through the returned slice.
Oversize path
The second call permits only four bytes. The adapter reads at most one byte beyond the configured limit, closes the body, and returns an error instead of exposing a truncated success value. The final true confirms that boundary without depending on the diagnostic text.
In an application, use fetch or fetchLimited for a context-bound GET. Use send for another caller-built request and sendWith when timeout, transport, or connection-pool policy belongs to an explicit http.Client.
See the kinmokusei/http API for every client function and HTTP applications for server and lifecycle choices.