-
-
Save stopher/5495353 to your computer and use it in GitHub Desktop.
public class ByteRangeRequestsController extends Controller { | |
// 206 Partial content Byte range requests | |
private static Result stream(long start, long length, File file) throws IOException { | |
FileInputStream fis = new FileInputStream(file); | |
fis.skip(start); | |
response().setContentType(MimeTypes.forExtension("mp4").get()); | |
response().setHeader(CONTENT_LENGTH, ((length - start) +1l)+""); | |
response().setHeader(CONTENT_RANGE, String.format("bytes %d-%d/%d", start, length,file.length())); | |
response().setHeader(ACCEPT_RANGES, "bytes"); | |
response().setHeader(CONNECTION, "keep-alive"); | |
return status(PARTIAL_CONTENT, fis); | |
} | |
// GET a file item | |
public static Result file(Long id, String filename) throws IOException { | |
Item item = Item.fetch(id); | |
File file = item.getFile(); | |
if(file== null || !file.exists()) { | |
Logger.error("File no longer exist item"+id+" filename:"+filename); | |
return notFound(); | |
} | |
String rangeheader = request().getHeader(RANGE); | |
if(rangeheader != null) { | |
String[] split = rangeheader.substring("bytes=".length()).split("-"); | |
if(Logger.isDebugEnabled()) { Logger.debug("Range header is:"+rangeheader); } | |
if(split.length == 1) { | |
long start = Long.parseLong(split[0]); | |
long length = file.length()-1l; | |
return stream(start, length, file); | |
} else { | |
long start = Long.parseLong(split[0]); | |
long length = Long.parseLong(split[1]); | |
return stream(start, length, file); | |
} | |
} | |
// if no streaming is required we simply return the file as a 200 OK | |
if(Play.isProd()) { | |
response().setHeader("Cache-Control", "max-age=3600, must-revalidate"); | |
} | |
return ok(file); | |
} | |
} |
Great post, thank you so much, you made my day. I saw lots of post related to streaming all have some bug or error but your post is complete.
Anyone have issues with Netty using this? I get:
2017-12-07T16:39:35.246Z [warn] com.lightbend.lagom.gateway.NettyServiceGateway [] - Exception caught in proxy connection
java.lang.NullPointerException: null
at io.netty.handler.codec.http.HttpHeaders.isKeepAlive(HttpHeaders.java:576)
at com.lightbend.lagom.gateway.NettyServiceGateway$ProxyHandler$$anon$3.handleLastContent(NettyServiceGateway.scala:298)
at com.lightbend.lagom.gateway.NettyServiceGateway$ProxyHandler$$anon$3.channelRead(NettyServiceGateway.scala:251)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:356)
at io.netty.channel.AbstractChannelHandlerContext.access$600(AbstractChannelHandlerContext.java:35)
at io.netty.channel.AbstractChannelHandlerContext$7.run(AbstractChannelHandlerContext.java:347)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:399)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:464)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:131)
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138)
at java.lang.Thread.run(Thread.java:748)
@felix-schwarz Are you sure? I am not seeing any issues when sending the Content-Length header. Do you have some more information - what exactly should fail when sending the header?