oddjob 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 38b952a30ef59eab2aecda48c84c792a02daff9e
4
+ data.tar.gz: 6d0f3456c227c1bef0888db3971a80671054ba1d
5
+ SHA512:
6
+ metadata.gz: 71b6164c4462f00a4e7c6cb6385eec124b2d13aea477301ae205d4aac46ed288293ada192acc5499bfa106963ee2edca41e422da83bcd6f54dac620c55c09ef8
7
+ data.tar.gz: aab8882dd01c9585ec228f6a3ba481f9f746b0e906345bbef4fd7f3ae00817ce74fde44c3e9a38feffba4b58bcd8cc340934b26538165a138c3f4af582b8b68b
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ *.swp
2
+ .ruby-version
3
+ .bundle
4
+ vendor
5
+ Gemfile.lock
6
+ pkg
7
+ doc
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Dependencies specified in oddjob.gemspec
4
+ gemspec
data/MIT-LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) Mike Fellows
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19
+ DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,147 @@
1
+ # oddjob #
2
+
3
+ oddjob is a lightweight, command line controlled web server. Built for
4
+ development and testing purposes, it can be used to serve static content for
5
+ local web development and has basic file upload capabilities. It was initially
6
+ created when web browsers become more restrictive about displaying local files
7
+ directly (*i.e.* file:// URLs).
8
+
9
+ oddjob's file upload endpoint can be used directly via forms or ajax request you
10
+ build yourself with a POST to the `/oj_upload` URL. A basic file upload form
11
+ is also available via a GET request to that same URL. Upon upload the default
12
+ behaviour is for the server to dump the entire upload POST request (header and
13
+ body), followed by the contents of each uploaded file to STDOUT. This is
14
+ useful for small tests uploading text files, but if you need to upload larger
15
+ or binary format files tell oddjob to save the files to a directory instead. If
16
+ you upload and save the same file twice oddjob will not overwrite existing
17
+ saved files, instead a unique name is generated by adding a number to the end
18
+ of the file's name.
19
+
20
+ It is easy to hack the oddjob script to build quick test jigs for web
21
+ development. Sometimes using a simple test web server is easier than working
22
+ with a full fledged development or production environment. To hack the code
23
+ download from the [github repo](https://github.com/MCF/oddjob) and run oddjob
24
+ out of the included `bin` directory.
25
+
26
+ ## Installation ##
27
+
28
+ oddjob is available as a ruby gem. To install it for general command line
29
+ use simply use gem like so:
30
+
31
+ ```sh
32
+ gem install oddjob
33
+ ```
34
+
35
+ In the unlikely event you would like it tied to a project add the following
36
+ line to the project's Gemfile:
37
+
38
+ ```ruby
39
+ gem 'oddjob'
40
+ ```
41
+
42
+ And then execute:
43
+
44
+ ```sh
45
+ bundle
46
+ ```
47
+
48
+ You can also run oddjob directly from the git repo. Clone the git repo and run
49
+ oddjob directly from the repo's bin directory.
50
+
51
+ ## Usage ##
52
+
53
+ Command line usage is:
54
+
55
+ ```
56
+ oddjob [OPTIONS] [server_root]
57
+ ```
58
+
59
+ Where the optional server_root argument will be the server's root directory.
60
+ The default server root is the current working directory.
61
+
62
+ The default file upload behaviour will print the contents of the HTTP POST
63
+ request, and the contents of any uploaded files, to the server's STDOUT. It is
64
+ recommended that you only upload text files in this case. If an output
65
+ directory is specified all uploaded files are saved under their own names in
66
+ this directory. Pre-existing files are not overwritten, instead a number is
67
+ added to the end of the new file names when saving.
68
+
69
+ If a simulated network delay is specified the server will pause that many
70
+ seconds before returning a response for file(s) uploaded to the file upload
71
+ path: `/oj_upload`.
72
+
73
+ The server will only respond to clients on localhost unless the `--allhosts`
74
+ option is specified. Be aware of the security implications of allowing any
75
+ other host on your network to connect to the server if you use this option.
76
+
77
+ An informational page is available at the `/oj_info` path that includes the
78
+ command line usage.
79
+
80
+ The default server port is 4400.
81
+
82
+ Command line options:
83
+
84
+ -d, --delay=value File upload simulated network delay
85
+ -a, --allhosts Allow connections from all hosts
86
+ -o, --output=value Directory to save uploaded files
87
+ -p, --port=value Web server port to use
88
+ --version Display the version number and exit
89
+
90
+ -h, --help Display the usage message
91
+
92
+ To stop oddjob use the normal interrupt key combination (usually Ctrl-C).
93
+
94
+ ## Examples ##
95
+
96
+ ```sh
97
+ oddjob
98
+ ```
99
+
100
+ Serves the files and directories in your current working directory at the
101
+ `http://localhost:4400/` URL. File upload is available at
102
+ `http://localhost:4400/oj_upload`
103
+
104
+ ```sh
105
+ oddjob -p 2222 -o ./uploads ./my-site
106
+ ```
107
+
108
+ Serves the contents of the `./my-site` directory at the
109
+ `http://localhost:2222/` URL, file upload is available at
110
+ `http://localhost:2222/oj_upload` files are saved to the
111
+ `./uploads` directory.
112
+
113
+ ## Environment ##
114
+
115
+ oddjob is written in ruby and its only required dependency is a standard ruby
116
+ install. oddjob makes use of the built in ruby's
117
+ [webrick](http://ruby-doc.org/stdlib-2.0.0/libdoc/webrick/rdoc/WEBrick.html)
118
+ web server library. No gems are required for running oddjob. oddjob has been
119
+ tested with ruby 1.8.7 and up.
120
+
121
+ ## Security ##
122
+
123
+ By default oddjob serves to clients on localhost only (that is: browsers
124
+ running on the same computer as oddjob). If the `-a` option is used connections
125
+ from any client on your network are allowed. If you do not trust the users on
126
+ your local network the `-a` option could be a security concern. Anyone who can
127
+ connect to your IP address can browse and download the files served by oddjob.
128
+
129
+ oddjob will serve the contents of the directory specified on the command line,
130
+ or the current working directory if no directory is specified. It does no
131
+ filtering on the contents of the directory served, and the entire directory
132
+ tree below the top level directory is available for browsing.
133
+
134
+ ## License ##
135
+
136
+ oddjob is released under an [MIT style license](MIT-LICENSE).
137
+
138
+ ## Development ##
139
+
140
+ After checking out the repo, run `bundle install` to install dependencies. Then, run
141
+ `rake spec` to run the tests. Oddjob can be run directly from the repo's bin
142
+ directory for easy testing.
143
+
144
+ ## Contributing ##
145
+
146
+ Bug reports and pull requests are welcome on GitHub at
147
+ https://github.com/MCF/oddjob.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/oddjob ADDED
@@ -0,0 +1,151 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #--
4
+ # Copyright (c) Mike Fellows
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # of this software and associated documentation files (the "Software"), to deal
8
+ # in the Software without restriction, including without limitation the rights
9
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ # copies of the Software, and to permit persons to whom the Software is
11
+ # furnished to do so, subject to the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be included in
14
+ # all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
+ # DEALINGS IN THE SOFTWARE.
23
+ #++
24
+
25
+ begin
26
+ require 'rubygems' # Ruby 1.8.7 compatible.
27
+ gem 'rake'
28
+ rescue LoadError
29
+ end
30
+
31
+ begin
32
+ require 'oddjob' # Installed as a gem.
33
+ rescue LoadError
34
+ lib = File.expand_path('../lib', File.dirname( __FILE__))
35
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
36
+
37
+ require 'oddjob' # Simply run from the repo, no gems.
38
+ end
39
+
40
+ def show_version
41
+ STDOUT.puts("Version: #{OddJob::VERSION}")
42
+ exit
43
+ end
44
+
45
+ def error(msg, suggest_usage = false)
46
+ STDERR.puts("ERORR: #{msg}")
47
+ STDERR.puts(" try the -h option for the command usage") if suggest_usage
48
+ exit 1
49
+ end
50
+
51
+ require 'optparse'
52
+
53
+ opts = {}
54
+
55
+ optparser = OptionParser.new do |o|
56
+ o.banner = "Usage: #{File.basename($0)} [OPTIONS] [server_root]"
57
+ o.separator <<TXT
58
+
59
+ Where the optional server_root argument will be the server's root directory.
60
+ The default server root is the current working directory.
61
+
62
+ The default file upload behaviour will print the contents of the HTTP POST
63
+ request, and the contents of any uploaded files, to the server's STDOUT. It is
64
+ recommended that you only upload text files in this case. If an output
65
+ directory is specified all uploaded files are saved under their own names in
66
+ this directory. Pre-existing files are not overwritten, instead a number is
67
+ added to the end of the new file names when saving.
68
+
69
+ If a simulated network delay is specified the server will pause that many
70
+ seconds before returning a response for file(s) uploaded to the file upload
71
+ path: #{OddJob::UPLOAD_PATH}.
72
+
73
+ The server will only respond to clients on localhost unless the --allhosts
74
+ option is specified. Be aware of the security implications of allowing any
75
+ other host on your network to connect to the server if you use this option.
76
+
77
+ An informational page is available at the #{OddJob::INFO_PATH} path.
78
+
79
+ The default server port is #{OddJob::DEFAULT_PORT}.
80
+
81
+ To stop the server use the normal interrupt key combination (usually Ctrl-C).
82
+
83
+ TXT
84
+
85
+ o.on('-d', '--delay=value', Float,
86
+ 'File upload simulated network delay') { |x| opts[:networkdelay] = x }
87
+ o.on('-a', '--allhosts',
88
+ 'Allow connections from all hosts') { opts[:allowall] = true }
89
+ o.on('-o', '--output=value', String,
90
+ 'Directory to save uploaded files') { |x| opts[:savedirectory] = x }
91
+ o.on('-p', '--port=value', Integer,
92
+ "Web server port to use") { |x| opts[:port] = x }
93
+ o.on('--version',
94
+ 'Display the version number and exit') { show_version() }
95
+
96
+ o.separator("")
97
+
98
+ o.on('-h', '--help', 'Display this message') { puts(o); exit }
99
+ end
100
+
101
+ theRest = []
102
+ begin
103
+ theRest = optparser.parse(ARGV)
104
+ rescue
105
+ error($!.to_s, true)
106
+ end
107
+
108
+ error("too many arguments given", true) if theRest.size > 1
109
+
110
+ if theRest.size == 1
111
+ opts[:serverroot] = theRest.pop
112
+
113
+ unless File.directory?(opts[:serverroot])
114
+ error([
115
+ "directory to serve does not exist or is not ",
116
+ "a directory: #{opts[:serverroot]}"
117
+ ].join(''))
118
+ end
119
+
120
+ if opts[:savedirectory] and not File.directory?(opts[:savedirectory])
121
+ error([
122
+ "output directory does not exist or is not ",
123
+ "a directory: #{opts[:savedirectory]}"
124
+ ].join(''))
125
+ end
126
+ end
127
+
128
+ if opts.has_key?(:port) and (opts[:port] < 0 or opts[:port] > 65535)
129
+ error("port specified is invalid: #{opts[:port]}")
130
+ end
131
+
132
+ if opts.has_key?(:networkdelay) and opts[:networkdelay] < 0
133
+ error("simulated delay cannot be negative: #{opts[:networkdelay]}")
134
+ end
135
+
136
+ opts[:usagemessage] = optparser.to_s
137
+
138
+ begin
139
+ OddJob.server(opts)
140
+ rescue Errno::EADDRINUSE => e
141
+ error([
142
+ "Could not bind to the port because it is already in use, ",
143
+ "port: #{opts[:port].nil? ? OddJob::DEFAULT_PORT : opts[:port]}"
144
+ ].join("\n"))
145
+ rescue Errno::EACCES => e
146
+ error([
147
+ "Could not bind to the port due to insufficient permission, usually",
148
+ "this happens when a non root user attempts to use a privileged port",
149
+ "(between 1 and 1000). Port requested: #{opts[:port]}"
150
+ ].join("\n"))
151
+ end
@@ -0,0 +1,3 @@
1
+ module OddJob
2
+ VERSION = '1.6.0'
3
+ end
data/lib/oddjob.rb ADDED
@@ -0,0 +1,288 @@
1
+ #--
2
+ # Copyright (c) Mike Fellows
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20
+ # DEALINGS IN THE SOFTWARE.
21
+ #++
22
+
23
+ require 'webrick'
24
+ require 'oddjob/version'
25
+
26
+ module OddJob
27
+
28
+ UPLOAD_PATH = '/oj_upload'
29
+ INFO_PATH = '/oj_info'
30
+ DEFAULT_PORT = 4400
31
+
32
+ ##
33
+ # Start the oddjob server.
34
+ #
35
+ # +opts+ is a hash. Allowed keys are:
36
+ #
37
+ # * +:serverroot+ - directory to serve (default CWD)
38
+ # * +:savedirectory+ - where to save uploads (default dump to STDOUT)
39
+ # * +:usagemessage+ - the command line usage message to dispaly on info page
40
+ # * +:allowall+ - serve to clients other than on localhost? (default false)
41
+ # * +:networkdelay+ - simulated network delay (default no delay).
42
+ # * +:port+ - port to use. (default is in DEFAULT_PORT module constant)
43
+ #
44
+ # Runs the server until a TERM or INT signal is received (e.g. ctrl-c from
45
+ # the command line).
46
+ def OddJob.server(opts)
47
+ defaults = {
48
+ :serverroot => ".",
49
+ :savedirectory => nil,
50
+ :usagemessage => nil,
51
+ :allowall => false,
52
+ :networkdelay => 0,
53
+ :port => DEFAULT_PORT
54
+ }
55
+
56
+ options = defaults.merge(opts)
57
+
58
+ # Add any missing MIME types (http://bugs.ruby-lang.org/issues/5365)
59
+ m_types = WEBrick::HTTPUtils::DefaultMimeTypes.dup
60
+ m_types['js'] = 'application/javascript' unless m_types.has_key?('js')
61
+ m_types['svg'] = 'image/svg+xml' unless m_types.has_key?('svg')
62
+
63
+ server = WEBrick::HTTPServer.new(
64
+ :Port => options[:port],
65
+ :BindAddress => options[:allowall] ? '0.0.0.0' : '127.0.0.1',
66
+ :MimeTypes => m_types,
67
+ :DocumentRoot => options[:serverroot]
68
+ )
69
+
70
+ server.mount(
71
+ INFO_PATH,
72
+ Info,
73
+ options[:usagemessage]
74
+ )
75
+
76
+ server.mount(
77
+ UPLOAD_PATH,
78
+ FileUpload,
79
+ options[:networkdelay],
80
+ options[:savedirectory]
81
+ )
82
+
83
+ ['TERM', 'INT'].each { |signal| trap(signal){ server.shutdown } }
84
+
85
+ server.start
86
+ end
87
+
88
+ ##
89
+ # A very basic utility for rendering OddJob specific pages.
90
+
91
+ module HtmlRender
92
+
93
+ ##
94
+ # Wrap +content+ in the standard page layout. +title+ is set as the HTML
95
+ # page's title.
96
+ def page(content, title)
97
+ [
98
+ "<!DOCTYPE html>",
99
+ "<head>",
100
+ " <title>OJ #{title}</title>",
101
+ " <style>",
102
+ " body {font:100% arial,sans-serif; margin:1.5em 5em 4em 5em;}",
103
+ " a {text-decoration:none; color:rgb(248,157,30)}",
104
+ " a:hover {color:rgb(239,131,0);}",
105
+ " .header {font-size:0.75em; float:right; margin-bottom: 2.0em;}",
106
+ " </style>",
107
+ "</head>",
108
+ "<html><body>",
109
+ " <div class=\"header\">",
110
+ " <a href=\"https://github.com/MCF/oddjob\">OddJob on github</a>",
111
+ " </div>",
112
+ " <div style=\"clear:both;\"></div>",
113
+ content.kind_of?(Array) ? content.join("\n") : content,
114
+ "</body></html>",
115
+ ].join("\n")
116
+ end
117
+ end
118
+
119
+ ##
120
+ # Webrick servlet for creating the information page.
121
+
122
+ class Info < WEBrick::HTTPServlet::AbstractServlet
123
+ include HtmlRender
124
+
125
+ ##
126
+ # Standard servlet initialization function with an additional
127
+ # +cmd_usage+ argument for specifying the command line usage
128
+ # of the OddJob module's calling entity.
129
+ def initialize(server, cmd_usage, *options)
130
+ @usage = cmd_usage
131
+ super(server, options)
132
+ end
133
+
134
+ ##
135
+ # Respond to get request, returns informational page.
136
+ def do_GET(request, response)
137
+ response.status = 200
138
+ response['Content-Type'] = "text/html"
139
+ response.body = info_page
140
+ end
141
+
142
+ protected
143
+
144
+ ##
145
+ # Render the HTML for the informational page.
146
+ def info_page
147
+ html = [
148
+ " <h1>#{File.basename($0)}</h1>",
149
+ " <p>Version: <strong>#{VERSION}</strong></p>"
150
+ ]
151
+ html << " <pre>#{@usage}</pre>" unless @usage.nil?
152
+ page(html, "Info")
153
+ end
154
+
155
+ end
156
+
157
+ ##
158
+ # Webrick servlet for upload pages.
159
+
160
+ class FileUpload < WEBrick::HTTPServlet::AbstractServlet
161
+ include HtmlRender
162
+
163
+ ##
164
+ # Standard servlet initialization function with additional arguments.
165
+ #
166
+ # +delay+ is the seconds of simulated network delay to wait before
167
+ # responding after an upload request.
168
+ #
169
+ # +save_directory+ is the the directory location to save uploaded files.
170
+ # If +save_directory+ is set to nil uploaded files are not save, instead
171
+ # the entire http request is printed on STDOUT, followed by the name and
172
+ # contents of each file. Generally only useful for small and non-binary
173
+ # files.
174
+ def initialize(server, delay, save_directory, *options)
175
+ @simulated_delay = delay
176
+ @save_directory = save_directory
177
+ super(server, options)
178
+ end
179
+
180
+ ##
181
+ # Handles webrick post request when uploading one or more files via a
182
+ # standard HTML form submission. The form should include an input of type
183
+ # 'file'. See the page produced by the do_GET method for an example form.
184
+ def do_POST(request, response)
185
+
186
+ if @save_directory.nil? # Request to server STDOUT.
187
+ puts "-- BEGIN File Upload POST Request --"
188
+ puts request
189
+ puts "-- END File Upload POST Request --"
190
+ end
191
+
192
+ all_files = Array.new
193
+ ['file', 'file[]'].each do |name|
194
+ if request.query[name]
195
+ request.query[name].each_data do |data|
196
+
197
+ all_files.push(data.filename)
198
+
199
+ if @save_directory.nil? # File contents to server STDOUT.
200
+ puts "== BEGIN #{data.filename} Contents =="
201
+ puts data.to_s
202
+ puts "== END #{data.filename} Contents =="
203
+ else
204
+ output_name = unique_name(data.filename, @save_directory)
205
+ File.open(output_name, "w"){|f| f.print(data.to_s)}
206
+ puts "#{data.filename} uploaded, saved to #{output_name}"
207
+ end
208
+ end
209
+ end
210
+ end
211
+
212
+ response.status = 200
213
+ response['Content-type'] = 'text/html'
214
+ response.body = uploaded_page(all_files)
215
+
216
+ sleep(@simulated_delay)
217
+ end
218
+
219
+ ##
220
+ # Serves a simple file upload form. Uploads submitted are handled by this
221
+ # class' +do_Post+ method.
222
+ def do_GET(request, response)
223
+ response.status = 200
224
+ response['Content-type'] = 'text/html'
225
+ response.body = uploader_page
226
+ end
227
+
228
+ protected
229
+
230
+ ##
231
+ # Finds a unique name in the same directory for the given file.
232
+ #
233
+ # The uploaded file will be renamed if a file by that name already exists.
234
+ # An index number is added to the file's base name to make it unique. For
235
+ # example if test.txt already existed then test_1.txt would be checked,
236
+ # followed by test_2.txt, and so on.
237
+ def unique_name(desired_name, save_directory)
238
+ ext = File.extname(desired_name)
239
+ base = File.basename(desired_name, ext)
240
+
241
+ final_base = full_base = File.join(save_directory, base)
242
+ i = 1
243
+ while(File.exist?(final_base + ext))
244
+ final_base = "#{full_base}_#{i}"
245
+ i += 1
246
+ end
247
+
248
+ final_base + ext
249
+ end
250
+
251
+ ##
252
+ # Returns a string holding the full HTML page with the file upload form.
253
+ def uploader_page
254
+ html = [
255
+ "<h1>Uploader</h1>",
256
+ "<form action='' method='POST' enctype='multipart/form-data'>",
257
+ " <p>",
258
+ " Select file(s) to upload:",
259
+ " <br><br>",
260
+ " <input type='file' name='file' multiple='true'>",
261
+ " <br><br>",
262
+ " <input type='submit'>",
263
+ " </p>",
264
+ "</form>",
265
+ ]
266
+
267
+ page(html, "Uploader")
268
+ end
269
+
270
+ ##
271
+ # Returns a string holding the result of the upload page submission.
272
+ #
273
+ # +names+ is an array of the uploaded file names. These are names
274
+ # as submitted. Saved names may be different to avoid overwritting.
275
+ def uploaded_page(names)
276
+ html = [
277
+ "<h1>Results</h1>",
278
+ "<p>Uploaded:",
279
+ " <strong>#{names.join("</strong>, <strong>")}</strong>",
280
+ "</p>",
281
+ "<p><a href=''>Return to upload page</a></p>",
282
+ ]
283
+
284
+ page(html, "Upload Results")
285
+ end
286
+ end
287
+
288
+ end
data/oddjob.gemspec ADDED
@@ -0,0 +1,40 @@
1
+ # coding: utf-8
2
+
3
+ lib = File.expand_path('./lib', File.dirname( __FILE__))
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'oddjob/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'oddjob'
9
+ spec.version = OddJob::VERSION
10
+ spec.authors = ['Mike Fellows']
11
+ spec.email = ['Mike.Fellows@shaw.ca']
12
+
13
+ spec.summary = 'OddJob is simple command line driven web server'
14
+ spec.description = <<TXT
15
+ Oddjob is a simple command line driver web server, written in ruby and
16
+ utilizing ruby's built in web server webrick. It is meant to be a test and
17
+ development tool, suitable for static content from a local directory.
18
+
19
+ Oddjob also provides basic file upload capabilities (single or multi-file
20
+ upload). This includes the ability to save uploaded files locally.
21
+
22
+ As a stand alone application the server is quick and convenient application
23
+ for web developers working with static files. Or get a copy of the source and
24
+ add in new endpoints for simple tests as needed.
25
+ TXT
26
+
27
+ spec.homepage = 'https://github.com/MCF/oddjob'
28
+ spec.license = 'MIT'
29
+
30
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
31
+ spec.bindir = 'bin'
32
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
33
+ spec.require_paths = ['lib']
34
+ spec.extra_rdoc_files = ['README.md', 'MIT-LICENSE']
35
+ spec.rdoc_options = ['--main', 'README.md']
36
+
37
+ spec.add_development_dependency('bundler', '~> 1.10')
38
+ spec.add_development_dependency('rake', '~> 10.0')
39
+ spec.add_development_dependency('rspec')
40
+ end
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: oddjob
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.6.0
5
+ platform: ruby
6
+ authors:
7
+ - Mike Fellows
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-02-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.10'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: |
56
+ Oddjob is a simple command line driver web server, written in ruby and
57
+ utilizing ruby's built in web server webrick. It is meant to be a test and
58
+ development tool, suitable for static content from a local directory.
59
+
60
+ Oddjob also provides basic file upload capabilities (single or multi-file
61
+ upload). This includes the ability to save uploaded files locally.
62
+
63
+ As a stand alone application the server is quick and convenient application
64
+ for web developers working with static files. Or get a copy of the source and
65
+ add in new endpoints for simple tests as needed.
66
+ email:
67
+ - Mike.Fellows@shaw.ca
68
+ executables:
69
+ - oddjob
70
+ extensions: []
71
+ extra_rdoc_files:
72
+ - README.md
73
+ - MIT-LICENSE
74
+ files:
75
+ - ".gitignore"
76
+ - Gemfile
77
+ - MIT-LICENSE
78
+ - README.md
79
+ - Rakefile
80
+ - bin/oddjob
81
+ - lib/oddjob.rb
82
+ - lib/oddjob/version.rb
83
+ - oddjob.gemspec
84
+ homepage: https://github.com/MCF/oddjob
85
+ licenses:
86
+ - MIT
87
+ metadata: {}
88
+ post_install_message:
89
+ rdoc_options:
90
+ - "--main"
91
+ - README.md
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirements: []
105
+ rubyforge_project:
106
+ rubygems_version: 2.4.5
107
+ signing_key:
108
+ specification_version: 4
109
+ summary: OddJob is simple command line driven web server
110
+ test_files: []