Search in sources :

Example 1 with Response

use of ratpack.http.Response in project ratpack by ratpack.

the class NettyHandlerAdapter method newRequest.

private void newRequest(final ChannelHandlerContext ctx, final HttpRequest nettyRequest) throws Exception {
    if (!nettyRequest.decoderResult().isSuccess()) {
        sendError(ctx, HttpResponseStatus.BAD_REQUEST);
        return;
    }
    Headers requestHeaders = new NettyHeadersBackedHeaders(nettyRequest.headers());
    //Find the content length we will use this as an indicator of a body
    Long contentLength = HttpUtil.getContentLength(nettyRequest, -1L);
    String transferEncoding = requestHeaders.get(HttpHeaderNames.TRANSFER_ENCODING);
    //If there is a content length or transfer encoding that indicates there is a body
    boolean hasBody = (contentLength > 0) || (transferEncoding != null);
    RequestBody requestBody = hasBody ? new RequestBody(contentLength, nettyRequest, ctx) : null;
    final Channel channel = ctx.channel();
    if (requestBody != null) {
        channel.attr(BODY_ACCUMULATOR_KEY).set(requestBody);
    }
    InetSocketAddress remoteAddress = (InetSocketAddress) channel.remoteAddress();
    InetSocketAddress socketAddress = (InetSocketAddress) channel.localAddress();
    final DefaultRequest request = new DefaultRequest(Instant.now(), requestHeaders, nettyRequest.method(), nettyRequest.protocolVersion(), nettyRequest.uri(), remoteAddress, socketAddress, serverRegistry.get(ServerConfig.class), requestBody);
    final HttpHeaders nettyHeaders = new DefaultHttpHeaders(false);
    final MutableHeaders responseHeaders = new NettyHeadersBackedMutableHeaders(nettyHeaders);
    final AtomicBoolean transmitted = new AtomicBoolean(false);
    final DefaultResponseTransmitter responseTransmitter = new DefaultResponseTransmitter(transmitted, channel, nettyRequest, request, nettyHeaders, requestBody);
    ctx.channel().attr(DefaultResponseTransmitter.ATTRIBUTE_KEY).set(responseTransmitter);
    Action<Action<Object>> subscribeHandler = thing -> {
        transmitted.set(true);
        ctx.channel().attr(CHANNEL_SUBSCRIBER_ATTRIBUTE_KEY).set(thing);
    };
    final DefaultContext.RequestConstants requestConstants = new DefaultContext.RequestConstants(applicationConstants, request, channel, responseTransmitter, subscribeHandler);
    final Response response = new DefaultResponse(responseHeaders, ctx.alloc(), responseTransmitter);
    requestConstants.response = response;
    DefaultContext.start(channel.eventLoop(), requestConstants, serverRegistry, handlers, execution -> {
        if (requestBody != null) {
            requestBody.close();
            channel.attr(BODY_ACCUMULATOR_KEY).set(null);
        }
        if (!transmitted.get()) {
            Handler lastHandler = requestConstants.handler;
            StringBuilder description = new StringBuilder();
            description.append("No response sent for ").append(request.getMethod().getName()).append(" request to ").append(request.getUri());
            if (lastHandler != null) {
                description.append(" (last handler: ");
                if (lastHandler instanceof DescribingHandler) {
                    ((DescribingHandler) lastHandler).describeTo(description);
                } else {
                    DescribingHandlers.describeTo(lastHandler, description);
                }
                description.append(")");
            }
            String message = description.toString();
            LOGGER.warn(message);
            response.getHeaders().clear();
            ByteBuf body;
            if (development) {
                CharBuffer charBuffer = CharBuffer.wrap(message);
                body = ByteBufUtil.encodeString(ctx.alloc(), charBuffer, CharsetUtil.UTF_8);
                response.contentType(HttpHeaderConstants.PLAIN_TEXT_UTF8);
            } else {
                body = Unpooled.EMPTY_BUFFER;
            }
            response.getHeaders().set(HttpHeaderConstants.CONTENT_LENGTH, body.readableBytes());
            responseTransmitter.transmit(HttpResponseStatus.INTERNAL_SERVER_ERROR, body);
        }
    });
}
Also used : AttributeKey(io.netty.util.AttributeKey) DescribingHandlers(ratpack.handling.internal.DescribingHandlers) LoggerFactory(org.slf4j.LoggerFactory) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Unpooled(io.netty.buffer.Unpooled) ByteBuf(io.netty.buffer.ByteBuf) MutableHeaders(ratpack.http.MutableHeaders) ServerConfig(ratpack.server.ServerConfig) Registry(ratpack.registry.Registry) CharsetUtil(io.netty.util.CharsetUtil) DefaultRenderController(ratpack.render.internal.DefaultRenderController) io.netty.channel(io.netty.channel) DefaultContext(ratpack.handling.internal.DefaultContext) Logger(org.slf4j.Logger) CharBuffer(java.nio.CharBuffer) ClosedChannelException(java.nio.channels.ClosedChannelException) ratpack.http.internal(ratpack.http.internal) ChainHandler(ratpack.handling.internal.ChainHandler) IOException(java.io.IOException) DescribingHandler(ratpack.handling.internal.DescribingHandler) Instant(java.time.Instant) InetSocketAddress(java.net.InetSocketAddress) ByteBufUtil(io.netty.buffer.ByteBufUtil) io.netty.handler.codec.http(io.netty.handler.codec.http) Response(ratpack.http.Response) Headers(ratpack.http.Headers) Action(ratpack.func.Action) Handler(ratpack.handling.Handler) Handlers(ratpack.handling.Handlers) ExecController(ratpack.exec.ExecController) Action(ratpack.func.Action) MutableHeaders(ratpack.http.MutableHeaders) Headers(ratpack.http.Headers) InetSocketAddress(java.net.InetSocketAddress) CharBuffer(java.nio.CharBuffer) ByteBuf(io.netty.buffer.ByteBuf) ServerConfig(ratpack.server.ServerConfig) MutableHeaders(ratpack.http.MutableHeaders) DescribingHandler(ratpack.handling.internal.DescribingHandler) ChainHandler(ratpack.handling.internal.ChainHandler) DescribingHandler(ratpack.handling.internal.DescribingHandler) Handler(ratpack.handling.Handler) Response(ratpack.http.Response) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) DefaultContext(ratpack.handling.internal.DefaultContext)

