tiny_ruby_server 0.1

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: 3b41e06e5d2a0614dc1d97de394ba4a925a5ed0e
4
+ data.tar.gz: 8ac6127db498dbb191aaaa4c0dd3944951f1c680
5
+ SHA512:
6
+ metadata.gz: 3ee1ba0e6780c4e7fbd5b0b4168319847d2ab657dc36f86c8afec2a8f07561c60531a78106aa44539dd09b50a6944de8de689c088d17a3e6eac4d200ce1d1e89
7
+ data.tar.gz: c0e3f26350627154db3e09b005feffa6f8da11d303f457739a39e0c527c62eb92011e126810946c7f4b3bcb15836afbc39c5bd6e36dbb1a863c48f986b2bc5f6
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ .ruby-gemset
2
+ .ruby-version
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+
data/README.md ADDED
@@ -0,0 +1,13 @@
1
+ ### Demo of Simple Ruby Web Server to View Files
2
+
3
+ #### Usage:
4
+
5
+ * Run with ruby, `ruby ./test/file_server.rb`
6
+ * Navigate to a file, e.g. http://5678:SeaSerpent.jpg
7
+
8
+ #### Features
9
+
10
+ * Will only serve files in `public` directory
11
+ * Incorporates security features implemented in `Rack::File` to ensure only authorized files are accessed.
12
+ * Uses `IO.copy_stream(file, socket)`
13
+ * Will continue to serve files until killed.
data/lib/server.rb ADDED
@@ -0,0 +1,36 @@
1
+ require 'socket'
2
+
3
+ server = TCPServer.new('localhost', 5678)
4
+
5
+ # infinite loop to process one incoming connection at a time
6
+
7
+ loop do
8
+ # wait for client to connect, then reurn a TCPSocket
9
+ # that can be used in a similar fashion to other Ruby
10
+ # I/O objects.
11
+ socket = server.accept
12
+
13
+ # read the first line of request (Request Line)
14
+ request = socket.gets
15
+
16
+ # Log request to console for debugging
17
+ STDERR.puts request
18
+
19
+ response = "Welcome to jetWhidbey World.\n"
20
+
21
+ # Include the Content-Type and Content-Length headers
22
+ # to let the client know the size and type of data
23
+ # contained in the response. Note that HTTP is whitespacce sensitive
24
+ # and expects each header line to end with CRLF (i.e. "\r\n")
25
+ socket.print "HTTP/1.1 200 OK\r\n" +
26
+ "Content-Type: text/plain\r\n" +
27
+ "Content-Length: #{response.bytesize}\r\n" +
28
+ "Connection: close\r\n"
29
+
30
+ # Print a blank line to separate the header from the respnse body,
31
+ # as required by the protocol.
32
+ socket.print "\r\n"
33
+
34
+ # Print the actual response body, which is just "Welcome to jetWhidbey World.\n"
35
+ socket.print response
36
+ end
@@ -0,0 +1,14 @@
1
+ require 'socket'
2
+
3
+ port = (ARGV[0] || 5678).to_i
4
+ server = TCPServer.new('localhost', port)
5
+
6
+ loop do
7
+ while (session = server.accept)
8
+ puts "Request: #{session.gets}"
9
+ session.print "HTTP/1.1 200/OK\r\nContent-type: text/html\r\n\r\n"
10
+ session.print "<html><body><h1>#{Time.now}</h1></body></html>\r\n"
11
+ session.close
12
+ end
13
+ end
14
+
@@ -0,0 +1,61 @@
1
+ require 'socket'
2
+ require 'uri'
3
+ require 'tiny_ruby_server/version'
4
+
5
+ module TinyRubyServer
6
+
7
+ # File will be served from below directory
8
+ WEB_ROOT = './public'
9
+
10
+ # Map extensions to their content type
11
+ CONTENT_TYPE_MAPPING = {
12
+ 'html' => 'text/html',
13
+ 'txt' => 'text/plain',
14
+ 'png' => 'image/png',
15
+ 'jpg' => 'image/jpeg',
16
+ 'gif' => 'image/gif'
17
+ }
18
+
19
+ # Treat as binary data if content type can not be found
20
+ DEFAULT_CONTENT_TYPE = 'application/octet-stream'
21
+
22
+ # Helper function to parse extension of requested file,
23
+ # then looks up its content type:
24
+
25
+ def self.content_type(path)
26
+ ext = File.extname(path).split(".").last
27
+ CONTENT_TYPE_MAPPING.fetch(ext, DEFAULT_CONTENT_TYPE)
28
+ end
29
+
30
+ # Helper function to parse the Request-Line and
31
+ # generate a pathe to a file on the server.
32
+
33
+ # The below is lifted from Rack::File
34
+ # The reason for this is that it is extremely easy to introduce a
35
+ # security vulnerablility where any file in file system can be accessed.
36
+ # In fact, the below was added in 2013 specifically to deal with such a
37
+ # security vulnerablility
38
+
39
+ def self.requested_file(request_line)
40
+ request_uri = request_line.split(" ")[1]
41
+ path = URI.unescape(URI(request_uri).path)
42
+
43
+ clean = []
44
+
45
+ # Split the path into components
46
+ parts = path.split("/")
47
+
48
+ parts.each do |part|
49
+ # skip any empty or current directory (".") path components
50
+ next if part.empty? || part == '.'
51
+ # If the path component goes up one directory level (".."),
52
+ # remove the last clean component.
53
+ # Otherwise, add the component to the Array of clean components
54
+ part == '..' ? clean.pop : clean << part
55
+ end
56
+ # return the web root joined to the clean path
57
+ path = File.join(WEB_ROOT, *clean)
58
+
59
+ end
60
+ end
61
+
@@ -0,0 +1,3 @@
1
+ module TinyRubyServer
2
+ VERSION = "0.1"
3
+ end
Binary file
Binary file
Binary file
data/public/index.html ADDED
@@ -0,0 +1,11 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width">
6
+ <title>A Simple File Server</title>
7
+ </head>
8
+ <body>
9
+ <h2>Here is our simple file server.</h2>
10
+ </body>
11
+ </html>
Binary file
Binary file
@@ -0,0 +1,47 @@
1
+ require 'pry'
2
+ require 'tiny_ruby_server'
3
+
4
+ server = TCPServer.new('localhost', 5678)
5
+ loop do
6
+ socket = server.accept
7
+ request_line = socket.gets
8
+ STDERR.puts request_line
9
+
10
+ if request_line
11
+ path = TinyRubyServer.requested_file(request_line)
12
+
13
+ path = File.join(path, 'index.html') if File.directory?(path)
14
+
15
+ # Make sure file exists and is not a directory
16
+ # before attempting to open it
17
+ if File.exist?(path) && !File.directory?(path)
18
+ File.open(path, "rb") do |file|
19
+ socket.print "HTTP/1.1 200 OK\r\n" +
20
+ "Content-Type: #{TinyRubyServer.content_type(file)}\r\n" +
21
+ "Content-Length: #{file.size}\r\n" +
22
+ "Connection: close\r\n"
23
+
24
+ # print blank line necessary for specification:
25
+ socket.print "\r\n"
26
+
27
+ # Write the contents of the file to the socket
28
+ IO.copy_stream(file, socket)
29
+ end
30
+
31
+ else
32
+ msg = "File not found\n"
33
+
34
+ # respond with a 404 error code to indicate the file does not exist
35
+ socket.print "HTTP/1.1 404 Not Found\r\n" +
36
+ "Content-Type: text/plain\r\n" +
37
+ "Content-Length: #{msg.size}\r\n" +
38
+ "Connection: close\r\n"
39
+
40
+ socket.print "\r\n"
41
+ socket.print msg
42
+ end
43
+
44
+ socket.close
45
+ end
46
+ end
47
+
@@ -0,0 +1,18 @@
1
+ # coding: utf-8
2
+
3
+ lib = File.expand_path(File.join(*%w[.. lib]), File.dirname(__FILE__))
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require File.expand_path('../lib/tiny_ruby_server/version', __FILE__)
6
+
7
+ Gem::Specification.new do |gem|
8
+ gem.name = 'tiny_ruby_server'
9
+ gem.version = TinyRubyServer::VERSION
10
+ gem.date = '2015-04-02'
11
+ gem.summary = "Tiny Ruby Server"
12
+ gem.description = "A tiny, secure Ruby file server"
13
+ gem.authors = ["Jerry Thompson"]
14
+ gem.email = 'jerrold.r.thompson@gmail.com'
15
+ gem.homepage = 'https://github.com/jetsgit/tiny_ruby_server'
16
+ gem.files = `git ls-files`.split($/)
17
+ gem.require_paths = ["lib"]
18
+ end
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tiny_ruby_server
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - Jerry Thompson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-04-02 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A tiny, secure Ruby file server
14
+ email: jerrold.r.thompson@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - ".gitignore"
20
+ - Gemfile
21
+ - README.md
22
+ - lib/server.rb
23
+ - lib/time_server_local.rb
24
+ - lib/tiny_ruby_server.rb
25
+ - lib/tiny_ruby_server/version.rb
26
+ - public/SeaSerpent.png
27
+ - public/Vinh_Long_small.jpg
28
+ - public/goldstar.gif
29
+ - public/index.html
30
+ - public/ruby_reflections.png
31
+ - public/sockeyes_in_stream.jpg
32
+ - test/file_server.rb
33
+ - tiny_ruby_server.gemspec
34
+ homepage: https://github.com/jetsgit/tiny_ruby_server
35
+ licenses: []
36
+ metadata: {}
37
+ post_install_message:
38
+ rdoc_options: []
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ required_rubygems_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ requirements: []
52
+ rubyforge_project:
53
+ rubygems_version: 2.2.2
54
+ signing_key:
55
+ specification_version: 4
56
+ summary: Tiny Ruby Server
57
+ test_files: []
58
+ has_rdoc: