package im.rosetta.api; import im.rosetta.storage.FileStore; import jakarta.ws.rs.Consumes; import jakarta.ws.rs.GET; import jakarta.ws.rs.POST; import jakarta.ws.rs.Path; import jakarta.ws.rs.PathParam; import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.StreamingOutput; import org.glassfish.jersey.media.multipart.FormDataParam; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.util.Map; import java.util.Optional; import java.util.UUID; @Path("/") public class CdnResource { private final FileStore fileStore; public CdnResource(FileStore fileStore) { this.fileStore = fileStore; } @POST @Path("u") @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces(MediaType.APPLICATION_JSON) public Response upload(@FormDataParam("file") InputStream inputStream) { if (inputStream == null) { return Response.status(Response.Status.BAD_REQUEST) .entity(Map.of("error", "file is required")) .build(); } try { String tag = fileStore.save(inputStream); return Response.ok(Map.of("t", tag)).build(); } catch (IOException e) { return Response.serverError() .entity(Map.of("error", "upload failed")) .build(); } } @GET @Path("d/{tag}") @Produces(MediaType.APPLICATION_OCTET_STREAM) public Response download(@PathParam("tag") String tag) { if (!isValidTag(tag)) { return Response.status(Response.Status.BAD_REQUEST) .entity(Map.of("error", "invalid tag")) .build(); } try { Optional file = fileStore.getIfValid(tag); if (file.isEmpty()) { return Response.status(Response.Status.NOT_FOUND) .entity(Map.of("error", "not found")) .build(); } StreamingOutput stream = output -> Files.copy(file.get(), output); return Response.ok(stream) .header("Content-Disposition", "attachment; filename=\"" + tag + "\"") .build(); } catch (IOException e) { return Response.serverError() .entity(Map.of("error", "download failed")) .build(); } } private boolean isValidTag(String tag) { try { UUID.fromString(tag); return true; } catch (IllegalArgumentException ex) { return false; } } }