File Uploading, A Perl+Python Approach
My initial approach avoided the whole issue by running the download server from the opposite end, but this approach is not very flexible 'cos user requires Python to be installed in their desktop.
My second approach was to develop a CGI program (upload.cgi) based on the established Perl CGI.pm module. The below CGI script is launched via a running Apache web server. However, we have to depend on the existence of Apache web server.
#! /usr/bin/perl use CGI; use CGI::Carp qw ( fatalsToBrowser ); use File::Basename; if ( $ENV{"REQUEST_METHOD"} eq "GET" ) { print "Content-type: text/html\n\n"; print "<html><head><title>Upload</title></head><body>"; printf("<form action=%s method=POST ENCTYPE=multipart/form-data>", $ENV{'SCRIPT_NAME'}); print "<input type=file name=upfile> <input type=submit value=Upload></form>"; print "</body></html>"; } else { my $safe_filename_characters = "a-zA-Z0-9_.-"; my $upload_dir = "/export/software/upload"; my $query = new CGI; my $fname = $query->param("upfile"); $fname =~ s/\\/\//g; my ( $name, $path, $extension ) = fileparse ( $fname, '\..*' ); $filename = $name . $extension; $filename =~ tr/ /_/; $filename =~ s/[^$safe_filename_characters]//g; my $upload_filehandle = $query->upload("upfile"); open ( UPLOADFILE, ">$upload_dir/$filename" ) or die "$!"; binmode UPLOADFILE; print "Content-type: text/html\n\n"; print "<html><head><title>Upload</title></head><body>"; while ( <$upload_filehandle> ) { print "..."; print UPLOADFILE; } close UPLOADFILE; printf("Your file is in /export/software/upload/%s (%s)", $filename, $fname); print "</body></html>"; }
My third approach was to combine Perl and Python in a single Python script. Python comes with a simple and workable CGIHTTPServer module that allows me to run a self-contained web server that can server CGI script. With the below script (uploadserver), it will dynamically create a random cgi-bin directory with the Perl upload.cgi script. An index.html is also dynamically created that can do auto-redirection to the cgi-bin/upload.cgi. With this script, I can launch the upload server anywhere and able to upload file via a web browser.
#! /usr/local/bin/python import BaseHTTPServer import CGIHTTPServer import tempfile import os import random import platform # # standalone CGI perl script for uploading. # escaped all the backslashes # perlscript="""#! /usr/bin/perl use CGI; use CGI::Carp qw ( fatalsToBrowser ); use File::Basename; if ( $ENV{"REQUEST_METHOD"} eq "GET" ) { print "Content-type: text/html\\n\\n"; print "<html><head><title>Upload</title></head><body>"; printf("<form action=%s method=POST ENCTYPE=multipart/form-data>", $ENV{'SCRIPT_NAME'}); print "<input type=file name=upfile> <input type=submit value=Upload></form>"; print "</body></html>"; } else { my $safe_filename_characters = "a-zA-Z0-9_.-"; my $upload_dir = "."; my $query = new CGI; my $fname = $query->param("upfile"); # # convert backslash to forward flash, remove un-safe characters in filename # $fname =~ s/\\\\/\\//g; my ( $name, $path, $extension ) = fileparse ( $fname, '\\..*' ); $filename = $name . $extension; $filename =~ tr/ /_/; $filename =~ s/[^$safe_filename_characters]//g; my $upload_filehandle = $query->upload("upfile"); open ( UPLOADFILE, ">$upload_dir/$filename" ) or die "$!"; binmode UPLOADFILE; while ( <$upload_filehandle> ) { print UPLOADFILE; } close UPLOADFILE; print "Content-type: text/html\\n\\n"; print "<html><head><title>Upload</title></head><body>"; printf("Your file '%s' has been successfully uploaded", $filename,); print "</body></html>"; } """ if not os.path.isfile('index.html'): try: tempdir = tempfile.mkdtemp(dir='.')[2:] os.chmod(tempdir, 0755) uploadcgi = tempdir + '/upload.cgi' cgidir = '/' + uploadcgi # write index.html fp = open('index.html', 'w') refresh = '<html><head><meta http-equiv="REFRESH" content="0;url=/%s"></head><body></body></html>' % uploadcgi fp.write(refresh) fp.close() # create cgi script fp = open(uploadcgi, 'w') fp.write(perlscript) fp.close() os.chmod(uploadcgi, 0755) # change the internal settings CGIHTTPServer.CGIHTTPRequestHandler.cgi_directories = [cgidir] CGIHTTPServer.nobody = os.getuid() port = random.randint(50000,60000) url = "http://%s:%d/" % (platform.node(), port) httpd = BaseHTTPServer.HTTPServer(('',port), CGIHTTPServer.CGIHTTPRequestHandler) print "Ask user to visit this URL:\n\t%s" % url httpd.serve_forever() except: # clean up os.remove('index.html') os.remove(uploadcgi) os.rmdir(tempdir) else: print 'Error. index.html exists'
# ./uploadserver Ask user to visit this URL: http://user-PC:52233/
When you point your web server to the able URL, it will auto redirect.