private static String addVersion1ResponseCookieToExchange(final Cookie cookie) { final StringBuilder header = new StringBuilder(cookie.getName()); header.append("="); header.append(cookie.getValue()); header.append("; Version=1"); if (cookie.getPath() != null) { header.append("; Path="); header.append(cookie.getPath()); } if (cookie.getDomain() != null) { header.append("; Domain="); header.append(cookie.getDomain()); } if (cookie.isDiscard()) { header.append("; Discard"); } if (cookie.isSecure()) { header.append("; Secure"); } if (cookie.isHttpOnly()) { header.append("; HttpOnly"); } if (cookie.getMaxAge() != null) { if (cookie.getMaxAge() >= 0) { header.append("; Max-Age="); header.append(cookie.getMaxAge()); } } if (cookie.getExpires() != null) { header.append("; Expires="); header.append(DateUtils.toDateString(cookie.getExpires())); } return header.toString(); }
public static void addDateHeaderIfRequired(HttpServerExchange exchange) { HeaderMap responseHeaders = exchange.getResponseHeaders(); if (exchange.getConnection().getUndertowOptions().get(UndertowOptions.ALWAYS_SET_DATE, true) && !responseHeaders.contains(Headers.DATE)) { long time = System.nanoTime(); if (time < nextUpdateTime) { responseHeaders.put(Headers.DATE, cachedDateString); } else { long realTime = System.currentTimeMillis(); String dateString = DateUtils.toDateString(new Date(realTime)); cachedDateString = dateString; nextUpdateTime = time + 1000000000; responseHeaders.put(Headers.DATE, dateString); } } }
@Override public void addDateHeader(final String name, final long date) { addHeader(name, DateUtils.toDateString(new Date(date))); }
/** * Attempts to serve the response from a cache. * * <p>If this fails, and the markCachable parameter is true then the response will be considered * cachable, and may be cached to be served by future handlers. * * <p>If this returns true then the caller should not modify the exchange any more, as this can * result in a handoff to an IO thread * * @param markCacheable If this is true then the resulting response will be considered cachable * @return <code>true</code> if serving suceeded, */ public boolean tryServeResponse(boolean markCacheable) { final CachedHttpRequest key = new CachedHttpRequest(exchange); DirectBufferCache.CacheEntry<CachedHttpRequest> entry = cache.get(key); // we only cache get and head requests if (!exchange.getRequestMethod().equals(GET) && !exchange.getRequestMethod().equals(HEAD)) { return false; } if (entry == null) { this.responseCachable = markCacheable; return false; } // It's loading retry later if (!entry.enabled() || !entry.reference()) { this.responseCachable = markCacheable; return false; } CachedHttpRequest existingKey = entry.key(); // if any of the header matches fail we just return // we don't can the request, as it is possible the underlying handler // may have additional etags final ETag etag = existingKey.getEtag(); if (!ETagUtils.handleIfMatch(exchange, etag, false)) { return false; } // we do send a 304 if the if-none-match header matches if (!ETagUtils.handleIfNoneMatch(exchange, etag, true)) { exchange.setResponseCode(304); exchange.endExchange(); return true; } // the server may have a more up to date representation if (!DateUtils.handleIfUnmodifiedSince(exchange, existingKey.getLastModified())) { return false; } if (!DateUtils.handleIfModifiedSince(exchange, existingKey.getLastModified())) { exchange.setResponseCode(304); exchange.endExchange(); return true; } // we are going to proceed. Set the appropriate headers if (existingKey.getContentType() != null) { exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, existingKey.getContentType()); } if (existingKey.getContentEncoding() != null && !Headers.IDENTITY.equals(HttpString.tryFromString(existingKey.getContentEncoding()))) { exchange.getResponseHeaders().put(Headers.CONTENT_ENCODING, existingKey.getContentEncoding()); } if (existingKey.getLastModified() != null) { exchange .getResponseHeaders() .put(Headers.LAST_MODIFIED, DateUtils.toDateString(existingKey.getLastModified())); } if (existingKey.getContentLocation() != null) { exchange.getResponseHeaders().put(Headers.CONTENT_LOCATION, existingKey.getContentLocation()); } if (existingKey.getLanguage() != null) { exchange.getResponseHeaders().put(Headers.CONTENT_LANGUAGE, existingKey.getLanguage()); } if (etag != null) { exchange.getResponseHeaders().put(Headers.CONTENT_LANGUAGE, etag.toString()); } // TODO: support if-range exchange.getResponseHeaders().put(Headers.CONTENT_LENGTH, Long.toString(entry.size())); if (exchange.getRequestMethod().equals(HEAD)) { exchange.endExchange(); return true; } final ByteBuffer[] buffers; boolean ok = false; try { LimitedBufferSlicePool.PooledByteBuffer[] pooled = entry.buffers(); buffers = new ByteBuffer[pooled.length]; for (int i = 0; i < buffers.length; i++) { // Keep position from mutating buffers[i] = pooled[i].getResource().duplicate(); } ok = true; } finally { if (!ok) { entry.dereference(); } } // Transfer Inline, or register and continue transfer // Pass off the entry dereference call to the listener exchange.getResponseSender().send(buffers, new DereferenceCallback(entry)); return true; }