#! /usr/bin/env perl # Program: upload_http # Copyright (C) 2016 R. W. Rodolico # # Description # Script will upload file passed on STDIN to URL defined in $server # using variable name $urlVarName. # Filename may also be passed on command line # It assumes the remote server will return the exact contents which # is then used to compare to what was sent # It will return the following codes # 0 - success # 1 - Could not find LWP::Simple module # 2 - file not passed on STDIN # 3 - Contents returned by server do not match our local copy # 4 - URL call returned a "not found" error # 5 - no key given for report contents # 6 - no key given for report date # 7 - no key given for hostname # 8 - no key given for client # 9 - no key given for serial number # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # version 1.1 RWR, 20240518 # Setting up so only UTF8 sent use warnings; use strict; use open ':std', ':encoding(utf8)' ; # force all I/O, including disk and STD?, to use utf-8 our $VERSION = '1.1'; eval { use LWP; }; if ( $@ ) { print STDERR "Could not load library LWP\n"; exit 1; # error 1 means we could not find LWP } use Data::Dumper; use Scalar::Util qw( looks_like_number ); sub urlEncode { my $contents = shift; # escape report for URI eval { # let's use URI::Escape if it is installed use URI::Escape; }; if ( ! $@ ) { # we loaded URI::Escape return uri_escape( $contents ); } else { # nope, URI::Escape was not installed (or died) # so use our home grown thing # kind of a funky way to write it, but it should be very, very fast # will take the document passed and split it into array of individual # characters -- split ( '', shift ) # that then will go through map, which converts it to the for %xx # required for URL encoding IF it is not alphanumeric. return join( '', ( map { ($_ =~ m/[a-zA-Z0-9]/) ? $_ : '%' . sprintf("%2.2x",ord( $_ ) ) } split ( '', $contents ) ) ); } # if } sub writeFile { my ( $filename, $contents ) = @_; open FILE,">$filename" or die "Could not write to $filename: $!\n"; print FILE $contents; close FILE; } sub sendData { my ( $url, $parameters ) = @_; # &writeFile( "/tmp/upload_http", Dumper( $parameters ) ); my $browser = LWP::UserAgent->new(); my $response = $browser->post( $url, $parameters, 'Content_Type' => 'form-data' ); return $response; } sub filename { return '/tmp/' . time . '.sysinfo'; } sub doit { my ( $parameters, $message ) = @_; my $url = $$parameters{'URL'} or die "Could not find URL to send to\n"; my %postData; my $saveFileName = &filename(); if ( $$parameters{'key for report'} ) { &writeFile( $saveFileName, $message ); # make a backup copy of the report $postData{ $$parameters{'key for report'} } = [ #'/tmp/theReport' => 'myReport' undef, 'temp.report', 'Content-Type' => 'application/x-www-form-urlencoded', 'Content' => $message ]; } else { return 5; # no key given for report } if ( $$parameters{'key for date'} ) { $postData{ $$parameters{'key for date'} } = $$parameters{'report date'}; } else { return 6; # can't process because we have no report date } if ( $$parameters{'key for hostname'} ) { $postData{ $$parameters{'key for hostname'} } = $$parameters{'host name'}; } else { return 7; # no hostname } if ( $$parameters{'key for client'} ) { $postData{ $$parameters{'key for client'} } = $$parameters{'client name'}; } else { return 8; # no client name } if ( $$parameters{'key for serial number'} ) { $postData{ $$parameters{'key for serial number'} } = $$parameters{'serial number'}; } else { return 9; # no serial number } if ( $$parameters{'upload_type'} ) { $postData{ 'upload_type' } = $$parameters{'upload_type'}; } $postData{'filename'} = $$parameters{'report date'} . '_' . $$parameters{'client name'} . '_' . $$parameters{'host name'} . '_' . $$parameters{'serial number'} . '.yaml'; #print Dumper( \%postData ); die; my $result = sendData( $url, \%postData ); if ( $result->is_success ) { # we got a response, so validate the transfer #print $result->status_line . "\n"; die; #unless ( ! looks_like_number( $result->content ) && ( $result->content * 1) == length($message) ) { # report returned was not one we sent # print STDERR "Server did not read file correctly\nWe sent " . length($message) . " bytes but server only saved " . $result->content . "\n"; # return 3; #} } else { print STDERR "URL did not work. Full URI sent follows\n$url\n"; print STDERR "Return was " . $result->content . "\n"; return 4; # crud, could not even find the URL } `rm $saveFileName`; return 1; } 1; #