@Override public void setResponseHeader(String name, String value) { response.getHeaders().set(name, value); }
/** * Forces the closing of the current connection, even if the client requested it to be kept alive. * <p> * This method can be used when it is desirable to force the client's connection to close, defeating HTTP keep alive. * This can be desirable in some networking environments where rate limiting or throttling is performed via edge routers or similar. * <p> * This method simply calls {@code getHeaders().set("Connection", "close")}, which has the same effect. * * @return {@code this} * @since 1.1 */ default Response forceCloseConnection() { getHeaders().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE); return this; } }
/** * Sets a response header. * <p> * Any previously set values for the header will be removed. * <p> * Shorthand for {@code getResponse().getHeaders().set(CharSequence, Iterable)}. * * @param name the name of the header to set * @param values the header values * @return {@code this} * @since 1.4 * @see MutableHeaders#set(CharSequence, Iterable) */ default Context header(CharSequence name, Object... values) { getResponse().getHeaders().set(name, Arrays.asList(values)); return this; }
@Override public void lastModified(Instant lastModified, Runnable runnable) { Instant ifModifiedSince = requestConstants.request.getHeaders().getInstant(IF_MODIFIED_SINCE); if (ifModifiedSince != null) { // Normalise to second resolution ifModifiedSince = Instant.ofEpochSecond(ifModifiedSince.getEpochSecond()); lastModified = Instant.ofEpochSecond(lastModified.getEpochSecond()); if (!lastModified.isAfter(ifModifiedSince)) { requestConstants.response.status(Status.NOT_MODIFIED).send(); return; } } requestConstants.response.getHeaders().setDate(HttpHeaderConstants.LAST_MODIFIED, lastModified); runnable.run(); }
/** * {@inheritDoc} */ @Override public void render(Context context) throws Exception { ByteBufAllocator bufferAllocator = context.get(ByteBufAllocator.class); Response response = context.getResponse(); response.getHeaders().add(HttpHeaderConstants.CONTENT_TYPE, HttpHeaderConstants.TEXT_EVENT_STREAM_CHARSET_UTF_8); response.getHeaders().add(HttpHeaderConstants.TRANSFER_ENCODING, HttpHeaderConstants.CHUNKED); response.getHeaders().add(HttpHeaderConstants.CACHE_CONTROL, HttpHeaderConstants.NO_CACHE_FULL); response.getHeaders().add(HttpHeaderConstants.PRAGMA, HttpHeaderConstants.NO_CACHE); response.sendStream(Streams.map(publisher, i -> ServerSentEventEncoder.INSTANCE.encode(i, bufferAllocator))); }
@Override public void forwardTo(Response response) { response.getHeaders().copy(headers); response.status(status); ByteBuf buffer = typedData.getBuffer(); if (buffer.readableBytes() > 0) { response.send(buffer.retain()); } else { buffer.release(); response.send(); } }
/** * {@inheritDoc} */ @Override public void render(Context context) throws Exception { Response response = context.getResponse(); response.getHeaders().add(HttpHeaderConstants.TRANSFER_ENCODING, HttpHeaderConstants.CHUNKED); response.getHeaders().set(HttpHeaderConstants.CONTENT_TYPE, getContentType()); Publisher<? extends ByteBuf> publisher = publisher(context.get(ByteBufAllocator.class)); response.sendStream(publisher); }
@Override public void redirect(Context context, int code, Object to) { String stringValue; if (to instanceof URI) { stringValue = ((URI) to).toASCIIString(); } else { stringValue = to.toString(); } context.getResponse().status(code); String normalizedLocation = generateRedirectLocation(context, context.getRequest(), stringValue); context.getResponse().getHeaders().set(HttpHeaderConstants.LOCATION, normalizedLocation); context.getResponse().send(); }
@Override public void handle(Context context) throws Exception { HttpMethod method = context.getRequest().getMethod(); if (method.isOptions() && !handlers.containsKey(HttpMethod.OPTIONS)) { List<String> parts = new ArrayList<>(Collections2.transform(handlers.keySet(), HttpMethod::getName)); Collections.sort(parts); String methods = JOINER.join(parts); context.getResponse().getHeaders().add(HttpHeaderConstants.ALLOW, methods); context.getResponse().status(200).send(); } else { Handler handler = handlers.get(method); if (handler != null) { context.insert(handler); return; } if (method.isHead()) { Handler getHandler = handlers.get(HttpMethod.GET); if (getHandler != null) { context.insert(getHandler); return; } } NO_METHOD_HANDLER.handle(context); } }
public static void sendFile(Context context, Path file, BasicFileAttributes attributes) { Date date = new Date(attributes.lastModifiedTime().toMillis()); context.lastModified(date, () -> { final String ifNoneMatch = context.getRequest().getHeaders().get(HttpHeaderNames.IF_NONE_MATCH); Response response = context.getResponse(); if (ifNoneMatch != null && ifNoneMatch.trim().equals("*")) { response.status(NOT_MODIFIED.code()).send(); return; } response.contentTypeIfNotSet(() -> context.get(MimeTypes.class).getContentType(file.getFileName().toString())); response.getHeaders().set(HttpHeaderConstants.CONTENT_LENGTH, Long.toString(attributes.size())); try { response.sendFile(file); } catch (Exception e) { throw Exceptions.uncheck(e); } }); }
/** * Adds the number of milliseconds of elapsed time between {@link Request#getTimestamp()} and when the response is ready to be sent. * <p> * The timer is stopped, and the header added, by {@link Response#beforeSend(ratpack.func.Action)}. * This means that the time value is the elapsed time, commonly referred to as wall clock time, and not CPU time. * Similarly, it does not include the time to actually start sending data out over the socket. * It effectively times the application processing. * <p> * The value is in milliseconds, accurate to 5 decimal places. * * @param ctx the handling context. */ @Override public void handle(Context ctx) { Response response = ctx.getResponse(); response.beforeSend(m -> { Clock clock = ctx.get(Clock.class); Instant start = ctx.getRequest().getTimestamp(); long nanos = start.until(Instant.now(clock), ChronoUnit.NANOS); BigDecimal diffNanos = new BigDecimal(nanos); BigDecimal diffMillis = diffNanos.divide(NANOS_IN_MILLIS, 5, RoundingMode.UP); m.getHeaders().set(HEADER_NAME, diffMillis.toString()); }); ctx.next(); } }
LOGGER.warn(message); response.getHeaders().clear(); response.getHeaders().set(HttpHeaderConstants.CONTENT_LENGTH, body.readableBytes()); responseTransmitter.transmit(HttpResponseStatus.INTERNAL_SERVER_ERROR, body);
/** * Renders health checks. * * @param ctx the request context */ @Override public void handle(Context ctx) throws Exception { ctx.getResponse().getHeaders() .add("Cache-Control", "no-cache, no-store, must-revalidate") .add("Pragma", "no-cache") .add("Expires", 0); String checkName = ctx.getPathTokens().get(name); if (checkName != null) { Optional<HealthCheck> first = ctx.first(HEALTH_CHECK_TYPE_TOKEN, healthCheck -> healthCheck.getName().equals(checkName) ? healthCheck : null); if (first.isPresent()) { ctx.render(HealthCheck.checkAll(ctx, Collections.singleton(first.get()))); } else { ctx.clientError(404); } } else { ctx.render(HealthCheck.checkAll(ctx, throttle, ctx.getAll(HEALTH_CHECK_TYPE_TOKEN))); } }
public void handle(Context context) { ratpack.http.HttpMethod requestMethod = context.getRequest().getMethod(); if (requestMethod == method || requestMethod.name(method.getName())) { context.next(); } else if (requestMethod.isOptions()) { Response response = context.getResponse(); response.getHeaders().add(HttpHeaderConstants.ALLOW, method); response.status(200).send(); } else { context.clientError(405); } } }
@Override public void forwardTo(Response response, Action<? super MutableHeaders> headerMutator) { MutableHeaders outgoingHeaders = response.getHeaders(); outgoingHeaders.copy(headers); outgoingHeaders.remove(HttpHeaderNames.CONNECTION);