Class CatalogueHttp

java.lang.Object
com.ultikits.ultitools.utils.CatalogueHttp

final class CatalogueHttp extends Object
The HTTP the module catalogue is asked with (plan 22-18, S-27, S-61).

The catalogue is public, so no request carries an Authorization header, and no redirect is followed: a 3xx is reported as such, so a compromised catalogue cannot send the client to another host. A network failure and an HTTP status stay distinct: CatalogueHttp.Kind.OK means an exchange completed, whatever its status.

download(java.lang.String, java.nio.file.Path, long) streams into a file while hashing what it wrote and keeps the stream open only while the body is at most the caller's limit; a body beyond it is cut at the limit, which is how a download larger than its declared sizeBytes is aborted while streaming rather than after. Timeouts: connect 10 s, read 15 s.

Since:
6.3.1
  • Field Details

    • SHA256_HEADER

      static final String SHA256_HEADER
      The response header carrying the SHA-256 of the body the catalogue served.
      See Also:
    • CONNECT_TIMEOUT_MS

      private static final int CONNECT_TIMEOUT_MS
      See Also:
    • READ_TIMEOUT_MS

      private static final int READ_TIMEOUT_MS
      See Also:
    • MAX_JSON_BYTES

      private static final int MAX_JSON_BYTES
      The JSON reader keeps its 4 MiB (4,194,304-byte) limit under catalogue contract 1.1.0. Every version-list request explicitly asks for five versions, not the default twenty: a changelog allows 64,000 characters and JSON can spend six bytes per character on a Unicode escape. Five worst-case changelogs take 5 * 64,000 * 6 = 1,920,000 bytes, leaving about 2.2 MB for the envelope and other fields. Twenty would need 7,680,000 bytes. The limit is not enlarged to the 38,400,000 bytes needed for one hundred versions: this plugin shares a Minecraft server's process. A module detail needs at most 50,000 * 6 = 300,000 description bytes plus 384,000 bytes for its latest version's changelog; one version needs at most 384,000 changelog bytes. Across pages the client retains only the fields its Version uses, never the changelogs, so their large bodies do not accumulate. An answer beyond the limit is refused as too large, never truncated and treated as malformed.
      See Also:
    • CHUNK

      private static final int CHUNK
      See Also:
    • LOGGER

      private static final Logger LOGGER
  • Constructor Details

    • CatalogueHttp

      private CatalogueHttp()
  • Method Details

    • getJson

      static CatalogueHttp.Json getJson(String pathAndQuery)
      Sends GET <api-url><pathAndQuery>.
      Parameters:
      pathAndQuery - a path beginning with /, with its query when it has one
      Returns:
      the answer; never null
    • download

      static CatalogueHttp.Download download(String url, Path target, long maxBytes)
      Streams url into target, keeping at most maxBytes bytes of it.
      Parameters:
      url - the absolute URL to read
      target - the file to write; created or replaced
      maxBytes - the most bytes to keep
      Returns:
      the outcome; never null
    • sha256Hex

      static String sha256Hex(byte[] bytes)
      Parameters:
      bytes - any bytes
      Returns:
      the lower-case hex SHA-256 of them
    • copy

      private static CatalogueHttp.Download copy(HttpURLConnection connection, Path target, long maxBytes, String sha256Header, long declared) throws IOException
      Throws:
      IOException
    • drain

      private static void drain(HttpURLConnection connection, int status)
    • open

      private static HttpURLConnection open(String url) throws IOException
      Throws:
      IOException
    • disconnect

      private static void disconnect(HttpURLConnection connection)
    • isRedirect

      private static boolean isRedirect(int status)
    • readBody

      private static String readBody(HttpURLConnection connection, int status) throws IOException
      Parameters:
      connection - the open connection
      status - its status
      Returns:
      the body as UTF-8 text, or null when it is longer than MAX_JSON_BYTES (nothing of it is then kept)
      Throws:
      IOException - when the body cannot be read
    • baseUrl

      static String baseUrl()
      Returns:
      the framework's catalogue base URL without trailing slashes, or null
    • digest

      private static MessageDigest digest()
    • hex

      private static String hex(byte[] digest)