Search in sources :

Example 1 with RangeStreamSinkConduit

use of io.undertow.conduits.RangeStreamSinkConduit in project undertow by undertow-io.

the class ByteRangeHandler method handleRequest.

@Override
public void handleRequest(HttpServerExchange exchange) throws Exception {
    //range requests are only support for GET requests as per the RFC
    if (!Methods.GET.equals(exchange.getRequestMethod()) && !Methods.HEAD.equals(exchange.getRequestMethod())) {
        next.handleRequest(exchange);
        return;
    }
    if (sendAcceptRanges) {
        exchange.addResponseCommitListener(ACCEPT_RANGE_LISTENER);
    }
    final ByteRange range = ByteRange.parse(exchange.getRequestHeaders().getFirst(Headers.RANGE));
    if (range != null && range.getRanges() == 1) {
        exchange.addResponseWrapper(new ConduitWrapper<StreamSinkConduit>() {

            @Override
            public StreamSinkConduit wrap(ConduitFactory<StreamSinkConduit> factory, HttpServerExchange exchange) {
                if (exchange.getStatusCode() != StatusCodes.OK) {
                    return factory.create();
                }
                String length = exchange.getResponseHeaders().getFirst(Headers.CONTENT_LENGTH);
                if (length == null) {
                    return factory.create();
                }
                long responseLength = Long.parseLong(length);
                ByteRange.RangeResponseResult rangeResponse = range.getResponseResult(responseLength, exchange.getRequestHeaders().getFirst(Headers.IF_RANGE), DateUtils.parseDate(exchange.getResponseHeaders().getFirst(Headers.LAST_MODIFIED)), exchange.getResponseHeaders().getFirst(Headers.ETAG));
                if (rangeResponse != null) {
                    long start = rangeResponse.getStart();
                    long end = rangeResponse.getEnd();
                    exchange.setStatusCode(rangeResponse.getStatusCode());
                    exchange.getResponseHeaders().put(Headers.CONTENT_RANGE, rangeResponse.getContentRange());
                    exchange.setResponseContentLength(rangeResponse.getContentLength());
                    if (rangeResponse.getStatusCode() == StatusCodes.REQUEST_RANGE_NOT_SATISFIABLE) {
                        return new HeadStreamSinkConduit(factory.create(), null, true);
                    }
                    return new RangeStreamSinkConduit(factory.create(), start, end, responseLength);
                } else {
                    return factory.create();
                }
            }
        });
    }
    next.handleRequest(exchange);
}
Also used : HttpServerExchange(io.undertow.server.HttpServerExchange) RangeStreamSinkConduit(io.undertow.conduits.RangeStreamSinkConduit) ByteRange(io.undertow.util.ByteRange) HeadStreamSinkConduit(io.undertow.conduits.HeadStreamSinkConduit) RangeStreamSinkConduit(io.undertow.conduits.RangeStreamSinkConduit) StreamSinkConduit(org.xnio.conduits.StreamSinkConduit) HeadStreamSinkConduit(io.undertow.conduits.HeadStreamSinkConduit)

Aggregations

HeadStreamSinkConduit (io.undertow.conduits.HeadStreamSinkConduit)1 RangeStreamSinkConduit (io.undertow.conduits.RangeStreamSinkConduit)1 HttpServerExchange (io.undertow.server.HttpServerExchange)1 ByteRange (io.undertow.util.ByteRange)1 StreamSinkConduit (org.xnio.conduits.StreamSinkConduit)1