class OddJob::FileUpload
Webrick servlet for upload pages.
Public Class Methods
Standard servlet initialization function with additional arguments.
delay
is the seconds of simulated network delay to wait before responding after an upload request.
save_directory
is the the directory location to save uploaded files. If save_directory
is set to nil uploaded files are not save, instead the entire http request is printed on STDOUT, followed by the name and contents of each file. Generally only useful for small and non-binary files.
# File lib/oddjob.rb, line 178 def initialize(server, delay, save_directory, *options) @simulated_delay = delay @save_directory = save_directory super(server, options) end
Public Instance Methods
Serves a simple file upload form. Uploads submitted are handled by this class’ do_Post
method.
# File lib/oddjob.rb, line 229 def do_GET(request, response) response.status = 200 response['Content-type'] = 'text/html' response.body = uploader_page end
Handles webrick post request when uploading one or more files via a standard HTML form submission. The form should include an input of type ‘file’. See the page produced by the do_GET
method for an example form.
# File lib/oddjob.rb, line 188 def do_POST(request, response) if @save_directory.nil? # Request to server STDOUT. puts "-- BEGIN File Upload POST Request --" puts request puts "-- END File Upload POST Request --" end all_uploads = Array.new ['file', 'file[]'].each do |name| if request.query[name] request.query[name].each_data do |data| upload = OpenStruct.new upload.name = data.filename if @save_directory.nil? # File contents to server STDOUT. puts "== BEGIN #{data.filename} Contents ==" puts data.to_s puts "== END #{data.filename} Contents ==" else output_name = unique_name(data.filename, @save_directory) File.open(output_name, "w"){|f| f.print(data.to_s)} puts "#{data.filename} uploaded, saved to #{output_name}" upload.output_name = File.expand_path(output_name) end all_uploads.push(upload) end end end response.status = 200 response['Content-type'] = 'text/html' response.body = uploaded_page(all_uploads) sleep(@simulated_delay) end
Protected Instance Methods
Finds a unique name in the same directory for the given file.
The uploaded file will be renamed if a file by that name already exists. An index number is added to the file’s base name to make it unique. For example if test.txt already existed then test_1.txt would be checked, followed by test_2.txt, and so on.
# File lib/oddjob.rb, line 244 def unique_name(desired_name, save_directory) ext = File.extname(desired_name) base = File.basename(desired_name, ext) final_base = full_base = File.join(save_directory, base) i = 1 while File.exist?(final_base + ext) final_base = "#{full_base}_#{i}" i += 1 end final_base + ext end
Returns a string holding the result of the upload page submission.
names
is an array of the uploaded file names. These are names as submitted. Saved names may be different to avoid overwritting.
# File lib/oddjob.rb, line 306 def uploaded_page(uploads) html = [ "<h2>Results</h2>", "<p>Uploaded:</p>", "<ul>", ] uploads.each do |upload| html += [ "<li>", "<strong>#{upload.name}</strong>", upload.output_name ? " - saved to: #{upload.output_name}" : "", "</li>", ] end html += [ "</ul>", "<p><a href=''>Return to upload page</a></p>", ] page(html, "Upload Results") end
Returns a string holding the full HTML page with the file upload form.
# File lib/oddjob.rb, line 260 def uploader_page html = [ "<h2>Oddjob File Uploader</h2>", "<form action='' method='POST' enctype='multipart/form-data'>", " <label for='file'>Select one or more files to upload:</label>", " <br><br>", " <input type='file' name='file' multiple='true'>", " <br><br>", " <input type='submit' value='Upload'>", "</form>", "<br>", ] if @save_directory.nil? html += [ "<p class=\"fineprint\">", "Currently file uploads will <strong>not</strong> be saved, instead", "their contents will be printed to oddjob's standard output.", "In this configuration it is recommended that you only upload", "text files.", "</p>", "<p class=\"fineprint\">", "To upload any kind of file (binary or text) specify an output", "directory where files will be saved instead. To see how visit the", "<a href=\"#{INFO_PATH}\">info page</a>.", "</p>", ] else html += [ "<p class=\"fineprint\">", "Uploaded files will be saved in the", "<strong>#{File.expand_path(@save_directory)}</strong> directory.", "New files do not overwrite existing ones, instead they are given", "a unique numbered suffix.", "</p>", ] end page(html, "Uploader") end