Reactor code. Some assorted bits of fixes.
* Check read() results where possible * Use unbuffered writes for temp files * Use vars instead of bare words as file handles * Use $VERSION * Coding style fixes * Update of Readme.md
This commit is contained in:
@@ -18,8 +18,10 @@
|
|||||||
## Как это работает?
|
## Как это работает?
|
||||||
|
|
||||||
При обращении к сгенерённому урлу, апи вначале идёт на сайт, выкачивает
|
При обращении к сгенерённому урлу, апи вначале идёт на сайт, выкачивает
|
||||||
видосик во временный каталог, отдаёт видосик клиенту и удаляет его из
|
видосик во временный каталог, отдаёт видосик клиенту. Есть встроенное
|
||||||
временного каталога. Есть встроенное ограничение на размер файла в 10Мб.
|
ограничение на размер файла в 10Мб.
|
||||||
|
|
||||||
|
N.B. Файлы из временного каталога автоматически не вычищаются.
|
||||||
|
|
||||||
## Как это запустить?
|
## Как это запустить?
|
||||||
|
|
||||||
|
|||||||
158
joyproxy.pm
158
joyproxy.pm
@@ -2,47 +2,61 @@ package joyproxy;
|
|||||||
|
|
||||||
use 5.018;
|
use 5.018;
|
||||||
use strict;
|
use strict;
|
||||||
use warnings "all";
|
use warnings;
|
||||||
use utf8;
|
use utf8;
|
||||||
use open qw(:std :utf8);
|
use open qw (:std :utf8);
|
||||||
|
|
||||||
|
use Fcntl;
|
||||||
use HTTP::Tiny;
|
use HTTP::Tiny;
|
||||||
use URI::URL;
|
use URI::URL;
|
||||||
use URI::Escape qw(uri_unescape);
|
use URI::Escape qw (uri_unescape);
|
||||||
|
|
||||||
use Exporter qw(import);
|
use Exporter qw (import);
|
||||||
use vars qw/$VERSION/;
|
use version; our $VERSION = qw (1.1.0);
|
||||||
|
our @EXPORT_OK = qw (joyproxy joyurl);
|
||||||
$VERSION = "1.0";
|
|
||||||
our @EXPORT = qw(joyproxy joyurl);
|
|
||||||
|
|
||||||
$| = 1;
|
|
||||||
|
|
||||||
sub joyproxy ($) {
|
sub joyproxy ($) {
|
||||||
my $str = shift;
|
my $str = shift;
|
||||||
chomp($str);
|
chomp $str;
|
||||||
|
|
||||||
return ('500', 'text/plain', 'This is not reactor video') if ($str !~ /^img[0-9]+\.reactor\.cc/);
|
# formal url check
|
||||||
|
if ($str !~ /^img\d+\.reactor\.cc/xmsg) {
|
||||||
|
return ('500', 'text/plain', 'This is not reactor video');
|
||||||
|
}
|
||||||
|
|
||||||
my ($file, $filesize) = __dlfunc("http://$str");
|
my ($file, $filesize) = __dlfunc ("http://$str");
|
||||||
|
|
||||||
if (defined($file)) {
|
if (defined $file) {
|
||||||
my $buf = '';
|
my $buf = '';
|
||||||
|
|
||||||
if (open(VID, '<', $file)) {
|
if (open my $VID, '<', $file) {
|
||||||
read(VID, $buf, $filesize);
|
binmode $VID;
|
||||||
close VID;
|
my $readlen = read ($VID, $buf, $filesize);
|
||||||
|
close $VID;
|
||||||
|
|
||||||
if ($file =~ /\.mp4/i) {
|
if (defined $readlen) {
|
||||||
|
if ($readlen != $filesize) {
|
||||||
|
warn "Unable to read $file readlen does not match filesize: $readlen vs $filesize";
|
||||||
|
return ('500', 'text/plain', "Unable to read file in temporary location\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
warn "Unable to read $file: $!";
|
||||||
|
return ('500', 'text/plain', "Unable to read file in temporary location: $!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($file =~ /\.mp4$/xmsgi) {
|
||||||
return ('200', 'video/mp4', $buf);
|
return ('200', 'video/mp4', $buf);
|
||||||
} elsif ($file =~ /\.webm/i) {
|
} elsif ($file =~ /\.webm$/xmsgi) {
|
||||||
return ('200', 'video/webm', $buf);
|
return ('200', 'video/webm', $buf);
|
||||||
} else {
|
} else {
|
||||||
return ('200', 'video/mpeg', $buf);
|
return ('200', 'video/mpeg', $buf);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
unlink $file if (-f $file);
|
if (-f $file) {
|
||||||
return ('500', 'text/plain', "Unable to open file in temporary loaction: $!\n");
|
unlink $file;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ('500', 'text/plain', "Unable to open file in temporary location: $!\n");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return ('500', 'text/plain', "Unable to get file from remote source!\n");
|
return ('500', 'text/plain', "Unable to get file from remote source!\n");
|
||||||
@@ -52,27 +66,29 @@ sub joyproxy ($) {
|
|||||||
sub joyurl (@) {
|
sub joyurl (@) {
|
||||||
my $str = shift;
|
my $str = shift;
|
||||||
my $host = shift;
|
my $host = shift;
|
||||||
$str = uri_unescape($str);
|
|
||||||
|
|
||||||
if (length($str) < 60) {
|
# TODO: handle error here
|
||||||
|
$str = uri_unescape $str;
|
||||||
|
|
||||||
|
if (length ($str) < 60) {
|
||||||
$str = '';
|
$str = '';
|
||||||
} else {
|
} else {
|
||||||
$str = substr($str, 14);
|
$str = substr $str, 14;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($str =~ /^img\d+\.reactor\.cc/) {
|
if ($str =~ /^img\d+\.reactor\.cc/xmsg) {
|
||||||
# img1.reactor.cc/pics/post/webm/видосик.webm
|
# img1.reactor.cc/pics/post/webm/видосик.webm
|
||||||
my @url = split(/\//, $str);
|
my @url = split /\//msx, $str;
|
||||||
|
|
||||||
if (($url[3] eq 'webm' || $url[3] eq 'mp4') and
|
if (($url[3] eq 'webm' || $url[3] eq 'mp4') &&
|
||||||
($url[4] =~ /\.webm$/ || $url[4] =~ /\.mp4$/)) {
|
($url[4] =~ /\.webm$/xmsg || $url[4] =~ /\.mp4$/xmsg)) {
|
||||||
# we prefer mp4, right?, so
|
# we prefer mp4, right?, so
|
||||||
my $fname;
|
my $fname;
|
||||||
$fname = substr($url[4], 0, -4) if (substr($url[4], -4, 4) eq '.mp4');
|
$fname = substr ($url[4], 0, -5) if (substr ($url[4], -5, 6) eq '.webm');
|
||||||
$fname = substr($url[4], 0, -5) if (substr($url[4], -5, 6) eq '.webm');
|
$fname = substr ($url[4], 0, -4) if (substr ($url[4], -4, 4) eq '.mp4');
|
||||||
|
|
||||||
$str = sprintf(
|
$str = sprintf (
|
||||||
"https://%s/joyproxy/%s/%s/%s/mp4/%s.mp4",
|
'https://%s/joyproxy/%s/%s/%s/mp4/%s.mp4',
|
||||||
$host,
|
$host,
|
||||||
$url[0],
|
$url[0],
|
||||||
$url[1],
|
$url[1],
|
||||||
@@ -80,7 +96,7 @@ sub joyurl (@) {
|
|||||||
$fname
|
$fname
|
||||||
);
|
);
|
||||||
|
|
||||||
$str = __urlencode($str);
|
$str = __urlencode ($str);
|
||||||
} else {
|
} else {
|
||||||
$str = '';
|
$str = '';
|
||||||
}
|
}
|
||||||
@@ -88,7 +104,16 @@ sub joyurl (@) {
|
|||||||
$str = '';
|
$str = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
my $msg = "<html>\n<body>\n<form method='get' action='joyurl'>\n<input type='text' name='joyurl' size=100 autofocus><br />\n<input type='submit' value='Post it!'' style='font-size:115%;'' />\n<br>$str\n</body>\n</html>\n";
|
my $msg = << "EOL";
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<form method='get' action='joyurl'>
|
||||||
|
<input type='text' name='joyurl' size=100 autofocus><br />
|
||||||
|
<input type='submit' value='Post it!' style='font-size:115%;' />
|
||||||
|
<br>$str
|
||||||
|
</body>
|
||||||
|
</html>\n
|
||||||
|
EOL
|
||||||
|
|
||||||
return ('200', 'text/html', $msg);
|
return ('200', 'text/html', $msg);
|
||||||
}
|
}
|
||||||
@@ -97,71 +122,72 @@ sub __urlencode($) {
|
|||||||
my $str = shift;
|
my $str = shift;
|
||||||
my $urlobj = url $str;
|
my $urlobj = url $str;
|
||||||
$str = $urlobj->as_string;
|
$str = $urlobj->as_string;
|
||||||
$urlobj = undef;
|
$urlobj = '';
|
||||||
undef $urlobj;
|
|
||||||
return $str;
|
return $str;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub __dlfunc($) {
|
sub __dlfunc($) {
|
||||||
my $url = shift;
|
my $url = shift;
|
||||||
|
|
||||||
if (! -d "/tmp/joyproxy") {
|
unless (-d '/tmp/joyproxy') {
|
||||||
warn "no /tmp/joyproxy";
|
warn 'no /tmp/joyproxy';
|
||||||
return (undef, undef) unless (mkdir("/tmp/joyproxy"));
|
|
||||||
|
unless (mkdir '/tmp/joyproxy') {
|
||||||
|
return (undef, undef);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
my @tmparray = split(/\//, $url);
|
my @explodedurl = split /\//msx, $url;
|
||||||
my $file = $tmparray[@tmparray - 1];
|
my $file = $explodedurl[$#explodedurl];
|
||||||
$#tmparray = -1; undef @tmparray;
|
$#explodedurl = -1; undef @explodedurl;
|
||||||
$file = "/tmp/joyproxy/" . $file;
|
$file = '/tmp/joyproxy/' . $file;
|
||||||
$url = __urlencode($url);
|
$url = __urlencode ($url);
|
||||||
|
|
||||||
my $http = HTTP::Tiny->new(max_size => 10485760);
|
my $http = HTTP::Tiny->new (max_size => 10485760);
|
||||||
|
|
||||||
my $response = $http->get(
|
# use ->get because of ->mirror does not respect max_size
|
||||||
|
my $response = $http->get (
|
||||||
$url,
|
$url,
|
||||||
{
|
{
|
||||||
headers => {
|
headers => {
|
||||||
"Accept" => '*/*',
|
'Accept' => '*/*',
|
||||||
"Accept-Encoding" => 'identity;q=1, *;q=0',
|
'Accept-Encoding' => 'identity;q=1, *;q=0',
|
||||||
"Accept-Language" => 'ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7',
|
'Accept-Language' => 'ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7',
|
||||||
"Range" => 'bytes=0-',
|
'Range' => 'bytes=0-',
|
||||||
"Referer" => 'http://old.reactor.cc/all',
|
'Referer' => 'http://old.reactor.cc/all',
|
||||||
"User-Agent" => "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36"
|
'User-Agent' => 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$http = '';
|
||||||
|
|
||||||
if ($response->{success}) {
|
if ($response->{success}) {
|
||||||
my $filesize = 0;
|
my $filesize = 0;
|
||||||
|
|
||||||
open (FILE, '>', $file) or do {
|
sysopen (my $FILE, $file, O_CREAT|O_TRUNC|O_WRONLY) or do {
|
||||||
$http = undef;
|
$response = '';
|
||||||
$response = undef;
|
|
||||||
return (undef, undef);
|
return (undef, undef);
|
||||||
};
|
};
|
||||||
|
|
||||||
binmode FILE;
|
binmode $FILE;
|
||||||
|
|
||||||
print (FILE $response->{content}) or do {
|
syswrite ($FILE, $response->{content}) or do {
|
||||||
$http = undef;
|
close $FILE;
|
||||||
$response = undef;
|
$response = '';
|
||||||
return (undef, undef);
|
return (undef, undef);
|
||||||
};
|
};
|
||||||
|
|
||||||
close FILE;
|
close $FILE;
|
||||||
$http = undef;
|
$response = '';
|
||||||
$response = undef;
|
$filesize = (stat $file )[7];
|
||||||
$filesize = (stat($file))[7];
|
|
||||||
return ($file, $filesize);
|
return ($file, $filesize);
|
||||||
} else {
|
} else {
|
||||||
$http = undef;
|
$response = '';
|
||||||
$response = undef;
|
|
||||||
return (undef, undef);
|
return (undef, undef);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
||||||
# vim: set ft=perl noet ai ts=4 sw=4 sts=4:
|
# vim: set ft=perl noet ai ts=4 sw=4 sts=4:
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
use 5.018;
|
use 5.018;
|
||||||
use strict;
|
use strict;
|
||||||
use warnings "all";
|
use warnings;
|
||||||
use utf8;
|
use utf8;
|
||||||
use open qw(:std :utf8);
|
use open qw (:std :utf8);
|
||||||
|
use version; our $VERSION = qw (1.1.0);
|
||||||
|
|
||||||
use lib qw(. ./vendor_perl/lib/perl5);
|
use lib qw (. ./vendor_perl/lib/perl5);
|
||||||
use joyproxy qw(joyurl joyproxy);
|
use joyproxy qw (joyurl joyproxy);
|
||||||
|
|
||||||
$| = 1;
|
|
||||||
|
|
||||||
my $app = sub {
|
my $app = sub {
|
||||||
my $env = shift;
|
my $env = shift;
|
||||||
@@ -16,25 +15,23 @@ my $app = sub {
|
|||||||
my $status = '404';
|
my $status = '404';
|
||||||
my $content = 'text/plain';
|
my $content = 'text/plain';
|
||||||
|
|
||||||
if ($env->{PATH_INFO} =~ /^\/joyproxy\/(.+)/) {
|
if ($env->{PATH_INFO} =~ /^\/joyproxy\/(.+)/xmsg) {
|
||||||
my $joyproxyurl = $1;
|
my $joyproxyurl = $1;
|
||||||
($status, $content, $msg) = ('400', $content, "Bad Request?\n");
|
($status, $msg) = ('400', "Bad Request?\n");
|
||||||
|
|
||||||
if (($joyproxyurl =~ /\.mp4/i) or ($joyproxyurl =~ /\.webm/i)) {
|
if (($joyproxyurl =~ /\.mp4$/xmsgi) or ($joyproxyurl =~ /\.webm$/xmsgi)) {
|
||||||
($status, $content, $msg) = joyproxy($joyproxyurl);
|
($status, $content, $msg) = joyproxy $joyproxyurl ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($env->{PATH_INFO} =~ /^\/joyurl/) {
|
if ($env->{PATH_INFO} =~ /^\/joyurl/xmsg) {
|
||||||
if (defined($env->{QUERY_STRING})) {
|
my $querystring = $env->{QUERY_STRING} // '';
|
||||||
($status, $content, $msg) = joyurl($env->{QUERY_STRING}, $env->{HTTP_HOST});
|
|
||||||
} else {
|
($status, $content, $msg) = joyurl ($querystring, $env->{HTTP_HOST});
|
||||||
($status, $content, $msg) = joyurl('', $env->{HTTP_HOST});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
use bytes;
|
use bytes;
|
||||||
my $length = length($msg);
|
my $length = length $msg;
|
||||||
no bytes;
|
no bytes;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|||||||
Reference in New Issue
Block a user