/** * @return Generate a weak Etag using the {@link #path()}, {@link #lastModified()} and * {@link #length()}. */ @Nonnull default String etag() { try { StringBuilder b = new StringBuilder(32); b.append("W/\""); BaseEncoding b64 = BaseEncoding.base64(); int lhash = resource().toURI().hashCode(); b.append(b64.encode(Longs.toByteArray(lastModified() ^ lhash))); b.append(b64.encode(Longs.toByteArray(length() ^ lhash))); b.append('"'); return b.toString(); } catch (URISyntaxException x) { throw Throwing.sneakyThrow(x); } }
@Override public String etag() { return asset.etag(); }
@Override public String name() { return asset.name(); }
@Override public URL resource() { return asset.resource(); }
String etag = asset.etag(); boolean ifnm = req.header("If-None-Match").toOptional() .map(etag::equals) long lastModified = asset.lastModified(); if (lastModified > 0) { boolean ifm = req.header("If-Modified-Since").toOptional(Long.class)
@Override public InputStream stream() throws Exception { return asset.stream(); }
@Override public String path() { return asset.path(); }
@Override public MediaType type() { return asset.type(); }
@Override public long length() { return asset.length(); }
@Override public long lastModified() { return asset.lastModified(); }
@Override public URL resource() { return asset.resource(); }
String etag = asset.etag(); boolean ifnm = req.header("If-None-Match").toOptional() .map(etag::equals) long lastModified = asset.lastModified(); if (lastModified > 0) { boolean ifm = req.header("If-Modified-Since").toOptional(Long.class)
@Override public void download(final String filename, final InputStream stream) throws Throwable { requireNonNull(filename, "A file's name is required."); requireNonNull(stream, "A stream is required."); // handle type type(type().orElseGet(() -> MediaType.byPath(filename).orElse(MediaType.octetstream))); Asset asset = new InputStreamAsset(stream, filename, type); contentDisposition(filename); send(Results.with(asset.stream())); }
/** * Examples: * * <pre> * GET /assets/index.js {@literal ->} index.js * GET /assets/js/index.js {@literal ->} index.js * </pre> * * @return The asset name (without path). */ @Nonnull default String name() { String path = path(); int slash = path.lastIndexOf('/'); return path.substring(slash + 1); }
@Override public MediaType type() { return asset.type(); }
@Override public long length() { return asset.length(); }