@Override public long lastModifiedMillis() { final long newLastModifiedMillis = e.lastModifiedMillis(); if (newLastModifiedMillis != cachedLastModifiedMillis) { cachedLastModifiedMillis = newLastModifiedMillis; destroyContent(); } return newLastModifiedMillis; }
@Override public synchronized ByteBuf readContent(ByteBufAllocator alloc) throws IOException { if (cachedContent == null) { final ByteBuf newContent = e.readContent(alloc); if (newContent.readableBytes() > maxCacheEntrySizeBytes) { // Do not cache if the content is too large. return newContent; } cachedContent = newContent; } return cachedContent.duplicate().retain(); }
@Override public void invoke( ServiceInvocationContext ctx, Executor blockingTaskExecutor, Promise<Object> promise) throws Exception { final HttpRequest req = ctx.originalRequest(); if (req.method() != HttpMethod.GET) { respond( ctx, promise, HttpResponseStatus.METHOD_NOT_ALLOWED, 0, ERROR_MIME_TYPE, Unpooled.wrappedBuffer(CONTENT_METHOD_NOT_ALLOWED)); return; } final String path = normalizePath(ctx.mappedPath()); if (path == null) { respond( ctx, promise, HttpResponseStatus.NOT_FOUND, 0, ERROR_MIME_TYPE, Unpooled.wrappedBuffer(CONTENT_NOT_FOUND)); return; } Entry entry = getEntry(path); long lastModifiedMillis; if ((lastModifiedMillis = entry.lastModifiedMillis()) == 0) { boolean found = false; if (path.charAt(path.length() - 1) == '/') { // Try index.html if it was a directory access. entry = getEntry(path + "index.html"); if ((lastModifiedMillis = entry.lastModifiedMillis()) != 0) { found = true; } } if (!found) { respond( ctx, promise, HttpResponseStatus.NOT_FOUND, 0, ERROR_MIME_TYPE, Unpooled.wrappedBuffer(CONTENT_NOT_FOUND)); return; } } long ifModifiedSinceMillis = Long.MIN_VALUE; try { ifModifiedSinceMillis = req.headers().getTimeMillis(HttpHeaderNames.IF_MODIFIED_SINCE, Long.MIN_VALUE); } catch (Exception e) { // Ignore the ParseException, which is raised on malformed date. //noinspection ConstantConditions if (!(e instanceof ParseException)) { throw e; } } // HTTP-date does not have subsecond-precision; add 999ms to it. if (ifModifiedSinceMillis > Long.MAX_VALUE - 999) { ifModifiedSinceMillis = Long.MAX_VALUE; } else { ifModifiedSinceMillis += 999; } if (lastModifiedMillis < ifModifiedSinceMillis) { respond( ctx, promise, HttpResponseStatus.NOT_MODIFIED, lastModifiedMillis, entry.mimeType(), Unpooled.EMPTY_BUFFER); return; } respond( ctx, promise, HttpResponseStatus.OK, lastModifiedMillis, entry.mimeType(), entry.readContent(ctx.alloc())); }
@Override public String toString() { return e.toString(); }
@Override public String mimeType() { return e.mimeType(); }
CachedEntry(Entry e, int maxCacheEntrySizeBytes) { this.e = e; this.maxCacheEntrySizeBytes = maxCacheEntrySizeBytes; cachedLastModifiedMillis = e.lastModifiedMillis(); }