Example usage for io.netty.buffer Unpooled EMPTY_BUFFER

List of usage examples for io.netty.buffer Unpooled EMPTY_BUFFER

Introduction

In this page you can find the example usage for io.netty.buffer Unpooled EMPTY_BUFFER.

Prototype

ByteBuf EMPTY_BUFFER

To view the source code for io.netty.buffer Unpooled EMPTY_BUFFER.

Click Source Link

Document

A buffer whose capacity is 0 .

Usage

From source file:com.linecorp.armeria.internal.Http1ObjectEncoder.java

License:Apache License

private HttpObject convertServerHeaders(int streamId, HttpHeaders headers, boolean endStream)
        throws Http2Exception {

    // Leading headers will always have :status, trailers will never have it.
    final HttpStatus status = headers.status();
    if (status == null) {
        return convertTrailingHeaders(streamId, headers);
    }//from   ww w .  ja v  a2s.c  o m

    // Convert leading headers.
    final HttpResponse res;
    final boolean informational = status.codeClass() == HttpStatusClass.INFORMATIONAL;
    final HttpResponseStatus nettyStatus = HttpResponseStatus.valueOf(status.code());

    if (endStream || informational) {

        res = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, nettyStatus, Unpooled.EMPTY_BUFFER, false);

        final io.netty.handler.codec.http.HttpHeaders outHeaders = res.headers();
        convert(streamId, headers, outHeaders, false);

        if (informational) {
            // 1xx responses does not have the 'content-length' header.
            outHeaders.remove(HttpHeaderNames.CONTENT_LENGTH);
        } else if (!headers.contains(HttpHeaderNames.CONTENT_LENGTH)) {
            // NB: Set the 'content-length' only when not set rather than always setting to 0.
            //     It's because a response to a HEAD request can have empty content while having
            //     non-zero 'content-length' header.
            //     However, this also opens the possibility of sending a non-zero 'content-length'
            //     header even when it really has to be zero. e.g. a response to a non-HEAD request
            outHeaders.setInt(HttpHeaderNames.CONTENT_LENGTH, 0);
        }
    } else {
        res = new DefaultHttpResponse(HttpVersion.HTTP_1_1, nettyStatus, false);
        // Perform conversion.
        convert(streamId, headers, res.headers(), false);
        setTransferEncoding(res);
    }

    return res;
}

From source file:com.linecorp.armeria.internal.Http1ObjectEncoder.java

License:Apache License

@Override
protected ChannelFuture doWriteReset(ChannelHandlerContext ctx, int id, int streamId, Http2Error error) {
    // NB: this.minClosedId can be overwritten more than once when 3+ pipelined requests are received
    //     and they are handled by different threads simultaneously.
    //     e.g. when the 3rd request triggers a reset and then the 2nd one triggers another.
    minClosedId = Math.min(minClosedId, id);
    for (int i = minClosedId; i <= maxIdWithPendingWrites; i++) {
        final PendingWrites pendingWrites = pendingWritesMap.remove(i);
        for (;;) {
            final Entry<HttpObject, ChannelPromise> e = pendingWrites.poll();
            if (e == null) {
                break;
            }//from  w  ww.  j  a v a  2  s.  c  o  m
            e.getValue().tryFailure(ClosedSessionException.get());
        }
    }

    final ChannelFuture f = ctx.write(Unpooled.EMPTY_BUFFER);
    if (currentId >= minClosedId) {
        f.addListener(ChannelFutureListener.CLOSE);
    }

    return f;
}

From source file:com.linecorp.armeria.server.http.file.HttpFileServiceInvocationHandler.java

License:Apache License

@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;/*from   ww  w  .jav  a2s.c o m*/
    }

    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()));
}

From source file:com.linecorp.armeria.server.http.Http1RequestDecoder.java

License:Apache License

private void fail(ChannelHandlerContext ctx, HttpResponseStatus status) {
    discarding = true;/*w ww . j  a  va  2  s .co m*/
    req = null;

    final ChannelFuture future;
    if (receivedRequests <= sentResponses) {
        // Just close the connection if sending an error response will make the number of the sent
        // responses exceed the number of the received requests, which doesn't make sense.
        future = ctx.writeAndFlush(Unpooled.EMPTY_BUFFER);
    } else {
        final ByteBuf content = Unpooled.copiedBuffer(status.toString(), StandardCharsets.UTF_8);
        final FullHttpResponse res = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status, content);

        final HttpHeaders headers = res.headers();
        headers.set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE);
        headers.set(HttpHeaderNames.CONTENT_TYPE, MediaType.PLAIN_TEXT_UTF_8);
        headers.setInt(HttpHeaderNames.CONTENT_LENGTH, content.readableBytes());

        future = ctx.writeAndFlush(res);
    }

    future.addListener(ChannelFutureListener.CLOSE);
}