Example 2 with Response

use of ratpack.http.Response in project ratpack by ratpack.

the class FileRenderer method sendFile.

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);
        }
    });
}
Also used : Response(ratpack.http.Response) Date(java.util.Date)

Example 3 with Response

use of ratpack.http.Response in project ratpack by ratpack.

the class ServerSentEvents method render.

/**
   * {@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)));
}
Also used : Response(ratpack.http.Response) Response(ratpack.http.Response) Context(ratpack.handling.Context) ServerSentEventEncoder(ratpack.sse.internal.ServerSentEventEncoder) ByteBufAllocator(io.netty.buffer.ByteBufAllocator) Action(ratpack.func.Action) Publisher(org.reactivestreams.Publisher) Renderable(ratpack.render.Renderable) Streams(ratpack.stream.Streams) HttpHeaderConstants(ratpack.http.internal.HttpHeaderConstants) DefaultEvent(ratpack.sse.internal.DefaultEvent) ByteBufAllocator(io.netty.buffer.ByteBufAllocator)

Example 4 with Response

use of ratpack.http.Response in project ratpack by ratpack.

the class ResponseTimer method handle.

/**
   * 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();
}
Also used : Response(ratpack.http.Response) Instant(java.time.Instant) Clock(java.time.Clock) BigDecimal(java.math.BigDecimal)

Example 5 with Response

use of ratpack.http.Response in project ratpack by ratpack.

the class DefaultContext method onErrorHandlerError.

private void onErrorHandlerError(ServerErrorHandler serverErrorHandler, Throwable original, Throwable errorHandlerThrowable) {
    String msg = "Throwable thrown by error handler " + serverErrorHandler + " while handling throwable\n" + "Original throwable: " + getStackTraceAsString(original) + "\n" + "Error handler throwable: " + getStackTraceAsString(errorHandlerThrowable);
    LOGGER.error(msg);
    Response response = requestConstants.response.status(500);
    if (getServerConfig().isDevelopment()) {
        response.send(msg);
    } else {
        response.send();
    }
}
Also used : Response(ratpack.http.Response) Throwables.getStackTraceAsString(com.google.common.base.Throwables.getStackTraceAsString)

Aggregations

Response (ratpack.http.Response)5 Instant (java.time.Instant)2 Action (ratpack.func.Action)2 Throwables.getStackTraceAsString (com.google.common.base.Throwables.getStackTraceAsString)1 ByteBuf (io.netty.buffer.ByteBuf)1 ByteBufAllocator (io.netty.buffer.ByteBufAllocator)1 ByteBufUtil (io.netty.buffer.ByteBufUtil)1 Unpooled (io.netty.buffer.Unpooled)1 io.netty.channel (io.netty.channel)1 io.netty.handler.codec.http (io.netty.handler.codec.http)1 AttributeKey (io.netty.util.AttributeKey)1 CharsetUtil (io.netty.util.CharsetUtil)1 IOException (java.io.IOException)1 BigDecimal (java.math.BigDecimal)1 InetSocketAddress (java.net.InetSocketAddress)1 CharBuffer (java.nio.CharBuffer)1 ClosedChannelException (java.nio.channels.ClosedChannelException)1 Clock (java.time.Clock)1 Date (java.util.Date)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1