Re: Overlap between StreamReader and FileReader

On Wed, Oct 23, 2013 at 11:42 PM, Aymeric Vitte <vitteaymeric@gmail.com>wrote:

>  Your filter idea seems to be equivalent to a createStream that I
> suggested some time ago (like node), what about:
>
> var encryptionPromise = crypto.subtle.encrypt(aesAlgorithmEncrypt, aesKey,
> sourceStream).createStream();
>
> So you don't need to modify the APIs where you can not specify the
> responseType.
>
> I was thinking to add stop/resume and pause/unpause:
>
> - stop: insert eof in the stream
>

close() does this.


>  Example : finalize the hash when eof is received
>
> - resume: restart from where the stream stopped
> Example : restart the hash from the state the operation was before
> receiving eof (related to Issue22 in WebCrypto that was closed without any
> solution, might imply to clone the state of the operation)
>
>
Should it really be a part of Streams API? How about just making the filter
(not Stream itself) returned by WebCrypto reusable and add some method to
recycle it?


> - pause: pause the stream, do not send eof
>
>
Sorry, what will be paused? Output?


>  - unpause: restart the stream
>
> And flow control should be back and explicit, not sure right now how to
> define it but I think it's impossible for a js app to do a precise flow
> control, and for existing APIs like WebSockets it's not easy to control the
> flow and avoid in some situations to overload the UA.
>
> Regards,
>
> Aymeric
>
> Le 21/10/2013 13:14, Takeshi Yoshino a écrit :
>
>  Sorry for blank of ~2 weeks.
>
>  On Fri, Oct 4, 2013 at 5:57 PM, Aymeric Vitte <vitteaymeric@gmail.com>wrote:
>
>>  I am still not very familiar with promises, but if I take your
>> preceeding example:
>>
>>
>> var sourceStream = xhr.response;
>> var resultStream = new Stream();
>> var fileWritingPromise = fileWriter.write(resultStream);
>> var encryptionPromise = crypto.subtle.encrypt(aesAlgorithmEncrypt,
>> aesKey, sourceStream, resultStream);
>>  Promise.all(fileWritingPromise, encryptionPromise).then(
>>   ...
>> );
>>
>
>  I made a mistake. The argument of Promise.all should be an Array. So,
> [fileWritingPromise, encryptionPromise].
>
>
>>
>>
>>  shoud'nt it be more something like:
>>
>> var sourceStream = xhr.response;
>> var encryptionPromise = crypto.subtle.encrypt(aesAlgorithmEncrypt,
>> aesKey);
>> var resultStream=sourceStream.pipe(encryptionPromise);
>> var fileWritingPromise = fileWriter.write(resultStream);
>>  Promise.all(fileWritingPromise, encryptionPromise).then(
>>   ...
>> );
>>
>
>  Promises just tell the user completion of each operation with some value
> indicating the result of the operation. It's not destination of data.
>
>  Do you think it's good to create objects representing each encrypt
> operation? So, some objects called "filter" is introduced and the code
> would be like:
>
>  var pipeToFilterPromise;
>
>  var encryptionFilter;
>  var fileWriter;
>
>  xhr.onreadystatechange = function() {
>   ...
>   } else if (this.readyState == this.LOADING) {
>      if (this.status != 200) {
>       ...
>     }
>
>      var sourceStream = xhr.response;
>
>      encryptionFilter =
> crypto.subtle.createEncryptionFilter(aesAlgorithmEncrypt, aesKey);
>     // Starts the filter.
>     var encryptionPromise = encryptionFilter.encrypt();
>     // Also starts pouring data but separately from promise creation.
>      pipeToFilterPromise = sourceStream.pipe(encryptionFilter);
>
>      fileWriter = ...;
>     // encryptionFilter works as data producer for FileWriter.
>     var fileWritingPromise = fileWriter.write(encryptionFilter);
>
>      // Set only handler for rejection now.
>      pipeToFilterPromise.catch(
>        function(result) {
>         xhr.abort();
>         encryptionFilter.abort();
>          fileWriter.abort();
>       }
>      );
>
>      encryptionPromise.catch(
>        function(result) {
>          xhr.abort();
>          fileWriter.abort();
>       }
>      );
>
>      fileWritingPromise.catch(
>        function(result) {
>          xhr.abort();
>          encryptionFilter.abort();
>       }
>      );
>
>       // As encryptionFilter will be (successfully) closed only
>      // when XMLHttpRequest and pipe() are both successful.
>     // So, it's ok to set handler for fulfillment now.
>      Promise.all([encryptionPromise, fileWritingPromise]).then(
>        function(result) {
>         // Done everything successfully!
>         // We come here only when encryptionFilter is close()-ed.
>         fileWriter.close();
>         processFile();
>       }
>     );
>   } else if (this.readyState == this.DONE) {
>      if (this.status != 200) {
>       encryptionFilter.abort();
>       fileWriter.abort();
>     } else {
>       // Now we know that XHR was successful.
>       // Let's close() the filter to finish encryption
>       // successfully.
>       pipeToFilterPromise.then(
>         function(result) {
>           // XMLHttpRequest closes sourceStream but pipe()
>           // resolves pipeToFilterPromise without closing
>           // encryptionFilter.
>           encryptionFilter.close();
>         }
>       );
>     }
>    }
>  };
> xhr.send();
>
>  encryptionFilter has the same interface as normal stream but encrypts
> piped data. Encrypted data is readable from it. It has special methods,
> encrypt() and abort().
>
>  processFile() is hypothetical function must be called only when all of
> loading, encryption and saving to file were successful.
>
>
>>
>> or
>>
>> var sourceStream = xhr.response;
>> var encryptionPromise = crypto.subtle.encrypt(aesAlgorithmEncrypt,
>> aesKey);
>> var hashPromise = crypto.subtle.digest(hash);
>> var resultStream = sourceStream.pipe([encryptionPromise,hashPromise]);
>> var fileWritingPromise = fileWriter.write(resultStream);
>> Promise.all([fileWritingPromise, resultStream]).then(
>>   ...
>> );
>>
>>
>  and this should be:
>
>  var sourceStream = xhr.response;
>
>  encryptionFilter =
> crypto.subtle.createEncryptionFilter(aesAlgorithmEncrypt, aesKey);
> var encryptionPromise = encryptionFilter.crypt();
>
>  hashFilter = crypto.subtle.createDigestFilter(hash);
> var hashPromise = hashFilter.digest();
>
>  pipeToFiltersPromise = sourceStream.pipe([encryptionFilter, hashFilter]);
>
>  var encryptedDataWritingPromise = fileWriter.write(encryptionFilter);
>
>  var hashWritingPromise =
>   Promise.all([encryptionPromise, encryptedDataWritingPromise]).then(
>      function(result) {
>       return fileWriter.write(hashFilter)
>     },
>     ...
>   );
>
>  Promise.all([hashPromise, hashWritingPromise]).then(
>    function(result) {
>     fileWriter.close();
>      processFile();
>   },
>   ...
> );
>
>  Or, we can also choose to let the writer API to create a special object
> that has the Stream interface for receiving input and then let
> encryptionFilter and hashFilter to pipe() to it.
>
>   ...
> pipeToFiltersPromise = sourceStream.pipe([encryptionFilter, hashFilter]);
> var streamForFileWrite = fileWriter.createStreamForWrite(encryptionFilter);
> var encryptedDataWritingPromise =
> encryptionFilter.pipe(streamForFileWrite);
>  var hashWritingPromise =
>   Promise.all([encryptionPromise, encryptedDataWritingPromise]).then(
>     function(result) {
>       return hashFilter.pipe(streamForWrite);
>      },
>     ...
>   );
>
>
>
> --
> Peersm : http://www.peersm.com
> node-Tor : https://www.github.com/Ayms/node-Tor
> GitHub : https://www.github.com/Ayms
>
>

Received on Wednesday, 30 October 2013 11:15:06 UTC