From source file:com.linecorp.armeria.server.http.HttpServerHandler.java

License:Apache License

private void handleRequest(ChannelHandlerContext ctx, DecodedHttpRequest req) throws Exception {
    // Ignore the request received after the last request,
    // because we are going to close the connection after sending the last response.
    if (handledLastRequest) {
        return;//from  w w w.j  a  v  a 2  s  .co m
    }

    // If we received the message with keep-alive disabled,
    // we should not accept a request anymore.
    if (!req.isKeepAlive()) {
        handledLastRequest = true;
    }

    final HttpHeaders headers = req.headers();
    if (!ALLOWED_METHODS.contains(headers.method())) {
        respond(ctx, req, HttpStatus.METHOD_NOT_ALLOWED);
        return;
    }

    // Handle 'OPTIONS * HTTP/1.1'.
    final String originalPath = headers.path();
    if (originalPath.isEmpty() || originalPath.charAt(0) != '/') {
        if (headers.method() == HttpMethod.OPTIONS && "*".equals(originalPath)) {
            handleOptions(ctx, req);
        } else {
            respond(ctx, req, HttpStatus.BAD_REQUEST);
        }
        return;
    }

    // Validate and split path and query.
    final String path = validatePathAndStripQuery(originalPath);
    if (path == null) {
        // Reject requests without a valid path.
        respond(ctx, req, HttpStatus.NOT_FOUND);
        return;
    }

    if (headers.authority() == null) {
        // HTTP/1.1 requests require a host header.
        respond(ctx, req, HttpStatus.BAD_REQUEST);
        return;
    }

    final String hostname = hostname(headers);
    final VirtualHost host = config.findVirtualHost(hostname);

    // Find the service that matches the path.
    final PathMapped<ServiceConfig> mapped = host.findServiceConfig(path);
    if (!mapped.isPresent()) {
        // No services matched the path.
        handleNonExistentMapping(ctx, req, host, path);
        return;
    }

    // Decode the request and create a new invocation context from it to perform an invocation.
    final String mappedPath = mapped.mappedPath();
    final ServiceConfig serviceCfg = mapped.value();
    final Service<Request, HttpResponse> service = serviceCfg.service();

    final Channel channel = ctx.channel();
    final ServiceRequestContext reqCtx = new DefaultServiceRequestContext(serviceCfg, channel, protocol,
            req.method().name(), path, mappedPath, LoggerFactory.getLogger(serviceCfg.loggerName()), req);

    final RequestLogBuilder reqLogBuilder = reqCtx.requestLogBuilder();
    final HttpResponse res;
    try (PushHandle ignored = RequestContext.push(reqCtx)) {
        req.init(reqCtx);
        res = service.serve(reqCtx, req);
    } catch (Throwable cause) {
        reqLogBuilder.end(cause);
        if (cause instanceof ResourceNotFoundException) {
            respond(ctx, req, HttpStatus.NOT_FOUND);
        } else if (cause instanceof ServiceUnavailableException) {
            respond(ctx, req, HttpStatus.SERVICE_UNAVAILABLE);
        } else {
            logger.warn("{} Unexpected exception: {}, {}", reqCtx, service, req, cause);
            respond(ctx, req, HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return;
    }

    final EventLoop eventLoop = channel.eventLoop();

    // Keep track of the number of unfinished requests and
    // clean up the request stream when response stream ends.
    unfinishedRequests++;
    res.closeFuture().handle(voidFunction((ret, cause) -> {
        req.abort();
        if (cause == null) {
            reqLogBuilder.end();
        } else {
            reqLogBuilder.end(cause);
        }
        eventLoop.execute(() -> {
            if (--unfinishedRequests == 0 && handledLastRequest) {
                ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(CLOSE);
            }
        });
    })).exceptionally(CompletionActions::log);

    res.subscribe(new HttpResponseSubscriber(ctx, responseEncoder, reqCtx, req), eventLoop);
}

From source file:com.linecorp.armeria.server.http.ServiceCodecPromiseTest.java

License:Apache License

protected static void setupServer(ServerBuilder sb,
        GenericFutureListener<? extends Future<? super Object>> listener, ServiceInvocationHandler handler) {
    Service service = Service.of(new DecoratingServiceCodec(new HttpServiceCodec()) {
        @Override//w  w  w .j av  a  2  s.  c  o m
        public DecodeResult decodeRequest(ServiceConfig cfg, Channel ch, SessionProtocol sessionProtocol,
                String hostname, String path, String mappedPath, ByteBuf in, Object originalRequest,
                Promise<Object> promise) throws Exception {
            promise.addListener(listener);
            return delegate().decodeRequest(cfg, ch, sessionProtocol, hostname, path, mappedPath, in,
                    originalRequest, promise);
        }

        @Override
        public ByteBuf encodeResponse(ServiceInvocationContext ctx, Object response) throws Exception {
            return Unpooled.EMPTY_BUFFER;
        }
    }, handler);

    sb.serviceAt("/", service);
}

From source file:com.linecorp.armeria.server.HttpServerHandler.java

License:Apache License

private void handleRequest(ChannelHandlerContext ctx, DecodedHttpRequest req) throws Exception {
    // Ignore the request received after the last request,
    // because we are going to close the connection after sending the last response.
    if (handledLastRequest) {
        return;/* w  w  w. j  a  v a  2s  .c o m*/
    }

    // If we received the message with keep-alive disabled,
    // we should not accept a request anymore.
    if (!req.isKeepAlive()) {
        handledLastRequest = true;
    }

    final HttpHeaders headers = req.headers();
    if (!ALLOWED_METHODS.contains(headers.method())) {
        respond(ctx, req, HttpStatus.METHOD_NOT_ALLOWED,
                new IllegalArgumentException("Request method is not allowed: " + headers.method().name()));
        return;
    }

    // Handle 'OPTIONS * HTTP/1.1'.
    final String originalPath = headers.path();
    if (originalPath == null) {
        respond(ctx, req, HttpStatus.BAD_REQUEST, new IllegalArgumentException("Request path is missing."));
        return;
    }
    if (originalPath.isEmpty() || originalPath.charAt(0) != '/') {
        if (headers.method() == HttpMethod.OPTIONS && "*".equals(originalPath)) {
            handleOptions(ctx, req);
        } else {
            respond(ctx, req, HttpStatus.BAD_REQUEST,
                    new IllegalArgumentException("Request path is invalid: " + originalPath));
        }
        return;
    }

    // Validate and split path and query.
    final PathAndQuery pathAndQuery = PathAndQuery.parse(originalPath);
    if (pathAndQuery == null) {
        // Reject requests without a valid path.
        respond(ctx, req, HttpStatus.NOT_FOUND,
                new IllegalArgumentException("Request path is invalid: " + originalPath));
        return;
    }

    final String hostname = hostname(ctx, headers);
    final VirtualHost host = config.findVirtualHost(hostname);

    final PathMappingContext mappingCtx = DefaultPathMappingContext.of(host, hostname, pathAndQuery.path(),
            pathAndQuery.query(), headers, host.producibleMediaTypes());
    // Find the service that matches the path.
    final PathMapped<ServiceConfig> mapped;
    try {
        mapped = host.findServiceConfig(mappingCtx);
    } catch (HttpStatusException cause) {
        // We do not need to handle HttpResponseException here because we do not use it internally.
        respond(ctx, req, pathAndQuery, cause.httpStatus(), cause);
        return;
    } catch (Throwable cause) {
        logger.warn("{} Unexpected exception: {}", ctx.channel(), req, cause);
        respond(ctx, req, pathAndQuery, HttpStatus.INTERNAL_SERVER_ERROR, cause);
        return;
    }
    if (!mapped.isPresent()) {
        // No services matched the path.
        handleNonExistentMapping(ctx, req, host, pathAndQuery, mappingCtx);
        return;
    }

    // Decode the request and create a new invocation context from it to perform an invocation.
    final PathMappingResult mappingResult = mapped.mappingResult();
    final ServiceConfig serviceCfg = mapped.value();
    final Service<HttpRequest, HttpResponse> service = serviceCfg.service();

    final Channel channel = ctx.channel();
    final DefaultServiceRequestContext reqCtx = new DefaultServiceRequestContext(serviceCfg, channel,
            serviceCfg.server().meterRegistry(), protocol, mappingCtx, mappingResult, req,
            getSSLSession(channel), proxiedAddresses);

    try (SafeCloseable ignored = RequestContext.push(reqCtx)) {
        final RequestLogBuilder logBuilder = reqCtx.logBuilder();
        HttpResponse serviceResponse;
        try {
            req.init(reqCtx);
            serviceResponse = service.serve(reqCtx, req);
        } catch (HttpResponseException cause) {
            serviceResponse = cause.httpResponse();
        } catch (Throwable cause) {
            try {
                if (cause instanceof HttpStatusException) {
                    respond(ctx, req, ((HttpStatusException) cause).httpStatus(), reqCtx, cause);
                } else {
                    logger.warn("{} Unexpected exception: {}, {}", reqCtx, service, req, cause);
                    respond(ctx, req, HttpStatus.INTERNAL_SERVER_ERROR, reqCtx, cause);
                }
            } finally {
                logBuilder.endRequest(cause);
                logBuilder.endResponse(cause);
            }
            return;
        }
        final HttpResponse res = serviceResponse;

        final EventLoop eventLoop = channel.eventLoop();

        // Keep track of the number of unfinished requests and
        // clean up the request stream when response stream ends.
        gracefulShutdownSupport.inc();
        unfinishedRequests++;
        unfinishedResponses.put(res, true);

        if (service.shouldCachePath(pathAndQuery.path(), pathAndQuery.query(), mapped.mapping())) {
            reqCtx.log().addListener(log -> {
                final HttpStatus status = log.responseHeaders().status();
                if (status != null && status.code() >= 200 && status.code() < 400) {
                    pathAndQuery.storeInCache(originalPath);
                }
            }, RequestLogAvailability.COMPLETE);
        }

        req.completionFuture().handle(voidFunction((ret, cause) -> {
            if (cause == null) {
                logBuilder.endRequest();
            } else {
                logBuilder.endRequest(cause);
                // NB: logBuilder.endResponse(cause) will be called by HttpResponseSubscriber below
            }
        })).exceptionally(CompletionActions::log);

        res.completionFuture().handleAsync(voidFunction((ret, cause) -> {
            req.abort();
            // NB: logBuilder.endResponse() is called by HttpResponseSubscriber below.
            gracefulShutdownSupport.dec();
            unfinishedResponses.remove(res);
            if (--unfinishedRequests == 0 && handledLastRequest) {
                ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(CLOSE);
            }
        }), eventLoop).exceptionally(CompletionActions::log);

        assert responseEncoder != null;
        final HttpResponseSubscriber resSubscriber = new HttpResponseSubscriber(ctx, responseEncoder, reqCtx,
                req, accessLogWriter);
        reqCtx.setRequestTimeoutChangeListener(resSubscriber);
        res.subscribe(resSubscriber, eventLoop, true);
    }
}

From source file:com.linecorp.armeria.server.metrics.MetricCollectingServiceCodecTest.java

License:Apache License

@SuppressWarnings("unchecked")
protected static void setupServer(ServerBuilder sb, ServiceInvocationHandler handler,
        final MetricConsumer consumer) throws Exception {
    ServiceCodec codec = Mockito.mock(ServiceCodec.class);
    DecodeResult decodeResult = Mockito.mock(DecodeResult.class);
    DefaultAttributeMap defaultAttributeMap = new DefaultAttributeMap();
    ServiceInvocationContext invocationContext = Mockito.mock(ServiceInvocationContext.class);

    when(decodeResult.type()).thenReturn(DecodeResultType.SUCCESS);
    when(decodeResult.invocationContext()).thenReturn(invocationContext);
    when(invocationContext.attr(any())).then(x -> defaultAttributeMap.attr(AttributeKey.valueOf("TEST")));
    when(invocationContext.method()).thenReturn("someMethod");

    when(codec.decodeRequest(any(), any(), any(), any(), any(), any(), any(), any(), any()))
            .thenReturn(decodeResult);/* w w w  . j a va 2  s. c o m*/

    when(codec.encodeResponse(any(), any())).thenReturn(Unpooled.EMPTY_BUFFER);
    when(codec.encodeFailureResponse(any(), any())).thenReturn(Unpooled.EMPTY_BUFFER);

    sb.serviceAt("/", Service.of(new MetricCollectingServiceCodec(codec, consumer), handler));
}

From source file:com.linecorp.armeria.unsafe.ByteBufHttpData.java

License:Apache License

/**
 * Constructs a new {@link ByteBufHttpData}. Ownership of {@code buf} is taken by this
 * {@link ByteBufHttpData}, which must not be mutated anymore.
 *//*from  www.  j  av a2  s. c o m*/
public ByteBufHttpData(ByteBuf buf, boolean endOfStream) {
    length = requireNonNull(buf, "buf").readableBytes();
    if (length != 0) {
        this.buf = buf;
    } else {
        buf.release();
        this.buf = Unpooled.EMPTY_BUFFER;
    }
    this.endOfStream = endOfStream;
}

From source file:com.linkedin.mitm.proxy.channel.ChannelMediator.java

License:Open Source License

private Future<Void> disconnect(final Channel channel) {
    if (channel == null) {
        return null;
    }//from  w w  w  . ja  va  2 s  .com
    final Promise<Void> promise = channel.newPromise();
    writeToChannel(channel, Unpooled.EMPTY_BUFFER).addListener(future -> closeChannel(promise, channel));
    return promise;
}