tiny_ruby_server 0.1

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 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: