mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-09-08 08:57:03 +03:00
Added AbstractFetchRemote.streamPerLine(fCallback, sGetAdd) for future use of streaming data to the client.
This commit is contained in:
parent
013f09c8d3
commit
20eb01de08
3 changed files with 95 additions and 3 deletions
|
|
@ -78,6 +78,45 @@ export class AbstractFetchRemote
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows quicker visual responses to the user.
|
||||||
|
* Can be used to stream lines of json encoded data, but does not work on all servers.
|
||||||
|
* Apache needs 'flushpackets' like in <Proxy "fcgi://...." flushpackets=on></Proxy>
|
||||||
|
*/
|
||||||
|
streamPerLine(fCallback, sGetAdd) {
|
||||||
|
rl.fetch(getURL(sGetAdd))
|
||||||
|
.then(response => response.body)
|
||||||
|
.then(body => {
|
||||||
|
// Firefox TextDecoderStream is not defined
|
||||||
|
// const reader = body.pipeThrough(new TextDecoderStream()).getReader();
|
||||||
|
const reader = body.getReader(),
|
||||||
|
re = /\r\n|\n|\r/gm,
|
||||||
|
utf8decoder = new TextDecoder();
|
||||||
|
let buffer = '';
|
||||||
|
function processText({ done, value }) {
|
||||||
|
buffer += value ? utf8decoder.decode(value, {stream: true}) : '';
|
||||||
|
for (;;) {
|
||||||
|
let result = re.exec(buffer);
|
||||||
|
if (!result) {
|
||||||
|
if (done) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
reader.read().then(processText);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fCallback(buffer.substring(0, result.index));
|
||||||
|
buffer = buffer.substring(result.index + 1);
|
||||||
|
re.lastIndex = 0;
|
||||||
|
}
|
||||||
|
if (buffer.length) {
|
||||||
|
// last line didn't end in a newline char
|
||||||
|
fCallback(buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reader.read().then(processText);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {?Function} fCallback
|
* @param {?Function} fCallback
|
||||||
* @param {string} sAction
|
* @param {string} sAction
|
||||||
|
|
|
||||||
11
dev/bootstrap.js
vendored
11
dev/bootstrap.js
vendored
|
|
@ -55,7 +55,7 @@ export default App => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
rl.fetchJSON = (resource, init, postData) => {
|
rl.fetch = (resource, init, postData) => {
|
||||||
init = Object.assign({
|
init = Object.assign({
|
||||||
mode: 'same-origin',
|
mode: 'same-origin',
|
||||||
cache: 'no-cache',
|
cache: 'no-cache',
|
||||||
|
|
@ -64,7 +64,6 @@ export default App => {
|
||||||
credentials: 'same-origin',
|
credentials: 'same-origin',
|
||||||
headers: {}
|
headers: {}
|
||||||
}, init);
|
}, init);
|
||||||
init.headers.Accept = 'application/json';
|
|
||||||
if (postData) {
|
if (postData) {
|
||||||
init.method = 'POST';
|
init.method = 'POST';
|
||||||
init.headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
|
init.headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
|
||||||
|
|
@ -86,7 +85,13 @@ export default App => {
|
||||||
init.body = new URLSearchParams(postData);
|
init.body = new URLSearchParams(postData);
|
||||||
}
|
}
|
||||||
|
|
||||||
return fetch(resource, init).then(response => {
|
return fetch(resource, init);
|
||||||
|
};
|
||||||
|
|
||||||
|
rl.fetchJSON = (resource, init, postData) => {
|
||||||
|
init = Object.assign({ headers: {} }, init);
|
||||||
|
init.headers.Accept = 'application/json';
|
||||||
|
return rl.fetch(resource, init, postData).then(response => {
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
return Promise.reject('Network response error: ' + response.status);
|
return Promise.reject('Network response error: ' + response.status);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
48
snappymail/v/0.0.0/app/libraries/snappymail/http/stream.php
Normal file
48
snappymail/v/0.0.0/app/libraries/snappymail/http/stream.php
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SnappyMail\HTTP;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can be used with JavaScript AbstractFetchRemote.streamPerLine(fCallback, sGetAdd)
|
||||||
|
*/
|
||||||
|
|
||||||
|
abstract class Stream
|
||||||
|
{
|
||||||
|
public static function start(bool $binary = false)
|
||||||
|
{
|
||||||
|
\set_time_limit(0);
|
||||||
|
\ob_implicit_flush();
|
||||||
|
\ini_set('implicit_flush',1);
|
||||||
|
\ini_set('output_buffering', 0);
|
||||||
|
if ($i = \ob_get_level()) {
|
||||||
|
# Clear buffers:
|
||||||
|
while ($i-- && \ob_end_clean());
|
||||||
|
// if (!\ob_get_level()) \header('Content-Encoding: ');
|
||||||
|
}
|
||||||
|
// https://www.w3.org/TR/edge-arch/
|
||||||
|
// We just fake Drupal https://www.drupal.org/docs/8/core/modules/big-pipe/bigpipe-environment-requirements
|
||||||
|
\header('Surrogate-Control: no-store, content="BigPipe/1.0"');
|
||||||
|
// Explicitly disable caching so Varnish and other upstreams won't cache.
|
||||||
|
\header('Cache-Control: no-store, no-cache, must-revalidate');
|
||||||
|
\header('Pragma: no-cache');
|
||||||
|
|
||||||
|
// Nginx: disable fastcgi_buffering and disable gzip for this request.
|
||||||
|
\header('X-Accel-Buffering: no');
|
||||||
|
|
||||||
|
// Apache mod_fastcgi needs the -flush option
|
||||||
|
// Apache mod_proxy_fcgi needs 'flushpackets' like in <Proxy "fcgi://...." flushpackets=on></Proxy>
|
||||||
|
// We can't control them here
|
||||||
|
// We can control ending the response with \fastcgi_finish_request()
|
||||||
|
|
||||||
|
if (!$binary) {
|
||||||
|
\header('Content-Type: text/plain');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function JSON($data)
|
||||||
|
{
|
||||||
|
echo \MailSo\Base\Utils::Php2js($data) . "\n";
|
||||||
|
\ob_flush();
|
||||||
|
\flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue