using Astralis; namespace UsmWeb { /** * `GET /{file}.usmc` — streams a package archive from the repository's * `public/` directory with an exact content-length, exactly what a USM * client fetching through this app expects (the bytes match the * listing's sha512). * * The route pattern matches any single segment; requests that do not * name a `.usmc` inside `public/` answer 404. */ public class PackageDownloadEndpoint : Object, Endpoint { private RepositoryService repositories = Inversion.inject(); public async HttpResult handle_request(HttpContext http_context, RouteContext route_context) throws Error { string file = ""; route_context.mapped_parameters.try_get("file", out file); if (!file.has_suffix(".usmc") || file.contains("/") || file.contains("..")) { return new HttpStringResult("Not Found", StatusCode.NOT_FOUND); } var path = repositories.package_location(file); var handle = File.new_for_path(path); if (!handle.query_exists()) { return new HttpStringResult("No such package", StatusCode.NOT_FOUND); } var info = yield handle.query_info_async( FileAttribute.STANDARD_SIZE, FileQueryInfoFlags.NONE); var result = new HttpStreamResult(yield handle.read_async(), info.get_size()); result.set_header("Content-Type", "application/octet-stream"); result.set_flag(HttpResultFlag.DO_NOT_COMPRESS); return result; } } }