#
# The attachment interface
#
-# Copyright (C) 2016, 2023 Balthasar Szczepański
+# Copyright (C) 2016, 2023, 2024 Balthasar Szczepański
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
###PERL_LIB: use lib /botm/lib/bsta
use botm_common (
+ 'HTTP_STATUS',
+ 'merge_settings',
+ 'fail_method', 'fail_content_type', 'fail_attachment', 'fail_500',
+ 'redirect',
'read_header_env',
'url_query_decode',
- 'read_data_file',
- 'join_path'
+ 'join_path',
+ 'merge_url',
+ 'open_encoded', 'stat_encoded',
+ 'http_header_line', 'http_header_content_length', 'http_header_content_disposition'
);
use bsta_lib (
'STATE',
- 'merge_settings',
'get_id', 'get_password',
- 'fail_attachment', 'fail_500'
+ 'read_settings', 'read_state', 'read_attachment'
);
###PERL_PATH_SEPARATOR: PATH_SEPARATOR = /
+###PERL_CGI_PATH: CGI_PATH = /bsta/
###PERL_DATA_PATH: DATA_PATH = /botm/data/bsta
-###PERL_DATA_SETTINGS_PATH: DATA_SETTINGS_PATH = /botm/data/bsta/settings
-###PERL_DATA_STATE_PATH: DATA_STATE_PATH = /botm/data/bsta/state
+###PERL_WWW_PATH: WWW_PATH = /botm/www/1190/bsta/
binmode STDIN, ':encoding(UTF-8)';
binmode STDOUT, ':encoding(UTF-8)';
my $method;
my $ID;
my $frame;
+my $last_frame;
+my $ong_state;
my $password;
my $password_ok;
my $IP;
+my $try_onged;
my $buffer;
my $fh;
my $file_path;
+my $file_name;
my $direct;
+my $r = 0;
delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
###PERL_SET_PATH: $ENV{'PATH'} = /usr/local/bin:/usr/bin:/bin;
$method = $1;
}
else{
- exit fail_method($ENV{'REQUEST_METHOD'}, 'GET, POST, HEAD');
+ exit fail_method($ENV{'REQUEST_METHOD'}, ['GET', 'POST', 'HEAD']);
}
%http = read_header_env(\%ENV);
}
}
-# print "content-type: text/plain\n\n";
-
$ID = get_id( \%cgi);
$password = get_password(\%cgi);
-%settings = read_data_file(DATA_SETTINGS_PATH);
-%state = read_data_file(DATA_STATE_PATH);
-%file_data = read_data_file(join_path(PATH_SEPARATOR(), DATA_PATH(), 'a'.$ID));
+%settings = read_settings();
+%state = read_state();
+%file_data = read_attachment($ID);
$frame = ($file_data{'frame'} ne '') ? int($file_data{'frame'}) : -1;
+$last_frame = int($state{'last'});
+$ong_state = int($state{'state'});
+$file_name = $file_data{'filename'};
$password_ok = ($password eq $settings{'password'});
unless (
- ($file_data{'filename'} ne '') && (
+ ($file_name ne '') && (
$password_ok || (
- (int($state{'state'}) >= STATE->{'waiting'}) &&
- ($frame <= int($state{'last'})) &&
+ ($ong_state >= STATE->{'waiting'}) &&
+ ($frame <= $last_frame) &&
($frame >=0)
)
)
}
else {
$direct = 0;
- $file_path = join_path(PATH_SEPARATOR(), DATA_PATH(), $file_data{'filename'});
- unless (open($fh,'<', encode('locale_fs', $file_path))) {
- exit fail_attachment($method, $ID);
+ $try_onged = (
+ ($ong_state >= STATE->{'waiting'}) &&
+ ($frame <= $last_frame) &&
+ ($frame >=0)
+ );
+ if ($try_onged) {
+ $file_path = join_path(PATH_SEPARATOR(), WWW_PATH(), $file_name);
+ $r = open_encoded($fh, '<' , $file_path);
+ if ($r) {
+ close($r);
+ $file_path = merge_url(
+ {'path' => CGI_PATH()},
+ {'path' => $file_name}
+ );
+ exit redirect ($method, $file_path, HTTP_STATUS->{'see_other'});
+ }
}
- unless(binmode($fh)) {
+ unless ($r) {
+ $file_path = join_path(PATH_SEPARATOR(), DATA_PATH(), $file_name);
+ $r = open_encoded($fh,'<', $file_path);
+ unless ($r) {
+ exit fail_attachment($method, $ID);
+ }
+ }
+ unless (binmode($fh)) {
close($fh);
exit fail_500("Can't switch file to binary mode.");
}
- if (my @file_info = stat($file_path)) {
- print 'Content-length: '.$file_info[7]."\n";
+ if (my @file_info = stat_encoded($file_path)) {
+ print http_header_content_length($file_info[7]);
}
}
-print 'Content-type: '.$file_data{'content-type'}."\n";
-print 'Content-disposition: attachment; filename="'.$file_data{'filename'}.'"'."\n";
+if ($file_data{'content-type'} ne '') {
+ print http_header_line('content-type', $file_data{'content-type'});
+}
+if ($file_name ne '') {
+ print http_header_content_disposition('inline', $file_name);
+}
unless ($direct) {
unless (binmode STDOUT) {
close($fh);