我一直在努力将内部应用程序转换为不使用FTP,因为安全团队已告知我们要退出FTP。 因此,我一直在使用HTTP上传,并且在大多数情况下效果很好。 我们的环境是Linux,HP-UX,Solaris和AIX的混搭。 在我们的Linux服务器上,curl是通用的,因此我一直在使用curl的POST功能进行上传,并且可以完美地工作。 不幸的是,Unix机器很少有卷曲,甚至没有wget,所以我用perl编写了一个GET脚本,该脚本可以正常工作,而我为perl编写的POST脚本(从网络上的其他地方提起并改编)可以很好地用于Unix,直到上传的数据大于约60K(在Linux中,curl处理得很好)。 除此之外,Apache错误日志开始溢出:
CGI.pm: Server closed socket during multipart read (client aborted?).
当我使用curl进行上传时,永远不会发生此类错误。 这是我使用Socket的POST脚本,因为LWP并非在每台服务器上都可用,并且在所有Unix服务器上都不可用。
#!/usr/bin/perl -w
use strict;
use Socket;
my $v = 'dcsm';
my $upfile = $ARGV[0] or die 'Upload File not found or not specified.' . "\n";
my $hostname = $ARGV[1] or die 'Hostname not specified.' . "\n";
$| = 1;
my $host = "url.mycompany dot com";
my $url = "/csmtar.cgi";
my $start = times;
my ( $iaddr, $paddr, $proto );
$iaddr = inet_aton($host);
$paddr = sockaddr_in( 80, $iaddr );
$proto = getprotobyname('tcp');
unless ( socket( SOCK, PF_INET, SOCK_STREAM, $proto ) ) {
die "ERROR : init socket: $!";
}
unless ( connect( SOCK, $paddr ) ) {
die "no connect: $!\n";
}
my $length = 0;
open( UH, "< $upfile" ) or warn "$!\n";
$length += -s $upfile;
my $boundary = 'nn7h23ffh47v98';
my @head = (
"POST $url HTTP/1.1",
"Host: $host",
"User-Agent: z-uploader",
"Content-Length: $length",
"Content-Type: multipart/form-data; boundary=$boundary",
"",
"--$boundary",
"Content-Disposition: form-data; name=\"hostname\"",
"",
"$hostname",
"--$boundary",
"Content-Disposition: form-data; name=\"ren\"",
"",
"true",
"--$boundary",
"Content-Disposition: file; name=\"filename\"; filename=\"$upfile\"",
"--$boundary--",
"",
"",
);
my $header = join( "\r\n", @head );
$length += length($header);
$head[3] = "Content-Length: $length";
$header = join( "\r\n", @head );
$length = -s $upfile;
$length += length($header);
select SOCK;
$| = 1;
print SOCK $header;
while ( sysread( UH, my $buf, 8196 ) ) {
if ( length($buf) < 8196 ) {
$buf = $buf . "\r\n--$boundary";
syswrite SOCK, $buf, length($buf);
} else {
syswrite SOCK, $buf, 8196;
}
print STDOUT '.',;
}
close UH;
shutdown SOCK, 1;
my @data = ();
print STDOUT "result->@data\n";
close SOCK;
有人看到有东西跳出来吗?
更新:
我进行了以下更新,并且错误似乎没有改变。
为了解决内容长度问题,并尝试消除在附加最终边界之前使循环等于字符的确切数目的可能性,我进行了以下代码更新。
my $boundary = 'nn7h23ffh47v98';
my $content = <
--$boundary
Content-Disposition: form-data; name="hostname"
$hostname
--$boundary
Content-Disposition: file; name="filename"; filename="$upfile"
--$boundary--
EOF
$length += length($content);
my $header = <
POST $url HTTP/1.1
Host: $host
User-Agent: z-uploader
Content-Length: $length
Content-Type: multipart/form-data; boundary=$boundary
EOF
$header .= $content;
select SOCK;
$| = 1;
print SOCK $header;
my $incr = ($length + 100) / 20;
$incr = sprintf("%.0f", $incr);
while (sysread(UH, my $buf, $incr )) {
syswrite SOCK, $buf, $incr;
}
syswrite SOCK, "\n--$boundary", $incr;