Class AppHttp
- Namespace
- McServerLauncher.Services
- Assembly
- McServerLauncher.dll
The one place an HttpClient of this app is made.
public static class AppHttp
- Inheritance
-
AppHttp
- Inherited Members
Remarks
Seventeen services each built their own, and they had drifted: six sent
JuanP-G/MC-ServerLauncher as their User-Agent, UpdateService sent
MC-ServerLauncher, and the rest sent none. Some CDNs (Forge's maven among them) refuse a
request without one, and Modrinth asks for one that says who is calling.
Keeping the creation here is also what gives the rules about what may come back a single home: a ceiling on how much a response may weigh (ReadCappedAsync(HttpContent, long, CancellationToken)) and the hosts a download is allowed to come from (RequireAllowedUrl(string?, params string[])) belong to every client or to none.
Each service still keeps its own static client (one per service, with its own timeout), so nothing is shared that did not need to be: a slow download cannot hold up the version check.
Fields
MaxApiBytes
The most a JSON answer from an API is read for: far above any real one.
public const long MaxApiBytes = 8388608
Field Value
MaxSmallTextBytes
The most a checksum list or a signature is read for; the real ones are a few hundred bytes.
public const long MaxSmallTextBytes = 65536
Field Value
UserAgent
What every request says it is, so the services we call can tell who is asking.
public const string UserAgent = "JuanP-G/MC-ServerLauncher"
Field Value
Methods
Create(TimeSpan)
A client with this app's User-Agent and the given overall timeout.
public static HttpClient Create(TimeSpan timeout)
Parameters
timeoutTimeSpanHow long one request may take in all. Use InfiniteTimeSpan when the caller sets its own deadline.
Returns
GetStringCappedAsync(HttpClient, string, long, CancellationToken)
A GET whose body is read as text, up to limit bytes.
public static Task<string> GetStringCappedAsync(HttpClient http, string url, long limit, CancellationToken ct)
Parameters
httpHttpClienturlstringlimitlongctCancellationToken
Returns
Exceptions
- HttpRequestException
The server answered with an error status.
- InvalidDataException
The body is larger than the limit.
IsAllowedUrl(string?, params string[])
Whether url is an https address on one of hosts (or a
subdomain of one), with no credentials in it.
public static bool IsAllowedUrl(string? url, params string[] hosts)
Parameters
Returns
ReadCappedAsync(HttpContent, long, CancellationToken)
Reads a response body, refusing one that grows past limit.
public static Task<byte[]> ReadCappedAsync(HttpContent content, long limit, CancellationToken ct)
Parameters
contentHttpContentlimitlongctCancellationToken
Returns
Remarks
GetStringAsync reads whatever the server sends, so a server that answers with
gigabytes fills memory before any check on the result can run. The announced length is
refused up front, and the bytes actually read are counted as well, since the announcement
can be absent or false.
Exceptions
- InvalidDataException
The body is larger than the limit.
ReadCappedStringAsync(HttpContent, long, CancellationToken)
A response body as text (UTF-8, or what its byte-order mark says), up to limit bytes.
public static Task<string> ReadCappedStringAsync(HttpContent content, long limit, CancellationToken ct)
Parameters
contentHttpContentlimitlongctCancellationToken
Returns
RequireAllowedUrl(string?, params string[])
Throws unless url passes IsAllowedUrl(string?, params string[]). For a download link
that came out of an API response: the response says where the file is, and nothing in it
should be able to say somewhere other than the publisher's own host.
public static void RequireAllowedUrl(string? url, params string[] hosts)
Parameters
Exceptions
- UserFacingException
The address is not https or not on an allowed host.