Re: HTBlackHole problem & dealing with stream return codes in HTTee

Hi Maciej,
... good stuff deleted ...

> In a simple WWW browser I have written using the WWWLib the user clicks on the
> link (anchor) leading to the ZIP file. After a while, the beautiful dialog box appears
> prompting for the file name (the ZIP files are not presented to the user, they are saved 
> to the disk instead). The user enters the name and clicks OK, and then watches
> the "Reading (2% of 3.8M)" messages for a while (sometimes a long one). After 
> that the file is saved on the local disk. That's perfectly OK, but what happens if the 
> user clicks Cancel button in the dialog box? The file is not saved to the disk, but the 
> message "Reading (2% of 3.8M)" still appears and changes slowly from 1% to 100%.
> This really can lead to a deep confusion...
> Why's that? The library creates a stream stack to deal with the transmitted data body
> after parsing the MIME headers. In our example, the body is in the ZIP format, so the
> library decides that it should be saved to the disk (see HTConverterInit() in HTInit.c).
> It constructs then a HTSaveLocally stream using HTSaveLocally() function 
> (HTFWrite.c). This function prompts the user for a file name (via HTAlert). If it gets
> NULL (which means an error, e.g. click on Cancel button), the HTBlackHole is returned
> to the HTSaveLocally() caller. And instead of cancelling the connection, the data keeps 
> flowing from the network and getting to the HTBlackHole, where it's discarded. 
> Hmmm...

Ha! Very nice description! Yep this is not too smart! 
> The easiest solution is to change the result codes returned in 
> HTBlackHole_put_character, HTBlackHole_put_string and HTBlackHole_write
> from HT_OK to HT_ERROR. This immediately stops receiving the data. There is
> however one VERY serious drawback. If the HTBlackHole is the main output stream,
> everything is all right, but what if not? What if HTBlackHole is used in place of some
> stream of a secondary importance (cache for example), attached to the main stream
> with a HTTee? Here we meet the problem we were discussing a few days ago: how
> the stream return codes should propagate in HTTee? (To Henrik: sorry I haven't
> answered your last letter until now, but I had to think about the problem).

Sorry for not answering _this_ mail before :-) I really would like to let 
HTBlackHole return HT_OK as it is a "neutral" return value that normally 
doesn't cause any reaction from the upstream modules. If the user has pushed 
"cancel" then there is really no more reason for continuing downloading the 
file (unless it goes in to some sort of shared cache). The stream prompting 
the user (HTSaveLocally) can therefore kill the request directly. This should 
work even if the instance of the HTSaveLocally stream is in fact a part of the 
request (however, testing it would be a good idea!). As the creation method 
for the HTSaveLocally gets passed the request object, it can immidiately call 
the HTRequest_kill() and then just exict when this call returns.

> > We can either say that this is a problem with a T stream or change the status 
> > code numbers and use bitflags instead. Error codes can still be negative by 
> > haing the MSB set to 1. This way you can easily check for error/success _and_ 
> > at the same time return multiple return codes. Does anybody see a problem with 
> > this except that you need to use binary operations on the return values?
> Here's the problem: bitflags won't allow you to indicate the importance of each return
> code.

But the upstream module can then check for both codes and then decide what to 
do... The important thing is that both codes (or in general all codes in case 
of multiple T streams) get proagated upstream.

> My proposition:
> 1. The HTBlackHole should return some special code, e.g. HT_STOP_BLACKHOLE.
> This would cause the whole engine to stop, but would not propagate in HTTee (unless
> two streams return this).
> 2. Who knows what the importance of a stream is? The function which created it,
> of course. So, the function which creates HTTee and then attaches two streams
> to it should pass HTTee a special callback function as a parameter. This callback 
> function would be used for resolving the stream return codes conflicts. To ease 
> programming, HTTee should have a default resolving function, something similar to 
> merge_results in Hakon's version.

Not a bad idea. The resolving function could also be a direct part of the 
upstream module which will be activated each time the T stream returns. As I 
see it, both ways will do, but maybe a callback function is a more flexibel 

Thanks for the feedback!


Henrik Frystyk Nielsen, <frystyk@w3.org>
World-Wide Web Consortium, MIT/LCS NE43-356
545 Technology Square, Cambridge MA 02139, USA