Streaming is theoretically implemented. My server does not support it, and most servers do not, but if any do it should work. Of course with no way to test, I'm just not sure.

This commit is contained in:
Storm Dragon
2025-08-05 14:11:06 -04:00
parent 6d1b97a012
commit d58e5045bd
+59 -20
View File
@@ -400,7 +400,7 @@ EOF
$directurl = "${apibase}/conversations"; $directurl = "${apibase}/conversations";
$listurl = "${apibase}/lists/%I/accounts"; $listurl = "${apibase}/lists/%I/accounts";
$murl = "${apibase}/timelines/home"; $murl = "${apibase}/timelines/home";
$streamurl = "${oauthbase}/api/v1/streaming/user"; $streamurl = "${oauthbase}/api/v1/streaming";
$publicurl = "${apibase}/timelines/public"; $publicurl = "${apibase}/timelines/public";
$searchurl = "${oauthbase}/api/v2/search"; $searchurl = "${oauthbase}/api/v2/search";
$trendsurl = "${apibase}/trends"; $trendsurl = "${apibase}/trends";
@@ -5920,29 +5920,68 @@ sub start_streaming {
# restart nurse process if it/curl died # restart nurse process if it/curl died
goto HELLOAGAINNURSE if(!$streampid); goto HELLOAGAINNURSE if(!$streampid);
# read a line of text (hopefully numbers) if ($authtype eq 'oauth2') {
chomp($buf = <NURSE>); # Handle Mastodon Server-Sent Events format
# should be nothing but digits and whitespace. my $event_type = '';
# if anything else, we're getting garbage, and we my $event_data = '';
# should reconnect.
if ($buf =~ /[^0-9\r\l\n\s]+/s) { # Read lines until we get a complete event
while(defined($buf = <NURSE>)) {
chomp($buf);
# Empty line marks end of event
if ($buf eq '') {
if ($event_data) {
# Package the event data for processing
$duf = "{ \"packet\" : \"data\", \"pid\" : \"$streampid\", \"curlpid\" : \"$curlpid\", \"payload\" : $event_data }";
printf STDOUT ("%08x%s", length($duf), $duf);
$packets_read++;
}
$event_type = '';
$event_data = '';
next HELLONURSE;
}
# Parse SSE fields
if ($buf =~ /^event:\s*(.*)$/) {
$event_type = $1;
} elsif ($buf =~ /^data:\s*(.*)$/) {
$event_data .= $1;
}
# Ignore other SSE fields like 'id:', 'retry:', etc.
}
# If we reach here, the stream ended - reconnect
close(NURSE); close(NURSE);
kill 9, $streampid if ($streampid); kill 9, $streampid if ($streampid);
# and SIGCHLD will reap
kill 9, $curlpid if ($curlpid); kill 9, $curlpid if ($curlpid);
goto HELLOAGAINNURSE; goto HELLOAGAINNURSE;
} else {
# Handle legacy Twitter-style length-prefixed format
chomp($buf = <NURSE>);
# should be nothing but digits and whitespace.
# if anything else, we're getting garbage, and we
# should reconnect.
if ($buf =~ /[^0-9\r\l\n\s]+/s) {
close(NURSE);
kill 9, $streampid if ($streampid);
# and SIGCHLD will reap
kill 9, $curlpid if ($curlpid);
goto HELLOAGAINNURSE;
}
$datasize = 0+$buf;
next HELLONURSE if (!$datasize);
$datasize--;
read(NURSE, $duf, $datasize);
# don't send broken entries
next HELLONURSE if (length($duf) < $datasize);
# yank out all \r\n
1 while $duf =~ s/[\r\n]//g;
$duf = "{ \"packet\" : \"data\", \"pid\" : \"$streampid\", \"curlpid\" : \"$curlpid\", \"payload\" : $duf }";
printf STDOUT ("%08x%s", length($duf), $duf);
$packets_read++;
} }
$datasize = 0+$buf;
next HELLONURSE if (!$datasize);
$datasize--;
read(NURSE, $duf, $datasize);
# don't send broken entries
next HELLONURSE if (length($duf) < $datasize);
# yank out all \r\n
1 while $duf =~ s/[\r\n]//g;
$duf = "{ \"packet\" : \"data\", \"pid\" : \"$streampid\", \"curlpid\" : \"$curlpid\", \"payload\" : $duf }";
printf STDOUT ("%08x%s", length($duf), $duf);
$packets_read++;
} }
} else { } else {
# within the nurse process # within the nurse process
@@ -5963,7 +6002,7 @@ sub start_streaming {
my $stream_endpoint; my $stream_endpoint;
if ($authtype eq 'oauth2') { if ($authtype eq 'oauth2') {
# Mastodon streaming - use Server-Sent Events # Mastodon streaming - use Server-Sent Events
$stream_endpoint = "$streamurl?stream=user"; $stream_endpoint = "$streamurl/user";
} else { } else {
# fediverse legacy streaming # fediverse legacy streaming
$stream_endpoint = "$streamurl?delimited=length${replarg}"; $stream_endpoint = "$streamurl?delimited=length${replarg}";