RE: Re: Re: How to server a video file
Hi, Thanks again for the prompt reply. > Hi Boris, > > Overriding doInit() method is easier as you don't need to make the > super.init() call and in addition if anything goes wrong, the doCatch() > will be invoked. Ok, thanks. > Regarding the broken pipe, I'm wondering it this isn't due to the ranged > request. Have you tried a straight/non-ranged HTTP call from curl or > another HTTP client? If the FileRepresentaton doesn't implement a range request, that'll break it. I believe Chrome does range requests while some other browsers (e.g. Mozilla) don't. It did work with curl so it must be comething related with the interaction with Chrome. Are there any docs, even unofficial, wikis or something that I could use as a starting point to implement a representation that supports range requests and whatever else is needed to make this work? > The idea to prevent direct access to header is not really to be more > general than HTTP, but rather to expose HTTP semantics as a Java API. This > is an aspect we might reconsider, especially for extension headers. Ok, but I think that addHeader static utility method could create the Series attribute in the request itself. Cause one can find addHeader in the APIs and say "Ah, I can try that", but it's much harder to figure out that you are supposed to add an attribute to the request before that, especially since in the servlet API for example, attributes are an application thing only. Cheers, Boris > Best regards, > Jerome > > > > 2013/6/15 Borislav Iordanov > > > Hi Jerome, > > > > Thanks a lot for your reply, replacing the handle() method by an > > implementation of get() yielded a NullPointerException in the > > ServerResource.handle implementation. It turned out it was because I'm also > > overriding the 'init' method in order to get to the request and response > > objects, as I read somewhere in the docs that I should do. Commenting out > > my overriding of init or calling super.init solved the NPE. I also read > > somewhere on the restlet website that "to intercept init, I can override > > doInit" which I didn't do because I didn't want to "intercept" anything. I > > only want to get a reference to me request and response objects. > > > > The broken pipe exception remains. The client is Chrome Version > > 27.0.1453.110 on Ubuntu, as I mentioned via an HTML tag generally > > used for videos. Here is the info that get be gather from Chrome dev tools > > for that particular request. Note that I did try setting the Content-Length > > header explicitly. > > > > Request URL:http://localhost:8182/show > > Request Method:GET > > Status Code:206 Partial Content > > Request Headersview source > > Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 > > Accept-Encoding:gzip,deflate,sdch > > Accept-Language:en-US,en;q=0.8 > > Connection:keep-alive > > Cookie:__atuvc=12%7C5%2C0%7C6%2C0%7C7%2C0%7C8%2C2%7C9; > > vctk=1e66b965-3619-403f-b22a-2281faed2977; > > user=20657493-763c-4109-805d-48de04f4317d > > Host:localhost:8182 > > If-Range:Wed, 17 Apr 2013 04:35:52 GMT > > Range:bytes=120832-120832 > > Referer:http://localhost:8182/ > > User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like > > Gecko) Chrome/27.0.1453.110 Safari/537.36 > > Response Headers > > HTTP/1.1 206 Partial Content > > Content-Length: 1 > > Content-Range: bytes 120832-120832/8973447 > > Content-Type: video/mp4 > > Last-Modified: Wed, 17 Apr 2013 04:35:52 GMT > > Date: Sat, 15 Jun 2013 17:38:56 GMT > > Accept-Ranges: bytes > > Server: Restlet-Framework/2.1.2 > > > > Final note: it took my a while to find out how to add header to an HTTP > > response. I understand that Restlet aims to be more general than HTTP, but > > one has to assume HTTP is the overwhelming majority of use cases. I would > > suggest that a call to: > > > > HttpResponse.addHeader() > > > > should lead to a NullPointerException, but rather automatically create the > > header "Series" in the response if they are not there. > > > > Thanks again! > > Boris > > > > -- > > > > http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3058179 > > -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3058275
Re: How to server a video file
Yes, Jetty or Simple connectors are recommended for production work. The internal connector is convenient during initial development phases but needs more work. Best, Jerome 2013/6/15 Borislav Iordanov > I also tried removing jetty from the picture, but then I started getting > an old friend: > > java.io.IOException: The thread blocked at the cyclic barrier has timed > out. > at > org.restlet.util.SelectionRegistration.block(SelectionRegistration.java:197) > at > org.restlet.engine.io.NbChannelInputStream.onFill(NbChannelInputStream.java:230) > at org.restlet.engine.io.Buffer.process(Buffer.java:601) > at > org.restlet.engine.io.NbChannelInputStream.read(NbChannelInputStream.java:307) > at java.io.InputStream.read(InputStream.java:101) > at org.restlet.engine.io.BioUtils.exhaust(BioUtils.java:239) > at > org.restlet.representation.Representation.exhaust(Representation.java:247) > at > org.restlet.engine.connector.ServerOutboundWay.onMessageCompleted(ServerOutboundWay.java:174) > at > org.restlet.engine.connector.HttpServerOutboundWay.onMessageCompleted(HttpServerOutboundWay.java:118) > at > org.restlet.engine.connector.OutboundWay.processIoBuffer(OutboundWay.java:468) > at org.restlet.engine.connector.Way.onSelected(Way.java:456) > at > org.restlet.util.SelectionRegistration.onSelected(SelectionRegistration.java:325) > at > org.restlet.engine.connector.Connection.onSelected(Connection.java:617) > at > org.restlet.util.SelectionRegistration.onSelected(SelectionRegistration.java:325) > at > org.restlet.engine.connector.ConnectionController.onSelected(ConnectionController.java:219) > at > org.restlet.engine.connector.ServerConnectionController.onSelected(ServerConnectionController.java:99) > at > org.restlet.engine.connector.ConnectionController.selectKeys(ConnectionController.java:308) > at > org.restlet.engine.connector.ConnectionController.doRun(ConnectionController.java:171) > at org.restlet.engine.connector.Controller.run(Controller.java:159) > at > java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) > at > java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334) > at java.util.concurrent.FutureTask.run(FutureTask.java:166) > at > java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1146) > at > java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) > at java.lang.Thread.run(Thread.java:679) > Caused by: java.util.concurrent.TimeoutException > at > java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:250) > at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:427) > at > org.restlet.util.SelectionRegistration.block(SelectionRegistration.java:191) > > > so jetty is unavoidable. > > I'd happily try to implement my own Representation, and perhaps get a > better idea of what's happening at a lower level, but with no documentation > it's not very inviting to make such an attempt. > > Thanks > Boris > > -- > > http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3058190 > -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3058207
Re: Re: How to server a video file
Hi Boris, Overriding doInit() method is easier as you don't need to make the super.init() call and in addition if anything goes wrong, the doCatch() will be invoked. Regarding the broken pipe, I'm wondering it this isn't due to the ranged request. Have you tried a straight/non-ranged HTTP call from curl or another HTTP client? The idea to prevent direct access to header is not really to be more general than HTTP, but rather to expose HTTP semantics as a Java API. This is an aspect we might reconsider, especially for extension headers. Best regards, Jerome 2013/6/15 Borislav Iordanov > Hi Jerome, > > Thanks a lot for your reply, replacing the handle() method by an > implementation of get() yielded a NullPointerException in the > ServerResource.handle implementation. It turned out it was because I'm also > overriding the 'init' method in order to get to the request and response > objects, as I read somewhere in the docs that I should do. Commenting out > my overriding of init or calling super.init solved the NPE. I also read > somewhere on the restlet website that "to intercept init, I can override > doInit" which I didn't do because I didn't want to "intercept" anything. I > only want to get a reference to me request and response objects. > > The broken pipe exception remains. The client is Chrome Version > 27.0.1453.110 on Ubuntu, as I mentioned via an HTML tag generally > used for videos. Here is the info that get be gather from Chrome dev tools > for that particular request. Note that I did try setting the Content-Length > header explicitly. > > Request URL:http://localhost:8182/show > Request Method:GET > Status Code:206 Partial Content > Request Headersview source > Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 > Accept-Encoding:gzip,deflate,sdch > Accept-Language:en-US,en;q=0.8 > Connection:keep-alive > Cookie:__atuvc=12%7C5%2C0%7C6%2C0%7C7%2C0%7C8%2C2%7C9; > vctk=1e66b965-3619-403f-b22a-2281faed2977; > user=20657493-763c-4109-805d-48de04f4317d > Host:localhost:8182 > If-Range:Wed, 17 Apr 2013 04:35:52 GMT > Range:bytes=120832-120832 > Referer:http://localhost:8182/ > User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like > Gecko) Chrome/27.0.1453.110 Safari/537.36 > Response Headers > HTTP/1.1 206 Partial Content > Content-Length: 1 > Content-Range: bytes 120832-120832/8973447 > Content-Type: video/mp4 > Last-Modified: Wed, 17 Apr 2013 04:35:52 GMT > Date: Sat, 15 Jun 2013 17:38:56 GMT > Accept-Ranges: bytes > Server: Restlet-Framework/2.1.2 > > Final note: it took my a while to find out how to add header to an HTTP > response. I understand that Restlet aims to be more general than HTTP, but > one has to assume HTTP is the overwhelming majority of use cases. I would > suggest that a call to: > > HttpResponse.addHeader() > > should lead to a NullPointerException, but rather automatically create the > header "Series" in the response if they are not there. > > Thanks again! > Boris > > -- > > http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3058179 > -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3058205
RE: How to server a video file
I also tried removing jetty from the picture, but then I started getting an old friend: java.io.IOException: The thread blocked at the cyclic barrier has timed out. at org.restlet.util.SelectionRegistration.block(SelectionRegistration.java:197) at org.restlet.engine.io.NbChannelInputStream.onFill(NbChannelInputStream.java:230) at org.restlet.engine.io.Buffer.process(Buffer.java:601) at org.restlet.engine.io.NbChannelInputStream.read(NbChannelInputStream.java:307) at java.io.InputStream.read(InputStream.java:101) at org.restlet.engine.io.BioUtils.exhaust(BioUtils.java:239) at org.restlet.representation.Representation.exhaust(Representation.java:247) at org.restlet.engine.connector.ServerOutboundWay.onMessageCompleted(ServerOutboundWay.java:174) at org.restlet.engine.connector.HttpServerOutboundWay.onMessageCompleted(HttpServerOutboundWay.java:118) at org.restlet.engine.connector.OutboundWay.processIoBuffer(OutboundWay.java:468) at org.restlet.engine.connector.Way.onSelected(Way.java:456) at org.restlet.util.SelectionRegistration.onSelected(SelectionRegistration.java:325) at org.restlet.engine.connector.Connection.onSelected(Connection.java:617) at org.restlet.util.SelectionRegistration.onSelected(SelectionRegistration.java:325) at org.restlet.engine.connector.ConnectionController.onSelected(ConnectionController.java:219) at org.restlet.engine.connector.ServerConnectionController.onSelected(ServerConnectionController.java:99) at org.restlet.engine.connector.ConnectionController.selectKeys(ConnectionController.java:308) at org.restlet.engine.connector.ConnectionController.doRun(ConnectionController.java:171) at org.restlet.engine.connector.Controller.run(Controller.java:159) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334) at java.util.concurrent.FutureTask.run(FutureTask.java:166) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1146) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:679) Caused by: java.util.concurrent.TimeoutException at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:250) at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:427) at org.restlet.util.SelectionRegistration.block(SelectionRegistration.java:191) so jetty is unavoidable. I'd happily try to implement my own Representation, and perhaps get a better idea of what's happening at a lower level, but with no documentation it's not very inviting to make such an attempt. Thanks Boris -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3058190
RE: Re: How to server a video file
Hi Jerome, Thanks a lot for your reply, replacing the handle() method by an implementation of get() yielded a NullPointerException in the ServerResource.handle implementation. It turned out it was because I'm also overriding the 'init' method in order to get to the request and response objects, as I read somewhere in the docs that I should do. Commenting out my overriding of init or calling super.init solved the NPE. I also read somewhere on the restlet website that "to intercept init, I can override doInit" which I didn't do because I didn't want to "intercept" anything. I only want to get a reference to me request and response objects. The broken pipe exception remains. The client is Chrome Version 27.0.1453.110 on Ubuntu, as I mentioned via an HTML tag generally used for videos. Here is the info that get be gather from Chrome dev tools for that particular request. Note that I did try setting the Content-Length header explicitly. Request URL:http://localhost:8182/show Request Method:GET Status Code:206 Partial Content Request Headersview source Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Encoding:gzip,deflate,sdch Accept-Language:en-US,en;q=0.8 Connection:keep-alive Cookie:__atuvc=12%7C5%2C0%7C6%2C0%7C7%2C0%7C8%2C2%7C9; vctk=1e66b965-3619-403f-b22a-2281faed2977; user=20657493-763c-4109-805d-48de04f4317d Host:localhost:8182 If-Range:Wed, 17 Apr 2013 04:35:52 GMT Range:bytes=120832-120832 Referer:http://localhost:8182/ User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36 Response Headers HTTP/1.1 206 Partial Content Content-Length: 1 Content-Range: bytes 120832-120832/8973447 Content-Type: video/mp4 Last-Modified: Wed, 17 Apr 2013 04:35:52 GMT Date: Sat, 15 Jun 2013 17:38:56 GMT Accept-Ranges: bytes Server: Restlet-Framework/2.1.2 Final note: it took my a while to find out how to add header to an HTTP response. I understand that Restlet aims to be more general than HTTP, but one has to assume HTTP is the overwhelming majority of use cases. I would suggest that a call to: HttpResponse.addHeader() should lead to a NullPointerException, but rather automatically create the header "Series" in the response if they are not there. Thanks again! Boris -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3058179
Re: How to server a video file
Hi Boris, You should override the get():Representation method instead of hanle(), or use an @Get annotation on a method returning a FileRepresentation. This way the response entity will automatically be set. The handle() method is the main entry point for objects calling a ServerResource, it does many things such as method dispatching, conditional processing or content negotiation. I've added a Javadoc comment to help clarify. In term of doc, you can check this first application tutorial for guidance: http://restlet.org/learn/guide/2.1/introduction/first-steps/first-application Regarding your exception, it looks like an issue on the client side. What are you using there? Best regards, Jerome -- http://restlet.org http://twitter.com/#!/jlouvel 2013/6/15 Borislav Iordanov > Hi, > > I'm using 2.1.2 with the Jetty HTTP connector. I'd appreciate any pointers > on the following issue. > > I tried serving a video file to a browser that loads with an src='...'> tag by creating a ServerResource implementing the handle() > method and returning a FileRepresentation of my video: > > public Representation handle() > { >return new FileRepresentation(new File(...), MediaType.VIDEO_MP4); > } > > that didn't work. It turned out I had to set the representation as the > response entity: > > > public Representation handle() > { >Representation r = new FileRepresentation(new File(...), > MediaType.VIDEO_MP4); > response.setEntity(r); >return r; > } > > But the gives my the following exception: > > The connection was broken. It was probably closed by the client. > > org.eclipse.jetty.io.EofException > at > org.eclipse.jetty.http.HttpGenerator.flushBuffer(HttpGenerator.java:952) > at > org.eclipse.jetty.http.AbstractGenerator.blockForOutput(AbstractGenerator.java:518) > at org.eclipse.jetty.server.HttpOutput.write(HttpOutput.java:182) > at org.eclipse.jetty.server.HttpOutput.write(HttpOutput.java:101) > at org.restlet.engine.io.BioUtils.copy(BioUtils.java:82) > at > org.restlet.representation.FileRepresentation.write(FileRepresentation.java:271) > at > org.restlet.engine.adapter.ServerCall.writeResponseBody(ServerCall.java:510) > at > org.restlet.engine.adapter.ServerCall.sendResponse(ServerCall.java:454) > at > org.restlet.ext.jetty.internal.JettyCall.sendResponse(JettyCall.java:312) > > > caused by: > > Caused by: java.io.IOException: Connection reset by peer > at sun.nio.ch.FileDispatcher.write0(Native Method) > at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:47) > at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:122) > at sun.nio.ch.IOUtil.write(IOUtil.java:93) > at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:352) > at > org.eclipse.jetty.io.nio.ChannelEndPoint.flush(ChannelEndPoint.java:305) > at > org.eclipse.jetty.io.nio.SelectChannelEndPoint.flush(SelectChannelEndPoint.java:356) > at > org.eclipse.jetty.http.HttpGenerator.flushBuffer(HttpGenerator.java:891) > ... 22 more > > I trying googling for examples and I couldn't find any documentation about > how to create ServerResources and what the rules are for implementation the > Representation interface. It's pretty much trial and error and shooting in > the dark, so any hint will probably help. > > Regards, > Boris > > -- > > http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3058146 > -- http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=3058166