HTTP, JSON, download and webhook helpers for PocketMine-MP plugins and EasyLibrary packages.
LibHttp is the official EasyLibrary HTTP helper package for PocketMine-MP.
It exists because raw HTTP in PMMP plugins usually ends up as repeated cURL
setup, JSON checks, retry loops, webhook payload code and download validation.
The first 3.0-dev version focuses on the common server-side jobs:
- immutable HTTP requests and responses;
- cURL transport with PHP stream fallback;
- retry policies for transport errors and retryable status codes;
- optional auth header helpers;
- optional interceptors for default headers, request mutation and response observation;
- optional fixed-window rate limiter for local throttling;
- typed exceptions for transport, status, JSON and download failures;
- JSON request/response helpers;
- atomic file downloads with optional size and checksum validation;
- generic JSON webhooks and Discord webhook payload helpers;
- PMMP async adapter for fire-and-callback requests.
Standalone plugin:
- Install
LibCommons, which provides the shared JSON, validation, checksum and filesystem helpers used byLibHttp. - Download
LibHttp-1.0.0-dev.pharfrom the GitHub Release. - Put it in
plugins/. - Restart the server.
EasyLibrary package:
/easylibrary packages install libhttp development confirm
Then restart and confirm:
/easylibrary packages doctor
use imperazim\http\client\HttpClient;
use imperazim\http\HttpRequest;
use imperazim\http\RetryPolicy;
$client = new HttpClient();
$response = $client->send(
HttpRequest::get('https://example.com/api/status')
->withTimeout(8.0),
RetryPolicy::networkDefaults()
);
if ($response->isSuccessful()) {
$body = $response->getBody();
}use imperazim\http\client\JsonHttpClient;
use imperazim\http\HttpRequest;
$api = new JsonHttpClient();
$data = $api->sendJson(
HttpRequest::json('POST', 'https://example.com/api/report', [
'server' => 'lobby',
'online' => 42,
])
);sendJson() throws when the response body is not valid JSON. Use
HttpResponse::tryJsonArray() when you prefer a nullable result.
use imperazim\http\auth\HttpAuth;
use imperazim\http\HttpRequest;
$request = HttpRequest::get('https://example.com/api/private')
->withHeaders(HttpAuth::bearerToken($token));
$basic = HttpRequest::get('https://example.com/api/private')
->withHeaders(HttpAuth::basic('user', 'password'));Auth helpers only build headers. Keep tokens in plugin config or environment variables and do not log them.
use imperazim\http\client\HttpClient;
use imperazim\http\interceptor\DefaultHeadersInterceptor;
use imperazim\http\rate\FixedWindowRateLimiter;
$client = new HttpClient(
interceptors: [
new DefaultHeadersInterceptor([
'User-Agent' => 'MyPlugin/1.0',
'Accept' => 'application/json',
]),
],
rateLimiter: FixedWindowRateLimiter::perSecond(5)
);Interceptors run before each transport attempt and after each response. The
fixed-window limiter is local to the HttpClient instance; it is meant to avoid
plugin-side request bursts, not to coordinate limits across multiple servers.
use imperazim\http\exception\JsonHttpException;
use imperazim\http\exception\StatusHttpException;
use imperazim\http\exception\TransportHttpException;
try {
$response = $client->sendOrFail($request);
} catch (TransportHttpException $error) {
// DNS, connection, timeout or other transport-level failure.
} catch (StatusHttpException $error) {
// Non-2xx HTTP response. The response is still available.
$status = $error->getResponse()->getStatusCode();
} catch (JsonHttpException $error) {
// Invalid or unexpected JSON shape.
}use imperazim\http\download\FileDownloader;
$downloader = new FileDownloader();
$result = $downloader->download(
'https://example.com/assets/resource-pack.zip',
$plugin->getDataFolder() . 'packs/resource-pack.zip',
expectedSha256: '...'
);
$plugin->getLogger()->info('Downloaded ' . $result->getBytes() . ' bytes');The downloader writes to a temporary file first and only replaces the target after status, size and checksum checks pass.
use imperazim\http\webhook\DiscordWebhookMessage;
use imperazim\http\webhook\DiscordWebhookClient;
$message = DiscordWebhookMessage::create()
->withUsername('EasyLibrary')
->withContent('Server started successfully.');
(new DiscordWebhookClient())->send($webhookUrl, $message);Secrets should stay in plugin config or environment variables, never in source files or logs.
use imperazim\http\async\AsyncHttpClient;
use imperazim\http\HttpRequest;
use imperazim\http\HttpResponse;
$client = new AsyncHttpClient();
$client->send(HttpRequest::get('https://example.com/ping'), function(HttpResponse $response): void {
// Runs back on the main server thread.
});The async adapter uses PMMP's async pool. It avoids blocking the main thread, but callbacks still run after the worker finishes, so keep callback work small.
examples/README.mdcollects focused snippets for JSON requests, auth headers, interceptors, rate limits, typed failures and async requests.examples/api_webhook_download.phpshows one realistic plugin integration that fetches JSON from an external API, sends a Discord webhook and downloads a checksum-verified asset.
The PHP examples are included in the repository lint step so documentation code stays syntactically valid as the API evolves.
LibHttp ships both:
plugin.ymlfor normal PMMP plugin installation;package.ymlfor EasyLibrary package manager installation.
Runtime dependency:
LibCommons, used for shared JSON encoding/decoding, URL validation, SHA-256 comparison and atomic file writes.
Release assets include:
LibHttp-1.0.0-dev.phar;LibHttp-1.0.0-dev.easylib.zip;package.yml;checksums.txt.
- PHP
8.2+ - PocketMine-MP API
5.0.0 - EasyLibrary
3.0.0-devpackage manager - LibCommons
1.0.0-dev+
The public API is intentionally small in 1.0.0-dev; new helpers should build
on the request/response/client contracts instead of bypassing them.