Flash-Apache conflict: error 416?

Flash-Apache conflict: error 416?

Post by Daniel Grisco » Fri, 27 Jun 2003 12:31:28



I'm developing a Macromedia Flash-based product which runs on a Pocket
PC (a Dell Axim X5). At one point in the startup procedure, the product
loads a new Flash file from an Apache server (2.0.44 running on OS X
10.2.6). Problem: the load fails every other time time with a 416
response code ("Requested Range Not Satisfiable").

Using Ethereral (cool program!) on the server, I grabbed the relevant
packets. First, a successful transaction. Flash's request:

Quote:> GET /flash/main.swf HTTP/1.1\r\n
> Referer: http://server/flash/main.swf\r\n
> User-Agent: Shockwave Flash\r\n
> Host: server\r\n
> \r\n

Apache's response:

Quote:> HTTP/1.1 200 OK\r\n
> Date: Thu, 26 Jun 2003 02:34:44 GMT\r\n
> Server: Apache/2.0.44 (Unix) DAV/2 PHP/4.3.1\r\n
> Last-Modified: Mon, 23 Jun 2003 13:51:51 GMT\r\n
> ETag: "11f8ea-b94-c6c42bc0"\r\n
> Accept-Ranges: bytes\r\n
> Content-Length: 2964\r\n
> Content-Type: application/x-shockwave-flash\r\n
> \r\n

Now, a failed transaction. Flash's request:

Quote:> GET /flash/main.swf HTTP/1.1\r\n
> Referer: http://server/flash/main.swf\r\n
> Range: bytes=2964-\r\n
> Unless-Modified-Since: Mon, 23 Jun 2003 13:51:51 GMT\r\n
> If-Range: "11f8ea-b94-c6c42bc0"\r\n
> User-Agent: Shockwave Flash\r\n
> Host: server\r\n
> \r\n

Apache's response:

Quote:> HTTP/1.1 416 Requested Range Not Satisfiable\r\n
> Date: Thu, 26 Jun 2003 02:35:19 GMT\r\n
> Server: Apache/2.0.44 (Unix) DAV/2 PHP/4.3.1\r\n
> Transfer-Encoding: chunked\r\n
> Content-Type: text/html; charset=iso-8859-1\r\n
> \r\n
> Data (414 bytes)

