Description
When making HTTP requests using the internal HTTP client libraries, the User-Agent header cannot be customized. Even if a custom User-Agent is explicitly defined in the code, it is overwritten or ignored during the final transmission, resulting in all requests being sent with User-Agent: libhttpclient/1.0.0.0.
This behavior prevents proper identification of specific services or versions and departs from the expected behavior of a standard HTTP client implementation.
Steps to Reproduce
Initialize an HTTP request using the internal library.
Set a custom string for the
User-Agentheader (e.g.,"MyCustomClient/1.0").Execute the request to a destination that logs incoming headers (e.g., a local mock server or a service like Webhook.site).
Inspect the received HTTP headers.
Observed Results
The received User-Agent is always libhttpclient/1.0.0.0.
Expected Results
The received User-Agent should match the custom string set in the code.
Environment & Platform
OS: Observed on both Windows and Linux.
Impact: Cross-platform consistency suggests this is a hardcoded value within the common library logic.
Version: 1.26.20-beta26
Build ID: 43049666
Branch: r/26_u2
Commit ID: 7c7f24697370a34623235a6a0dfeb6bf59e3c3f4
Configuration: Publish
Required Permissions:
@minecraft/server-netenabled inpermissions.json.
Code Snippet
import { http, HttpHeader, HttpRequest, HttpRequestMethod, } from "@minecraft/server-net";
import { system } from "@minecraft/server";
export const URL = "http://127.0.0.1:1080";
export async function call() {
const req = new HttpRequest(URL);
req.method = HttpRequestMethod.Post;
const User_agent = new HttpHeader("User-Agent", "RooCode/1.0");
const Content_Type = new HttpHeader("Content-Type", "application/json");
const Authorization = new HttpHeader("Authorization", `Bearer xxx`);
req.headers = [
User_agent,
Content_Type,
Authorization,
];
console.log(req.headers)
req.headers.forEach(header => {
console.log(`${header.key}: ${header.value}`);
});
req.body = JSON.stringify({
nothing: "nonono"
});
req.timeout = 30*1000;
const resp = await http.request(req);
if (resp.status !== 200) {
throw new Error(`${resp.status}: ${resp.body}`);
}
console.log(`Response: ${resp.body}`);
return resp.body
}
system.run(() => {
call()
});
console.log("Hello, World!");
The following is the actual packet received by the local mock server, showing the overwritten header.
POST / HTTP/1.1
Connection: Keep-Alive
Content-Type: application/json
Authorization: Bearer xxx
User-Agent: libhttpclient/1.0.0.0
Content-Length: 20
Host: 127.0.0.1:1080
{"nothing":"nonono"}Key Finding: As shown above, while other headers like Authorization and Content-Type are correctly processed, the User-Agent remains libhttpclient/1.0.0.0 despite being set differently in the application code.