Uploading - Off Track
June 22nd, 2006
Recently for work I made a file parser with a web interface. Although it currently isn’t in production, here is my general setup:
- XAMPP 1.5.2
- Ruby 1.8.4, from the provided zip file
Note: No Ruby on Rails.
Ruby was supprisinly easy to get running along with XAMPP - scripts simply needed the correct first line. Since I used the zip file, mine is:
#!"\ruby\bin\ruby.exe"
To make things easier - so I thought - I would use Ruby’s CGI library.
That is not quite true - the ‘easier’ part.
CGI does give a very easy way to access POST and GET variables - cgi.params['variable']
However, it is quite prone to breaking the webpage it generates, with downright useless error messages.
So I came up with some code that will run both from form submission AND form the command line, which gives the option for much easier testing.
Note: zytrax Ruby Info served as an important basis of this information.
First, the form that submits; upload.rb.cgi
#!"\ruby\bin\ruby.exe"
require 'cgi'
require 'stringio'
puts 'Content-Type: text/html'
puts
puts '<html>
<head>
</head>
<body>
<form method="post" action="parse.rb.cgi" enctype="multipart/form-data">
<fieldset>
<legend>Upload File</legend>
<input type="file" name="myfile" id="myfile" /><br /><br />
<input type="submit" value="Submit File"/>
</fieldset>
</form>
</body>
</html>'
Notice the ‘enctype’. It is required for file uploads. Also, the .rb.cgi extension is because XAMPP will recognize .cgi - and I will recognize .rb - without extra configuration.
The reason this is in ruby, instead of only xhtml, is because the full file shows the results of the parsing after the file has been submitted.
Now for parse.rb.cgi:
#!"\ruby\bin\ruby.exe"
require 'cgi' #POST
require 'stringio' #treat files like strings
require 'FileUtils' #local copy for command line usage
#####################################
installed_dir = "/xampp/htdocs/parsed/"
fromfile = ""
fromfilename = ""
tofile = ""
#####################################
# Move file
# ARGV.empty? - using cgi form
# !ARGV.empty? - using command line
#####################################
# if being called from apache
if (ARGV.empty?)
# save file posted by form locally
# copy the file - 'wb' is write in binary mode (IMPORTANT FOR WINDOWS)
cgi = CGI.new()
fromfile = cgi.params['myfile'].first
fromfilename = fromfile.original_filename
tofile = installed_dir + fromfilename
File.open(tofile, ‘wb’) { |file| file.write(fromfile.read) }
else
# copy file form local location to current directory
fromfile = ARGV[0].gsub(/[A-Za-z]:\\/, ‘/’).gsub(/\\/, ‘/’)
puts
puts fromfile
fromfilename = fromfile.split(/\//)[-1]
tofile = installed_dir + fromfilename
FileUtils.cp(fromfile, tofile)
end
#####################################
# Do your processing Here
#######################################
# Return to upload form when done, id upload form was used
puts ‘Location: upload.rb.cgi’ if (ARGV.empty?)
puts
‘wb’ - write in binary mode - is extremely important for uploading binary files, which I am. ‘fromfile = ARGV[0]‘ lets you use normal windows paths/tab completion from the command line.
-Sud.
Posted in Ruby |