lib/slinky/server.rb in slinky-0.1.0 vs lib/slinky/server.rb in slinky-0.1.1
- old
+ new
@@ -1,13 +1,20 @@
module Slinky
+ CONTENT_TYPES = {
+ 'html' => 'text/html',
+ 'js' => 'application/x-javascript',
+ 'css' => 'text/css'
+ }
+
+ EXTENSION_REGEX = /(.+)\.(\w+)/
+
class Server < EventMachine::Connection
include EM::HttpServer
@compilers = []
@compilers_by_ext = {}
-
@files = {}
class << self
def register_compiler klass, options
options[:klass] = klass
@@ -25,11 +32,10 @@
def files
self.class.instance_variable_get(:@files)
end
- EXTENSION_REGEX = /(^[\w\d\:\/\.]*)\.(\w+)/
def process_http_request
@resp = EventMachine::DelegatedHttpResponse.new(self)
_, _, _, _, _, path, _, query = URI.split @http_request_uri
path = path[1..-1] #get rid of the leading /
@@ -59,11 +65,11 @@
# find a compiler that outputs the request kind of file and
# which has an input file type that exists on the file system
compilers[extension].each do |c|
c[:inputs].each do |i|
if files_by_ext[i]
- cfile = CompiledFile.new files_by_ext[i], c[:klass]
+ cfile = CompiledFile.new files_by_ext[i], c[:klass], extension
files[path] = cfile
break
end
end
break if cfile
@@ -91,20 +97,29 @@
end
end
end
def serve_file path
- if File.exists? path
- size = File.size? path
- if true || size < EventMachine::FileStreamer::MappingThreshold
- s = File.open(path).read
- @resp.content = s
- @resp.send_response
- else
- stream_file_data path do
- @resp.send_headers
- @resp.send_trailer
+ if File.exists?(path) && size = File.size?(path)
+ _, _, extension = path.match(EXTENSION_REGEX).to_a
+ @resp.content_type CONTENT_TYPES[extension]
+ # File reading code from rack/file.rb
+ range = 0..size-1
+ EM.defer do
+ File.open path do |file|
+ file.seek(range.begin)
+ remaining_len = range.end-range.begin+1
+ while remaining_len > 0
+
+ part = file.read([8192, remaining_len].min)
+ break unless part
+ remaining_len -= part.length
+
+ @resp.chunk part
+ @resp.send_chunks
+ end
end
+ @resp.send_trailer
end
else
@resp.status = 404
@resp.content = "File '#{path}' not found."
@resp.send_response