(Note that this is on an isolated network, with "server" hardwired to
the server's IP address.)

I'm on the hairy edge of my expertise, but it seems that the Flash
program is requesting bytes 2964 and on of a 2964-byte file, and Apache
is objecting because the final byte number is 2963. Watching the log,
the failures and successes exactly alternate. What I'd like is for Flash
to request the file, and Apache to respond with (I think) a code 304
("Use your Cached Copy, Dude").

To keep the code 416 from happening, it seems I either have to persuade
Flash to stop getting funky with its request, or persuade Apache to be
more tolerant. Using the first approach, I added a "?randomVar=XXXXX"
suffix to each request to make Flash see each fetch as a new item. This
worked, except that Flash dutifully started caching all these
"different" files, ending with megabytes of useless cached files, which
is a memory and performance problem on a poor little palmtop. So, now
I'm stumped.

Any ideas?

Many thanks,
Dan

--
Daniel T. Griscom           Work:  (781) 665-0053
Suitable Systems            Fax:   (781) 665-7106

Melrose, MA 02176-1433      http://www.suitable.com/

 
 
 

Flash-Apache conflict: error 416?

Post by Joachim Ri » Sat, 28 Jun 2003 08:18:13


Quote:> I'm on the hairy edge of my expertise, but it seems that the Flash
> program is requesting bytes 2964 and on of a 2964-byte file, and Apache
> is objecting because the final byte number is 2963.

indeed

Quote:> Watching the log,
> the failures and successes exactly alternate. What I'd like is for Flash
> to request the file, and Apache to respond with (I think) a code 304
> ("Use your Cached Copy, Dude").

i think for this behaviour to occur the flash plugin needs to be
fixed, as it is the one behaving erratically.

Quote:> To keep the code 416 from happening, it seems I either have to persuade
> Flash to stop getting funky with its request, or persuade Apache to be
> more tolerant. Using the first approach, I added a "?randomVar=XXXXX"
> suffix to each request to make Flash see each fetch as a new item. This
> worked, except that Flash dutifully started caching all these
> "different" files, ending with megabytes of useless cached files, which
> is a memory and performance problem on a poor little palmtop. So, now
> I'm stumped.

send a Cache-Control: no-cache header with each of the randomized
requests, if you can bear the bandwidth hit.

or better still for everybody except your nerves, complain to
macromedia until they fix it.

joachim

 
 
 

Flash-Apache conflict: error 416?

Post by Daniel Grisco » Sat, 28 Jun 2003 10:48:24




Quote:> i think for this behaviour to occur the flash plugin needs to be
> fixed, as it is the one behaving erratically.

So you think it's Flash which is misbehaving. Good to know.

Quote:> > To keep the code 416 from happening, it seems I either have to persuade
> > Flash to stop getting funky with its request, or persuade Apache to be
> > more tolerant. Using the first approach, I added a "?randomVar=XXXXX"
> > suffix to each request to make Flash see each fetch as a new item. This
> > worked, except that Flash dutifully started caching all these
> > "different" files, ending with megabytes of useless cached files, which
> > is a memory and performance problem on a poor little palmtop. So, now
> > I'm stumped.

> send a Cache-Control: no-cache header with each of the randomized
> requests, if you can bear the bandwidth hit.

So, I'd use "Header add Cache-Control: no-cache" in the relevant
location of my conf file, right?

As an alternative, is there any way I could rewrite the offending
request? Remember that it is this:

Quote:> GET /flash/main.swf HTTP/1.1\r\n
> Referer: http://server/flash/main.swf\r\n
> Range: bytes=2964-\r\n
> Unless-Modified-Since: Mon, 23 Jun 2003 13:51:51 GMT\r\n
> If-Range: "11f8ea-b94-c6c42bc0"\r\n
> User-Agent: Shockwave Flash\r\n
> Host: server\r\n
> \r\n

I believe I'd need to do the following:
- Delete the "Range:" header
- Delete the "If-Range:" header
- Change the "Unless-Modified-Since" header to an "If-Modified-Since"
header, with the same date.

The first two can be done using "RequestHeader unset": is there a way to
do the third? (This, of course, assumes Flash will know what to do if it
gets a 304 response.)

Quote:> or better still for everybody except your nerves, complain to
> macromedia until they fix it.

In my decade of working with Macromedia, I've found that their tech
support department goes into turbo-denial mode whenever someone suggests
that their software might have a bug. For an example, go to
groups.google.com and search for "Shockwave 8.5 installers won't upgrade
older Flash under Win98 SE". (I'll give them a shot anyway.)

Many thanks,
Dan

--
Daniel T. Griscom           Work:  (781) 665-0053
Suitable Systems            Fax:   (781) 665-7106

Melrose, MA 02176-1433      http://www.suitable.com/

 
 
 

Flash-Apache conflict: error 416?

Post by Daniel Grisco » Sun, 29 Jun 2003 07:34:27


I've worked around my problem. To recap, when the Standalone Pocket
PC Flash Player executes a loadMovie() for a file it has loaded before,
it includes bogus Range, Unless-Modified-Since and If-Range headers in
the request. Again, here's the bogus request:

Quote:> GET /flash/main.swf HTTP/1.1\r\n
> Referer: http://server/flash/main.swf\r\n
> Range: bytes=2964-\r\n
> Unless-Modified-Since: Mon, 23 Jun 2003 13:51:51 GMT\r\n
> If-Range: "11f8ea-b94-c6c42bc0"\r\n
> User-Agent: Shockwave Flash\r\n
> Host: server\r\n
> \r\n

Properly-configured web servers respond to this with a 416 code
("Requested Range Not Satisfiable"), which aborts the load of the movie.
This is a Flash bug: it should not ask for a range when requesting the
movie. (Some web servers respond by sending the requested movie anyway;
although this dodges the Flash bug it isn't the correct behavior).

My server is Apache version 2.0.44. To work around the problem, I added
the following lines to a .htaccess file in the directory holding the
Flash files:

RequestHeader unset Range
RequestHeader unset If-Range
RequestHeader unset Unless-Modified-Since

This deletes the three offending headers before Apache can try to
process them. Apache then sends the movie back to Flash, and everyone's
happy. The only problem is that this disables all caching of movies, so
that every time my application asks for a movie it will have to come
over the network again. Slower, but far better than being unreliable. (I
considered rewriting the Unless-Modified-Since header into an
If-Modified-Since header using mod-perl, but the logistics of this
ballooned into impracticality.)

Thanks for the help,
Dan

--
Daniel T. Griscom           Work:  (781) 665-0053
Suitable Systems            Fax:   (781) 665-7106

Melrose, MA 02176-1433      http://www.suitable.com/

 
 
 

Flash-Apache conflict: error 416?

Post by Joachim Ri » Sun, 29 Jun 2003 08:08:17


Quote:> > send a Cache-Control: no-cache header with each of the randomized
> > requests, if you can bear the bandwidth hit.

> So, I'd use "Header add Cache-Control: no-cache" in the relevant
> location of my conf file, right?

yes.

Quote:> As an alternative, is there any way I could rewrite the offending
> request? Remember that it is this:

> > GET /flash/main.swf HTTP/1.1\r\n
> > Referer: http://server/flash/main.swf\r\n
> > Range: bytes=2964-\r\n
> > Unless-Modified-Since: Mon, 23 Jun 2003 13:51:51 GMT\r\n
> > If-Range: "11f8ea-b94-c6c42bc0"\r\n
> > User-Agent: Shockwave Flash\r\n
> > Host: server\r\n
> > \r\n

> I believe I'd need to do the following:
> - Delete the "Range:" header
> - Delete the "If-Range:" header
> - Change the "Unless-Modified-Since" header to an "If-Modified-Since"
> header, with the same date.

> The first two can be done using "RequestHeader unset":

i see another reason to look deeper into apache2 - mod_headers has
been imprved a lot...

Quote:> is there a way to
> do the third? (This, of course, assumes Flash will know what to do if it
> gets a 304 response.)

not without using some advanced magic not allowed for firstgraders:
you could use mod_perl to implement an input connection filter to
change the header. see

http://perl.apache.org/docs/2.0/user/handlers/filters.html#Connection...

for an example which will likely do what you want when you change the
line

if ($data and $data =~ s|^GET|HEAD|) {

into

if ($data and $data =~ s|^Unless-Modified-Since:|If-Modified-Since:|)
{

beware though, that i have not tested this (yet) - my fingers are
itching but it is late over here in .de...

but i will sometime soon, i'm shure - it seems very cool.

joachim

 
 
 

Flash-Apache conflict: error 416?

Post by Daniel Grisc » Sun, 29 Jun 2003 22:45:46



> not without using some advanced magic not allowed for firstgraders:

ouch

Quote:> you could use mod_perl to implement an input connection filter to
> change the header.

I've been looking into mod_perl, and the installation process alone
(at least on my OS X machine) is pretty protracted, with lots of
places things could go wrong in perhaps subtle ways. Given our tight
schedule, complex and/or subtle problems is not what I need right now.
So, I'll use the RequestHeader unset solution for our initial launch,
and once we've got things up and running reliably (although perhaps
slowly) I'll revisit the decision.

Many thanks,
Dan

 
 
 

1. apache bug: HTTP 416 errors can cause client hang

Greetings,

I've found that under certain conditions, Apache's 416 error response
("Requested Range Not Satisfiable") will return a non-0 Content-Length
header, followed by no  content, causing clients to hang.  A more
detailed description of the problem, and  a patch to fix it, are
below.

BTW, I also submitted this to apache's bug database (PR 8549) 4 weeks
ago, but got no reply of any kind, so I thought I'd try posting here
instead.

When a client sends a partial-content request (i.e. resumed download),
but requests a byte-range beyond what exists, Apache returns a 416
(Requested Range Not Satisfyable) as of 1.3.15.  However, the
Content-Length of the response is set to the (complete) size of
the requested entity body, followed by no entity body - causing
the client to hang waiting for a body that never comes.

This trace shows the problem (the "/" document on the test server
is 4592 bytes long):

% telnet localhost 80
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET / HTTP/1.1
Host: build
Range: bytes=100000-

HTTP/1.1 416 Requested Range Not Satisfiable
Date: Tue, 16 Oct 2001 07:34:21 GMT
Server: Apache/1.3.19 (Unix)  (Red-Hat/Linux) mod_ssl/2.8.1
OpenSSL/0.9.6 DAV/1.0.2 PHP/4.0.4pl1 mod_perl/1.24_01
Last-Modified: Mon, 15 Oct 2001 21:44:58 GMT
ETag: "259f2b-11f0-3bcb58da"
Accept-Ranges: bytes
Content-Length: 4592
Content-Range: bytes */4592
Content-Type: text/html

<no body returned>

Note that the server returns a "Content-Length: 4592" header,
followed by no content.

Section 10.4.17 of RFC2616 says "When [the 416] status code is
returned for a byte-range request, the response SHOULD include
a Content-Range entity-header field specifying the current length
of the selected resource."  So, the Content-Range header generated
by apache (which also indicates 4592 bytes are available) is
correct; the Content-Length header, however, causes clients to
hang as they wait for an entity body that never comes.

The trace shown above works repeatably for 1.3.19+ servers when
nonexistant byte ranges are requested

This seems to fix it:

--- http_core.c.orig    Tue Oct 16 00:54:57 2001

        rangestatus = ap_set_byterange(r);

+       if (r->header_only)
+           ap_set_content_length(r, 0);
+
        ap_send_http_header(r);


        }

        rangestatus = ap_set_byterange(r);
+
+       if (r->header_only)
+           ap_set_content_length(r, 0);
+
        ap_send_http_header(r);

        if (!r->header_only) {

2. How do I make file creation time same as shown by 'date' command

3. 416 errors in apache 2

4. XFree86 & ATI

5. HELP, Linux BBS's in 416/905 area code!

6. Block Size of SCSI DDS-2 Tape Drive

7. Linux-Activists Digest #416

8. x11amp won't work but xplaycd will after bios flash, HELP!

9. Linux in 416/905

10. APACHE Error: "Signaling Error: error already pending"

11. Flash ROM Driver / Flash File System

12. ****Flashing Screen*****Flashing Screen******

13. IDE Booting from Flash - Positive report: Adton PCMCIA Card Drive - PCMCIA vs. Compact Flash