fsws 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +21 -21
- data/README.md +18 -18
- data/bin/fsws +6 -26
- data/lib/fsws/cli.rb +62 -0
- data/lib/fsws/mime.types +110 -110
- data/lib/fsws/server.rb +97 -97
- data/lib/fsws/version.rb +3 -3
- data/lib/fsws/views/404.erb +11 -11
- data/lib/fsws/views/listing.erb +25 -25
- data/lib/fsws/views/style.css +31 -31
- data/lib/fsws.rb +2 -2
- metadata +11 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0bcba62b0f3352750ea47492c3fc24530e4d9cc5
|
4
|
+
data.tar.gz: 461d4f3023eaab7c1b86ce83523677b267596d5d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: efce146634e3c9b9ac18eab213d975b9c602c36956207112222b346d9daba36f393ec5e59936256ff206dd4d21487d2cf91dc71c277dc7caf7baabc17a4aff7f
|
7
|
+
data.tar.gz: d536d27a44d18e1c614794f127c65de3f6bf0e1367e00c9b3f0bf82cfab51fdde37e6ae9c3b7870b89299e2ac903cb6f4f51e7e8771627905d0c2457e4cea4ce
|
data/LICENSE
CHANGED
@@ -1,21 +1,21 @@
|
|
1
|
-
The MIT License (MIT)
|
2
|
-
|
3
|
-
Copyright (c) 2014 Chris Schmich
|
4
|
-
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
7
|
-
in the Software without restriction, including without limitation the rights
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
10
|
-
furnished to do so, subject to the following conditions:
|
11
|
-
|
12
|
-
The above copyright notice and this permission notice shall be included in
|
13
|
-
all copies or substantial portions of the Software.
|
14
|
-
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
-
THE SOFTWARE.
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 Chris Schmich
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,18 +1,18 @@
|
|
1
|
-
# fsws
|
2
|
-
|
3
|
-
A simple Ruby-based file system web server for serving static files from a directory.
|
4
|
-
|
5
|
-
## Usage
|
6
|
-
|
7
|
-
```
|
8
|
-
$ gem install fsws
|
9
|
-
$ fsws
|
10
|
-
```
|
11
|
-
|
12
|
-
This starts a web server for files in the current directory.
|
13
|
-
|
14
|
-
## License
|
15
|
-
|
16
|
-
Copyright © 2014 Chris Schmich
|
17
|
-
<br />
|
18
|
-
MIT License
|
1
|
+
# fsws
|
2
|
+
|
3
|
+
A simple Ruby-based file system web server for serving static files from a directory.
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
```
|
8
|
+
$ gem install fsws
|
9
|
+
$ fsws
|
10
|
+
```
|
11
|
+
|
12
|
+
This starts a web server for files in the current directory.
|
13
|
+
|
14
|
+
## License
|
15
|
+
|
16
|
+
Copyright © 2014 Chris Schmich
|
17
|
+
<br />
|
18
|
+
MIT License. See [LICENSE](LICENSE) for details.
|
data/bin/fsws
CHANGED
@@ -1,26 +1,6 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'fsws'
|
4
|
-
require '
|
5
|
-
|
6
|
-
|
7
|
-
port = (ARGV[0] || 8000).to_i
|
8
|
-
interface = '0.0.0.0'
|
9
|
-
|
10
|
-
Thin::Logging.silent = true
|
11
|
-
server = Thin::Server.new(interface, port, Fsws::server, signals: false)
|
12
|
-
|
13
|
-
Signal.trap('QUIT') do
|
14
|
-
puts 'Stopping...'
|
15
|
-
server.stop
|
16
|
-
end
|
17
|
-
|
18
|
-
Signal.trap('INT') do
|
19
|
-
puts 'Stopping...'
|
20
|
-
server.stop!
|
21
|
-
end
|
22
|
-
|
23
|
-
puts '>>'.cyan + " Serving #{Dir.pwd}"
|
24
|
-
puts '>>'.cyan + " Listening on #{interface}:#{port}"
|
25
|
-
puts '>>'.cyan + " Ctrl+C to stop"
|
26
|
-
server.start
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'fsws'
|
4
|
+
require 'fsws/cli'
|
5
|
+
|
6
|
+
Fsws::CommandLine.start(ARGV)
|
data/lib/fsws/cli.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'rack'
|
2
|
+
require 'webrick'
|
3
|
+
require 'thor'
|
4
|
+
|
5
|
+
module Fsws
|
6
|
+
class CommandLine < Thor
|
7
|
+
desc '[-h|--host <host>] [-p|--port <port>]', 'Start server.'
|
8
|
+
option :port, :type => :numeric, :aliases => :p
|
9
|
+
option :host, type: :string, aliases: :host
|
10
|
+
option :version, type: :boolean, aliases: :v
|
11
|
+
def start
|
12
|
+
if options[:version]
|
13
|
+
version
|
14
|
+
return
|
15
|
+
end
|
16
|
+
|
17
|
+
port = options[:port] || 8000
|
18
|
+
interface = options[:host] || '127.0.0.1'
|
19
|
+
|
20
|
+
if Signal.list.key? 'QUIT'
|
21
|
+
Signal.trap('QUIT') do
|
22
|
+
puts 'Stopping...'
|
23
|
+
Rack::Handler::WEBrick.shutdown
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
if Signal.list.key? 'INT'
|
28
|
+
Signal.trap('INT') do
|
29
|
+
puts 'Stopping...'
|
30
|
+
Rack::Handler::WEBrick.shutdown
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
puts ">> Serving #{normalize(Dir.pwd)}"
|
35
|
+
puts ">> Listening on #{interface}:#{port}"
|
36
|
+
puts ">> Ctrl+C to stop"
|
37
|
+
|
38
|
+
rd, wr = IO.pipe
|
39
|
+
opts = {
|
40
|
+
BindAddress: interface,
|
41
|
+
Port: port,
|
42
|
+
Logger: WEBrick::Log.new(wr),
|
43
|
+
AccessLog: []
|
44
|
+
}
|
45
|
+
|
46
|
+
Rack::Handler::WEBrick.run(Fsws::server, opts)
|
47
|
+
end
|
48
|
+
|
49
|
+
desc '-v|--version', 'Print version.'
|
50
|
+
def version
|
51
|
+
puts "fsws #{Fsws::VERSION}"
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def normalize(path)
|
57
|
+
path.gsub(File::SEPARATOR, File::ALT_SEPARATOR || File::SEPARATOR)
|
58
|
+
end
|
59
|
+
|
60
|
+
default_task :start
|
61
|
+
end
|
62
|
+
end
|
data/lib/fsws/mime.types
CHANGED
@@ -1,110 +1,110 @@
|
|
1
|
-
# From https://github.com/h5bp/server-configs-nginx/blob/master/mime.types
|
2
|
-
types {
|
3
|
-
|
4
|
-
# Audio
|
5
|
-
audio/midi mid midi kar;
|
6
|
-
audio/mp4 aac f4a f4b m4a;
|
7
|
-
audio/mpeg mp3;
|
8
|
-
audio/ogg oga ogg;
|
9
|
-
audio/x-realaudio ra;
|
10
|
-
audio/x-wav wav;
|
11
|
-
|
12
|
-
# Images
|
13
|
-
image/bmp bmp;
|
14
|
-
image/gif gif;
|
15
|
-
image/jpeg jpeg jpg;
|
16
|
-
image/png png;
|
17
|
-
image/tiff tif tiff;
|
18
|
-
image/vnd.wap.wbmp wbmp;
|
19
|
-
image/webp webp;
|
20
|
-
image/x-icon ico cur;
|
21
|
-
image/x-jng jng;
|
22
|
-
|
23
|
-
# JavaScript
|
24
|
-
application/javascript js;
|
25
|
-
application/json json;
|
26
|
-
|
27
|
-
# Manifest files
|
28
|
-
application/x-web-app-manifest+json webapp;
|
29
|
-
text/cache-manifest manifest appcache;
|
30
|
-
|
31
|
-
# Microsoft Office
|
32
|
-
application/msword doc;
|
33
|
-
application/vnd.ms-excel xls;
|
34
|
-
application/vnd.ms-powerpoint ppt;
|
35
|
-
application/vnd.openxmlformats-officedocument.wordprocessingml.document docx;
|
36
|
-
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx;
|
37
|
-
application/vnd.openxmlformats-officedocument.presentationml.presentation pptx;
|
38
|
-
|
39
|
-
# Video
|
40
|
-
video/3gpp 3gpp 3gp;
|
41
|
-
video/mp4 mp4 m4v f4v f4p;
|
42
|
-
video/mpeg mpeg mpg;
|
43
|
-
video/ogg ogv;
|
44
|
-
video/quicktime mov;
|
45
|
-
video/webm webm;
|
46
|
-
video/x-flv flv;
|
47
|
-
video/x-mng mng;
|
48
|
-
video/x-ms-asf asx asf;
|
49
|
-
video/x-ms-wmv wmv;
|
50
|
-
video/x-msvideo avi;
|
51
|
-
|
52
|
-
# Web feeds
|
53
|
-
application/xml atom rdf rss xml;
|
54
|
-
|
55
|
-
# Web fonts
|
56
|
-
application/font-woff woff;
|
57
|
-
application/font-woff2 woff2;
|
58
|
-
application/vnd.ms-fontobject eot;
|
59
|
-
application/x-font-ttf ttc ttf;
|
60
|
-
font/opentype otf;
|
61
|
-
image/svg+xml svg svgz;
|
62
|
-
|
63
|
-
# Other
|
64
|
-
application/java-archive jar war ear;
|
65
|
-
application/mac-binhex40 hqx;
|
66
|
-
application/pdf pdf;
|
67
|
-
application/postscript ps eps ai;
|
68
|
-
application/rtf rtf;
|
69
|
-
application/vnd.wap.wmlc wmlc;
|
70
|
-
application/xhtml+xml xhtml;
|
71
|
-
application/vnd.google-earth.kml+xml kml;
|
72
|
-
application/vnd.google-earth.kmz kmz;
|
73
|
-
application/x-7z-compressed 7z;
|
74
|
-
application/x-chrome-extension crx;
|
75
|
-
application/x-opera-extension oex;
|
76
|
-
application/x-xpinstall xpi;
|
77
|
-
application/x-cocoa cco;
|
78
|
-
application/x-java-archive-diff jardiff;
|
79
|
-
application/x-java-jnlp-file jnlp;
|
80
|
-
application/x-makeself run;
|
81
|
-
application/x-perl pl pm;
|
82
|
-
application/x-pilot prc pdb;
|
83
|
-
application/x-rar-compressed rar;
|
84
|
-
application/x-redhat-package-manager rpm;
|
85
|
-
application/x-sea sea;
|
86
|
-
application/x-shockwave-flash swf;
|
87
|
-
application/x-stuffit sit;
|
88
|
-
application/x-tcl tcl tk;
|
89
|
-
application/x-x509-ca-cert der pem crt;
|
90
|
-
application/x-bittorrent torrent;
|
91
|
-
application/zip zip;
|
92
|
-
|
93
|
-
application/octet-stream bin exe dll;
|
94
|
-
application/octet-stream deb;
|
95
|
-
application/octet-stream dmg;
|
96
|
-
application/octet-stream iso img;
|
97
|
-
application/octet-stream msi msp msm;
|
98
|
-
application/octet-stream safariextz;
|
99
|
-
|
100
|
-
text/css css;
|
101
|
-
text/html html htm shtml;
|
102
|
-
text/mathml mml;
|
103
|
-
text/plain txt;
|
104
|
-
text/vnd.sun.j2me.app-descriptor jad;
|
105
|
-
text/vnd.wap.wml wml;
|
106
|
-
text/vtt vtt;
|
107
|
-
text/x-component htc;
|
108
|
-
text/x-vcard vcf;
|
109
|
-
|
110
|
-
}
|
1
|
+
# From https://github.com/h5bp/server-configs-nginx/blob/master/mime.types
|
2
|
+
types {
|
3
|
+
|
4
|
+
# Audio
|
5
|
+
audio/midi mid midi kar;
|
6
|
+
audio/mp4 aac f4a f4b m4a;
|
7
|
+
audio/mpeg mp3;
|
8
|
+
audio/ogg oga ogg;
|
9
|
+
audio/x-realaudio ra;
|
10
|
+
audio/x-wav wav;
|
11
|
+
|
12
|
+
# Images
|
13
|
+
image/bmp bmp;
|
14
|
+
image/gif gif;
|
15
|
+
image/jpeg jpeg jpg;
|
16
|
+
image/png png;
|
17
|
+
image/tiff tif tiff;
|
18
|
+
image/vnd.wap.wbmp wbmp;
|
19
|
+
image/webp webp;
|
20
|
+
image/x-icon ico cur;
|
21
|
+
image/x-jng jng;
|
22
|
+
|
23
|
+
# JavaScript
|
24
|
+
application/javascript js;
|
25
|
+
application/json json;
|
26
|
+
|
27
|
+
# Manifest files
|
28
|
+
application/x-web-app-manifest+json webapp;
|
29
|
+
text/cache-manifest manifest appcache;
|
30
|
+
|
31
|
+
# Microsoft Office
|
32
|
+
application/msword doc;
|
33
|
+
application/vnd.ms-excel xls;
|
34
|
+
application/vnd.ms-powerpoint ppt;
|
35
|
+
application/vnd.openxmlformats-officedocument.wordprocessingml.document docx;
|
36
|
+
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx;
|
37
|
+
application/vnd.openxmlformats-officedocument.presentationml.presentation pptx;
|
38
|
+
|
39
|
+
# Video
|
40
|
+
video/3gpp 3gpp 3gp;
|
41
|
+
video/mp4 mp4 m4v f4v f4p;
|
42
|
+
video/mpeg mpeg mpg;
|
43
|
+
video/ogg ogv;
|
44
|
+
video/quicktime mov;
|
45
|
+
video/webm webm;
|
46
|
+
video/x-flv flv;
|
47
|
+
video/x-mng mng;
|
48
|
+
video/x-ms-asf asx asf;
|
49
|
+
video/x-ms-wmv wmv;
|
50
|
+
video/x-msvideo avi;
|
51
|
+
|
52
|
+
# Web feeds
|
53
|
+
application/xml atom rdf rss xml;
|
54
|
+
|
55
|
+
# Web fonts
|
56
|
+
application/font-woff woff;
|
57
|
+
application/font-woff2 woff2;
|
58
|
+
application/vnd.ms-fontobject eot;
|
59
|
+
application/x-font-ttf ttc ttf;
|
60
|
+
font/opentype otf;
|
61
|
+
image/svg+xml svg svgz;
|
62
|
+
|
63
|
+
# Other
|
64
|
+
application/java-archive jar war ear;
|
65
|
+
application/mac-binhex40 hqx;
|
66
|
+
application/pdf pdf;
|
67
|
+
application/postscript ps eps ai;
|
68
|
+
application/rtf rtf;
|
69
|
+
application/vnd.wap.wmlc wmlc;
|
70
|
+
application/xhtml+xml xhtml;
|
71
|
+
application/vnd.google-earth.kml+xml kml;
|
72
|
+
application/vnd.google-earth.kmz kmz;
|
73
|
+
application/x-7z-compressed 7z;
|
74
|
+
application/x-chrome-extension crx;
|
75
|
+
application/x-opera-extension oex;
|
76
|
+
application/x-xpinstall xpi;
|
77
|
+
application/x-cocoa cco;
|
78
|
+
application/x-java-archive-diff jardiff;
|
79
|
+
application/x-java-jnlp-file jnlp;
|
80
|
+
application/x-makeself run;
|
81
|
+
application/x-perl pl pm;
|
82
|
+
application/x-pilot prc pdb;
|
83
|
+
application/x-rar-compressed rar;
|
84
|
+
application/x-redhat-package-manager rpm;
|
85
|
+
application/x-sea sea;
|
86
|
+
application/x-shockwave-flash swf;
|
87
|
+
application/x-stuffit sit;
|
88
|
+
application/x-tcl tcl tk;
|
89
|
+
application/x-x509-ca-cert der pem crt;
|
90
|
+
application/x-bittorrent torrent;
|
91
|
+
application/zip zip;
|
92
|
+
|
93
|
+
application/octet-stream bin exe dll;
|
94
|
+
application/octet-stream deb;
|
95
|
+
application/octet-stream dmg;
|
96
|
+
application/octet-stream iso img;
|
97
|
+
application/octet-stream msi msp msm;
|
98
|
+
application/octet-stream safariextz;
|
99
|
+
|
100
|
+
text/css css;
|
101
|
+
text/html html htm shtml;
|
102
|
+
text/mathml mml;
|
103
|
+
text/plain txt;
|
104
|
+
text/vnd.sun.j2me.app-descriptor jad;
|
105
|
+
text/vnd.wap.wml wml;
|
106
|
+
text/vtt vtt;
|
107
|
+
text/x-component htc;
|
108
|
+
text/x-vcard vcf;
|
109
|
+
|
110
|
+
}
|
data/lib/fsws/server.rb
CHANGED
@@ -1,97 +1,97 @@
|
|
1
|
-
require 'rack'
|
2
|
-
require 'erb'
|
3
|
-
require 'pathname'
|
4
|
-
require 'ostruct'
|
5
|
-
|
6
|
-
def mime_types
|
7
|
-
return @mime_types if @mime_types
|
8
|
-
|
9
|
-
@mime_types = {}
|
10
|
-
|
11
|
-
path = File.join(File.dirname(__FILE__), 'mime.types')
|
12
|
-
File.open(path, 'r') do |file|
|
13
|
-
file.each_line do |line|
|
14
|
-
if line =~ /^\s*([\w\/.-]+)\s*((\w+\s*)+);\s*$/
|
15
|
-
mime_type = $1.strip
|
16
|
-
extensions = $2.strip.split.map(&:strip).map(&:downcase)
|
17
|
-
for ext in extensions
|
18
|
-
@mime_types[ext] = mime_type.downcase
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
@mime_types
|
25
|
-
end
|
26
|
-
|
27
|
-
def serve(env)
|
28
|
-
path = env['REQUEST_PATH'] || ''
|
29
|
-
path = '/' if path.empty?
|
30
|
-
path = '.' + path
|
31
|
-
|
32
|
-
return error(env) if !allowed?(path)
|
33
|
-
|
34
|
-
return serve_file(path) || serve_dir(path) || error(env)
|
35
|
-
end
|
36
|
-
|
37
|
-
def serve_file(path)
|
38
|
-
return nil if !File.file? path
|
39
|
-
|
40
|
-
ext = File.extname(path)
|
41
|
-
ext = ext[1...ext.length]
|
42
|
-
mime_type = mime_types[ext] || 'text/plain'
|
43
|
-
|
44
|
-
return 200, { 'Content-Type' => mime_type }, File.open(path, 'rb').read
|
45
|
-
end
|
46
|
-
|
47
|
-
def serve_dir(path)
|
48
|
-
return nil if !File.directory? path
|
49
|
-
|
50
|
-
for file in %w(index.html index.htm)
|
51
|
-
index = File.join(path, file)
|
52
|
-
page = serve_file(index)
|
53
|
-
return page if page
|
54
|
-
end
|
55
|
-
|
56
|
-
return redirect(path + '/') if !path.end_with?('/')
|
57
|
-
|
58
|
-
dirs, files = Dir.entries(path).partition { |e| File.directory?(File.join(path, e)) }
|
59
|
-
dirs.delete('.')
|
60
|
-
dirs.sort!
|
61
|
-
files.sort!
|
62
|
-
|
63
|
-
pwd = Pathname.new('/' + Pathname.new(File.absolute_path(path)).relative_path_from(Pathname.new(File.absolute_path(Dir.pwd))).to_s).cleanpath
|
64
|
-
|
65
|
-
return 200, { 'Content-Type' => 'text/html' }, erb('listing', dirs: dirs, files: files, pwd: pwd)
|
66
|
-
end
|
67
|
-
|
68
|
-
def erb(view, vars)
|
69
|
-
ERB.new(File.read(File.join(File.dirname(__FILE__), "views/#{view}.erb")))
|
70
|
-
.result(OpenStruct.new(vars).instance_eval { binding })
|
71
|
-
end
|
72
|
-
|
73
|
-
def error(env)
|
74
|
-
return 404, nil, erb('404', path: env['REQUEST_PATH'])
|
75
|
-
end
|
76
|
-
|
77
|
-
def redirect(path)
|
78
|
-
return 301, { 'Location' => path }, nil
|
79
|
-
end
|
80
|
-
|
81
|
-
def allowed?(path)
|
82
|
-
target = File.absolute_path(path)
|
83
|
-
return target.start_with?(File.absolute_path(Dir.pwd))
|
84
|
-
end
|
85
|
-
|
86
|
-
def include(file)
|
87
|
-
File.read(File.join(File.dirname(__FILE__), file))
|
88
|
-
end
|
89
|
-
|
90
|
-
module Fsws
|
91
|
-
def self.server
|
92
|
-
Proc.new do |env|
|
93
|
-
code, headers, body = serve(env)
|
94
|
-
[code.to_s, headers, [body]]
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
1
|
+
require 'rack'
|
2
|
+
require 'erb'
|
3
|
+
require 'pathname'
|
4
|
+
require 'ostruct'
|
5
|
+
|
6
|
+
def mime_types
|
7
|
+
return @mime_types if @mime_types
|
8
|
+
|
9
|
+
@mime_types = {}
|
10
|
+
|
11
|
+
path = File.join(File.dirname(__FILE__), 'mime.types')
|
12
|
+
File.open(path, 'r') do |file|
|
13
|
+
file.each_line do |line|
|
14
|
+
if line =~ /^\s*([\w\/.-]+)\s*((\w+\s*)+);\s*$/
|
15
|
+
mime_type = $1.strip
|
16
|
+
extensions = $2.strip.split.map(&:strip).map(&:downcase)
|
17
|
+
for ext in extensions
|
18
|
+
@mime_types[ext] = mime_type.downcase
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
@mime_types
|
25
|
+
end
|
26
|
+
|
27
|
+
def serve(env)
|
28
|
+
path = env['REQUEST_PATH'] || ''
|
29
|
+
path = '/' if path.empty?
|
30
|
+
path = '.' + path
|
31
|
+
|
32
|
+
return error(env) if !allowed?(path)
|
33
|
+
|
34
|
+
return serve_file(path) || serve_dir(path) || error(env)
|
35
|
+
end
|
36
|
+
|
37
|
+
def serve_file(path)
|
38
|
+
return nil if !File.file? path
|
39
|
+
|
40
|
+
ext = File.extname(path)
|
41
|
+
ext = ext[1...ext.length]
|
42
|
+
mime_type = mime_types[ext] || 'text/plain'
|
43
|
+
|
44
|
+
return 200, { 'Content-Type' => mime_type }, File.open(path, 'rb').read
|
45
|
+
end
|
46
|
+
|
47
|
+
def serve_dir(path)
|
48
|
+
return nil if !File.directory? path
|
49
|
+
|
50
|
+
for file in %w(index.html index.htm)
|
51
|
+
index = File.join(path, file)
|
52
|
+
page = serve_file(index)
|
53
|
+
return page if page
|
54
|
+
end
|
55
|
+
|
56
|
+
return redirect(path + '/') if !path.end_with?('/')
|
57
|
+
|
58
|
+
dirs, files = Dir.entries(path).partition { |e| File.directory?(File.join(path, e)) }
|
59
|
+
dirs.delete('.')
|
60
|
+
dirs.sort!
|
61
|
+
files.sort!
|
62
|
+
|
63
|
+
pwd = Pathname.new('/' + Pathname.new(File.absolute_path(path)).relative_path_from(Pathname.new(File.absolute_path(Dir.pwd))).to_s).cleanpath
|
64
|
+
|
65
|
+
return 200, { 'Content-Type' => 'text/html' }, erb('listing', dirs: dirs, files: files, pwd: pwd)
|
66
|
+
end
|
67
|
+
|
68
|
+
def erb(view, vars)
|
69
|
+
ERB.new(File.read(File.join(File.dirname(__FILE__), "views/#{view}.erb")))
|
70
|
+
.result(OpenStruct.new(vars).instance_eval { binding })
|
71
|
+
end
|
72
|
+
|
73
|
+
def error(env)
|
74
|
+
return 404, nil, erb('404', path: env['REQUEST_PATH'])
|
75
|
+
end
|
76
|
+
|
77
|
+
def redirect(path)
|
78
|
+
return 301, { 'Location' => path }, nil
|
79
|
+
end
|
80
|
+
|
81
|
+
def allowed?(path)
|
82
|
+
target = File.absolute_path(path)
|
83
|
+
return target.start_with?(File.absolute_path(Dir.pwd))
|
84
|
+
end
|
85
|
+
|
86
|
+
def include(file)
|
87
|
+
File.read(File.join(File.dirname(__FILE__), file))
|
88
|
+
end
|
89
|
+
|
90
|
+
module Fsws
|
91
|
+
def self.server
|
92
|
+
Proc.new do |env|
|
93
|
+
code, headers, body = serve(env)
|
94
|
+
[code.to_s, headers, [body]]
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
data/lib/fsws/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
module Fsws
|
2
|
-
VERSION = '0.0.
|
3
|
-
end
|
1
|
+
module Fsws
|
2
|
+
VERSION = '0.0.3'
|
3
|
+
end
|
data/lib/fsws/views/404.erb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
<html>
|
2
|
-
<head>
|
3
|
-
<title>404 Not Found</title>
|
4
|
-
<style type="text/css">
|
5
|
-
<%= include 'views/style.css' %>
|
6
|
-
</style>
|
7
|
-
</head>
|
8
|
-
<body>
|
9
|
-
<h1>404 Not Found: <%= path %></h1>
|
10
|
-
</body>
|
11
|
-
</html>
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title>404 Not Found</title>
|
4
|
+
<style type="text/css">
|
5
|
+
<%= include 'views/style.css' %>
|
6
|
+
</style>
|
7
|
+
</head>
|
8
|
+
<body>
|
9
|
+
<h1>404 Not Found: <%= path %></h1>
|
10
|
+
</body>
|
11
|
+
</html>
|
data/lib/fsws/views/listing.erb
CHANGED
@@ -1,25 +1,25 @@
|
|
1
|
-
<html>
|
2
|
-
<head>
|
3
|
-
<title>Index of <%= pwd %></title>
|
4
|
-
<style type="text/css">
|
5
|
-
<%= include 'views/style.css' %>
|
6
|
-
</style>
|
7
|
-
</head>
|
8
|
-
<body>
|
9
|
-
<h1>Index of <%= pwd %></h1>
|
10
|
-
<% if !dirs.empty? %>
|
11
|
-
<ul>
|
12
|
-
<% for dir in dirs %>
|
13
|
-
<li><a href="<%= dir %>/"><%= dir %>/</a></li>
|
14
|
-
<% end %>
|
15
|
-
</ul>
|
16
|
-
<% end %>
|
17
|
-
<% if !files.empty? %>
|
18
|
-
<ul>
|
19
|
-
<% for file in files %>
|
20
|
-
<li><a href="<%= file %>"><%= file %></a></li>
|
21
|
-
<% end %>
|
22
|
-
</ul>
|
23
|
-
<% end %>
|
24
|
-
</body>
|
25
|
-
</html>
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title>Index of <%= pwd %></title>
|
4
|
+
<style type="text/css">
|
5
|
+
<%= include 'views/style.css' %>
|
6
|
+
</style>
|
7
|
+
</head>
|
8
|
+
<body>
|
9
|
+
<h1>Index of <%= pwd %></h1>
|
10
|
+
<% if !dirs.empty? %>
|
11
|
+
<ul>
|
12
|
+
<% for dir in dirs %>
|
13
|
+
<li><a href="<%= dir %>/"><%= dir %>/</a></li>
|
14
|
+
<% end %>
|
15
|
+
</ul>
|
16
|
+
<% end %>
|
17
|
+
<% if !files.empty? %>
|
18
|
+
<ul>
|
19
|
+
<% for file in files %>
|
20
|
+
<li><a href="<%= file %>"><%= file %></a></li>
|
21
|
+
<% end %>
|
22
|
+
</ul>
|
23
|
+
<% end %>
|
24
|
+
</body>
|
25
|
+
</html>
|
data/lib/fsws/views/style.css
CHANGED
@@ -1,31 +1,31 @@
|
|
1
|
-
body {
|
2
|
-
font: 20px Consolas, Monaco, monospace;
|
3
|
-
}
|
4
|
-
a {
|
5
|
-
text-decoration: none;
|
6
|
-
color: #555;
|
7
|
-
padding: 15px;
|
8
|
-
}
|
9
|
-
a:hover {
|
10
|
-
background: #e7e7f3;
|
11
|
-
color: #048;
|
12
|
-
}
|
13
|
-
h1 {
|
14
|
-
margin-bottom: 10px;
|
15
|
-
}
|
16
|
-
body {
|
17
|
-
margin: 10px;
|
18
|
-
}
|
19
|
-
ul {
|
20
|
-
list-style-type: none;
|
21
|
-
margin: 0;
|
22
|
-
padding: 0;
|
23
|
-
}
|
24
|
-
li {
|
25
|
-
background: #f3f3f3;
|
26
|
-
margin-bottom: 5px;
|
27
|
-
padding: 0;
|
28
|
-
}
|
29
|
-
li a {
|
30
|
-
display: block;
|
31
|
-
}
|
1
|
+
body {
|
2
|
+
font: 20px Consolas, Monaco, monospace;
|
3
|
+
}
|
4
|
+
a {
|
5
|
+
text-decoration: none;
|
6
|
+
color: #555;
|
7
|
+
padding: 15px;
|
8
|
+
}
|
9
|
+
a:hover {
|
10
|
+
background: #e7e7f3;
|
11
|
+
color: #048;
|
12
|
+
}
|
13
|
+
h1 {
|
14
|
+
margin-bottom: 10px;
|
15
|
+
}
|
16
|
+
body {
|
17
|
+
margin: 10px;
|
18
|
+
}
|
19
|
+
ul {
|
20
|
+
list-style-type: none;
|
21
|
+
margin: 0;
|
22
|
+
padding: 0;
|
23
|
+
}
|
24
|
+
li {
|
25
|
+
background: #f3f3f3;
|
26
|
+
margin-bottom: 5px;
|
27
|
+
padding: 0;
|
28
|
+
}
|
29
|
+
li a {
|
30
|
+
display: block;
|
31
|
+
}
|
data/lib/fsws.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
require 'fsws/server'
|
2
|
-
require 'fsws/version'
|
1
|
+
require 'fsws/server'
|
2
|
+
require 'fsws/version'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fsws
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Schmich
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-10-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -25,33 +25,19 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.5'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: thor
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ~>
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '0.19'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ~>
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: colorize
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ~>
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0.7'
|
48
|
-
type: :runtime
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ~>
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0.7'
|
40
|
+
version: '0.19'
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
42
|
name: rake
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -75,16 +61,17 @@ executables:
|
|
75
61
|
extensions: []
|
76
62
|
extra_rdoc_files: []
|
77
63
|
files:
|
78
|
-
-
|
79
|
-
- README.md
|
80
|
-
- bin/fsws
|
81
|
-
- lib/fsws.rb
|
64
|
+
- lib/fsws/cli.rb
|
82
65
|
- lib/fsws/mime.types
|
83
66
|
- lib/fsws/server.rb
|
84
67
|
- lib/fsws/version.rb
|
85
68
|
- lib/fsws/views/404.erb
|
86
69
|
- lib/fsws/views/listing.erb
|
87
70
|
- lib/fsws/views/style.css
|
71
|
+
- lib/fsws.rb
|
72
|
+
- bin/fsws
|
73
|
+
- README.md
|
74
|
+
- LICENSE
|
88
75
|
homepage: https://github.com/schmich/fsws
|
89
76
|
licenses:
|
90
77
|
- MIT
|
@@ -105,9 +92,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
105
92
|
version: '0'
|
106
93
|
requirements: []
|
107
94
|
rubyforge_project:
|
108
|
-
rubygems_version: 2.
|
95
|
+
rubygems_version: 2.0.14
|
109
96
|
signing_key:
|
110
97
|
specification_version: 4
|
111
98
|
summary: Ruby file system web server.
|
112
99
|
test_files: []
|
113
|
-
has_rdoc:
|