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 +7 -0
- data/.gitignore +2 -0
- data/Gemfile +3 -0
- data/README.md +13 -0
- data/lib/server.rb +36 -0
- data/lib/time_server_local.rb +14 -0
- data/lib/tiny_ruby_server.rb +61 -0
- data/lib/tiny_ruby_server/version.rb +3 -0
- data/public/SeaSerpent.png +0 -0
- data/public/Vinh_Long_small.jpg +0 -0
- data/public/goldstar.gif +0 -0
- data/public/index.html +11 -0
- data/public/ruby_reflections.png +0 -0
- data/public/sockeyes_in_stream.jpg +0 -0
- data/test/file_server.rb +47 -0
- data/tiny_ruby_server.gemspec +18 -0
- metadata +58 -0
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
data/Gemfile
ADDED
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
|
+
|
Binary file
|
Binary file
|
data/public/goldstar.gif
ADDED
Binary file
|
data/public/index.html
ADDED
Binary file
|
Binary file
|
data/test/file_server.rb
ADDED
@@ -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:
|