Roku Developer Program

Join our online forum to talk to Roku developers and fellow channel creators. Ask questions, share tips with the community, and find helpful resources.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
retrotom
Visitor

Is "Transfer-Encoding: chunked" supported?

Hey,

We've noticed that when attempting to send the Roku a file/stream that we don't know the size of beforehand -- it keeps attempting to download the file over and over again. We've been attempting to use the chunked transfer-encoding. But what we see is an infinite loop -- the box keeps trying to download the file over and over again. The entire file will play, the stream will end, the connection will close, and then the box downloads the file again. As the Roku responds with HTTP/1.1 - it should support chunked encoding. Is this a bug? Or are we doing something wrong?

Thanks,
RT
0 Kudos
17 REPLIES 17
TheEndless
Channel Surfer

Re: Is "Transfer-Encoding: chunked" supported?

"retrotom" wrote:
Hey,

We've noticed that when attempting to send the Roku a file/stream that we don't know the size of beforehand -- it keeps attempting to download the file over and over again. We've been attempting to use the chunked transfer-encoding. But what we see is an infinite loop -- the box keeps trying to download the file over and over again. The entire file will play, the stream will end, the connection will close, and then the box downloads the file again. As the Roku responds with HTTP/1.1 - it should support chunked encoding. Is this a bug? Or are we doing something wrong?

Thanks,
RT

If you're using the roVideoPlayer, and not the roVideoScreen, do you have SetLoop() set to true, by any chance? If so, it's going to loop the content after it completes each time. Also, there's an IsFullResult() event that you should be able to act on to stop playback after the current video finishes, if it's not a SetLoop() issue.
My Channels: http://roku.permanence.com - Twitter: @TheEndlessDev
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
0 Kudos
retrotom
Visitor

Re: Is "Transfer-Encoding: chunked" supported?

"TheEndless" wrote:

If you're using the roVideoPlayer, and not the roVideoScreen, do you have SetLoop() set to true, by any chance? If so, it's going to loop the content after it completes each time. Also, there's an IsFullResult() event that you should be able to act on to stop playback after the current video finishes, if it's not a SetLoop() issue.



Actually, I'm experiencing this with the roAudioPlayer component. Looping is not on. We are looping similar to the way the audio player example/sample does -- that is, over a list of files. It's a very strange behavior we're seeing. For instance, if I provide a list of MP3s that are "ready to go" and send those without chunking -- everything works fine. If there's an error in retrieving one of the streams (chunked or not) -- the player still loops through each file. But if I provide it a chunked download, then it loops over and over on the same file. It's weird; requests for the same file over and over. I haven't tried using roAudioPlayer's "isFullResult()" though -- so you might be on to something. I will let you know. Thanks for the suggestion.

Thanks,
RT
0 Kudos
RokuKevin
Visitor

Re: Is "Transfer-Encoding: chunked" supported?

The Roku Streaming Player requires that your http server supports range requests. Both Apache and IIS support range requests.

The behavior of a download loop, sounds like a web server that claims http 1.1 support but does not actually support range requests...

--Kevin
0 Kudos
retrotom
Visitor

Re: Is "Transfer-Encoding: chunked" supported?

"RokuKevin" wrote:
The Roku Streaming Player requires that your http server supports range requests. Both Apache and IIS support range requests.

The behavior of a download loop, sounds like a web server that claims http 1.1 support but does not actually support range requests...

--Kevin


Kevin,

I will need to check that assertion out. My web server does support range requests though. I can serve up MP4s, etc. to multiple clients that use range request headers. I will need to actually set a breakpoint to see if that's what's happening. I'm pretty sure it's not though -- I thought I saw it re-requesting the entire file. But the range request mention does bring up and interesting thing I've noticed about the way the software handles MP4 playback (muddying the topic a bit here). It appears as if it sends a request for the file just to get it's length, and then open ended byte range requests for other data. So my issue/concerns/questions are:

1. Why not use HEAD request to get the size of the file? Cancelling the request causes an exception (in my server) which needs to be handled and may hurt overall performance.
2. Why not specify the full range when sending byte requests? If I playback the file via Chrome or pretty much any other "smart" web client, they use "bytes start-end". The Roku will ask for "bytes start-" and then close the connection while my server is still responding. According to the spec (I think), leaving it open means you're requesting from that position to the end of the file. Once again, this causes an exception because of the socket/connection being closed prematurely (in my server) which needs to be handled and may hurt overall performance. Speaking specifically about Chrome -- it will request the first kilobyte (presumably to read ftype and find out how big mdat is) and then jumps to moov and downloads whatever it needs.

Not trying to be a pain or complain -- I'm just wondering if you've heard this feedback before. And if so, is there a reason it works the way it does.

EDIT: You know, I realized I might be wrong about point #1. Is the Roku basically doing the same thing as Chrome? That is, in the first request are you reading ftype and mdat so that you can get to moov? If so, then a range end would still be a "nice to have".

Thanks,
RT
0 Kudos
retrotom
Visitor

Re: Is "Transfer-Encoding: chunked" supported?

"RokuKevin" wrote:
The Roku Streaming Player requires that your http server supports range requests. Both Apache and IIS support range requests.

The behavior of a download loop, sounds like a web server that claims http 1.1 support but does not actually support range requests...

--Kevin


OK, I was able to track down the issue here. Thanks for the input Kevin. Turns out the Roku was asking for an "invalid" range and I needed to return a 416 status. My server's range code was attempting to return a zero length byte range. Looking at the spec, it's actually kind of ambiguous to me. Say we're dealing with a file that's 1024 bytes long and you request "bytes 1023-". Well the spec says:

If the last-byte-pos value is absent, or if the value is greater than or equal to the current length of the entity-body, last-byte-pos is taken to be equal to one less than the current length of the entity- body in bytes


I interpret that to mean the request is really "bytes 1023-1023". OK -- so does that mean you want one byte or zero bytes? If you read the following -- it makes me feel that the Roku is asking for a single byte.

The first-byte-pos value in a byte-range-spec gives the byte-offset of the first byte in a range. The last-byte-pos value gives the byte-offset of the last byte in the range; that is, the byte positions specified are inclusive


Anyways...regardless of meaning -- they both passed my mental muster as being "valid" ranges. So would it make more sense for the Roku to actually ask for "bytes 1024-"? It seems to me that the start offset of the request is off by one anyways -- unless you're throwing the first read byte out. Requesting "1+last read byte" would generate the 416 in my code -- but the 1023 is a valid offset. Hope I made sense.

Thanks again,
RT
0 Kudos
kbenson
Visitor

Re: Is "Transfer-Encoding: chunked" supported?

"retrotom" wrote:

If the last-byte-pos value is absent, or if the value is greater than or equal to the current length of the entity-body, last-byte-pos is taken to be equal to one less than the current length of the entity- body in bytes


I interpret that to mean the request is really "bytes 1023-1023". OK -- so does that mean you want one byte or zero bytes? If you read the following -- it makes me feel that the Roku is asking for a single byte.


I would interpret that as a single byte at offset 1023. I would expect 1023-1024 to be two bytes, at offsets 1023 and 1024. I'm not sure that's what they mean, but that is how I would interpret that, similarly to how I would interpret a memory address range.

Is there a reference implementation to refer to?
-- GandK Labs
Check out Reversi! in the channel store!
0 Kudos
RokuMarkn
Visitor

Re: Is "Transfer-Encoding: chunked" supported?

If a file contains 1024 bytes, the request range "1023-" and "1023-1023" both request one byte, the last byte of the file. Range "1024-" is out of range and should return a 416 status. No range request should return status 200 with an empty body, it should return 416 if there are no bytes to return.

--Mark
0 Kudos
retrotom
Visitor

Re: Is "Transfer-Encoding: chunked" supported?

"RokuMarkn" wrote:
If a file contains 1024 bytes, the request range "1023-" and "1023-1023" both request one byte, the last byte of the file. Range "1024-" is out of range and should return a 416 status. No range request should return status 200 with an empty body, it should return 416 if there are no bytes to return.

--Mark


I agree with you Mark. I hope you understood what I was trying to say. It seems to me that I was getting range requests for valid ranges. The only way it would be invalid would be if a) it asked for zero bytes (which you can't do because the spec says the range is inclusive at both ends) or b) you asked for a start byte outside of the range. When I transfer with chunked encoding (that's with no content-length header specified and \r\n with each chunk, etc.), the Roku will ask for a byte range with the start position equal to the last byte it received. Well, that's one byte -- and it's a valid request. It never triggers my 416 is what I'm saying. Right now I have a "hack" in place for when start == end of file/stream -- just send a 416. It might be too much of stretch, but would it be possible for you to try to replicate what I'm talking about? To be clear, here's an example case on a 1024 byte file, I will transfer all 1024 bytes via chunked encoding. Then I receive a second request for "bytes 1023-".

Thanks,
RT
0 Kudos
RokuMarkn
Visitor

Re: Is "Transfer-Encoding: chunked" supported?

I don't have an easy way to set up a server to use chunked encoding (which isn't used too much any more). If you can send me a URL on a server that exhibits the problem, I'll take a look at it.

--Mark
0 Kudos