Module: Slinky::Server
- Includes:
- EM::HttpServer
- Defined in:
- lib/slinky/server.rb
Constant Summary collapse
- INJECT_CSS =
File.read("#{File.dirname(__FILE__)}/templates/inject.css")
- ERROR_CSS =
File.read("#{File.dirname(__FILE__)}/templates/error.css")
- ERROR_HAML =
File.read("#{File.dirname(__FILE__)}/templates/error.haml")
- ERROR_JS =
File.read("#{File.dirname(__FILE__)}/templates/error.js")
Class Method Summary collapse
- .config ⇒ Object
- .config=(_config) ⇒ Object
-
.dir ⇒ Object
Gets the root directory from which files should be served.
-
.dir=(_dir) ⇒ Object
Sets the root directory from which files should be served.
-
.format_error_output(resp, mf, error) ⇒ Object
Produces nice error output for various kinds of formats.
-
.handle_file(resp, mf, compile = true) ⇒ Object
Takes a manifest file and produces a response for it.
- .manifest ⇒ Object
- .manifest=(_manifest) ⇒ Object
-
.not_found(resp) ⇒ Object
Returns the proper response for files that do not exist.
-
.path_for_uri(uri) ⇒ Object
Splits a uri into its components, returning only the path sans initial forward slash.
- .process_path(resp, path, pushstate = false) ⇒ Object
-
.serve_file(resp, path) ⇒ Object
Serves a file from the file system.
Instance Method Summary collapse
-
#process_http_request ⇒ Object
Method called for every HTTP request made.
Class Method Details
.config ⇒ Object
16 |
# File 'lib/slinky/server.rb', line 16 def self.config; @config || ConfigReader.empty; end |
.config=(_config) ⇒ Object
15 |
# File 'lib/slinky/server.rb', line 15 def self.config= _config; @config = _config; end |
.dir ⇒ Object
Gets the root directory from which files should be served
13 |
# File 'lib/slinky/server.rb', line 13 def self.dir; @dir || "."; end |
.dir=(_dir) ⇒ Object
Sets the root directory from which files should be served
11 |
# File 'lib/slinky/server.rb', line 11 def self.dir= _dir; @dir = _dir; end |
.format_error_output(resp, mf, error) ⇒ Object
Produces nice error output for various kinds of formats
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/slinky/server.rb', line 74 def self.format_error_output resp, mf, error resp.content = case Pathname.new(mf.output_path).extname when ".html" Haml::Engine.new(ERROR_HAML). render(Object.new, errors: error., css: ERROR_CSS) when ".css" resp.status = 200 # browsers ignore 500'd css INJECT_CSS.gsub("{REPLACE_ERRORS}", error..join("\n").gsub("'", "\"")) when ".js" resp.status = 200 # browsers ignore 500'd js ERROR_JS .gsub("{REPLACE_CSS}", JSON.dump({css: ERROR_CSS.gsub("\n", "")})) .gsub("{REPLACE_ERRORS}", JSON.dump(error.)) else error. end end |
.handle_file(resp, mf, compile = true) ⇒ Object
Takes a manifest file and produces a response for it
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/slinky/server.rb', line 96 def self.handle_file resp, mf, compile = true begin path = mf.process(nil, compile) serve_file resp, path.to_s rescue SlinkyError => e resp.status = 500 if self.config.enable_browser_errors format_error_output(resp, mf, e) else resp.content = e. end e..each{|m| $stderr.puts(m.foreground(:red)) } rescue => e resp.status = 500 format_error_output(resp, mf, SlinkyError.new( "Unknown error handling #{mf.source}: #{$!}\n")) $stderr.puts("Unknown error handling #{mf.source}: #{$!}".foreground(:red)) end resp end |
.manifest ⇒ Object
19 |
# File 'lib/slinky/server.rb', line 19 def self.manifest; @manifest; end |
.manifest=(_manifest) ⇒ Object
18 |
# File 'lib/slinky/server.rb', line 18 def self.manifest= _manifest; @manifest = _manifest; end |
.not_found(resp) ⇒ Object
Returns the proper response for files that do not exist
140 141 142 143 |
# File 'lib/slinky/server.rb', line 140 def self.not_found resp resp.status = 404 resp.content = "File not found\n" end |
.path_for_uri(uri) ⇒ Object
Splits a uri into its components, returning only the path sans initial forward slash.
23 24 25 26 |
# File 'lib/slinky/server.rb', line 23 def self.path_for_uri uri _, _, _, _, _, path, _, _ = URI.split uri path[1..-1] #get rid of the leading / end |
.process_path(resp, path, pushstate = false) ⇒ Object
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/slinky/server.rb', line 43 def self.process_path resp, path, pushstate = false file = manifest.find_by_path(path).first if file.is_a? ManifestDir file = manifest.find_by_path(path + "/index.html").first path += "/index.html" end if file # They're requesting the source file and we should not # compile it (but still process directives) compile = !(file.source.end_with?(path) && file.source) handle_file(resp, file, compile) elsif !pushstate && p = config.pushstate_for_path("/" + path) path = p[0] == "/" ? p[1..-1] : p self.process_path(resp, path, true) else not_found resp end type = MIME::Types.type_for(path).first.to_s if resp.content.encoding.to_s == "UTF-8" type += "; charset=utf-8" end resp.content_type type resp end |
.serve_file(resp, path) ⇒ Object
Serves a file from the file system
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/slinky/server.rb', line 120 def self.serve_file resp, path if File.exists?(path) && !File.directory?(path) size = File.size(path) _, _, extension = path.match(EXTENSION_REGEX).to_a # File reading code from rack/file.rb File.open(path, "rb") do |file| resp.content = "" while size > 0 part = file.read([8192, size].min) break unless part size -= part.length resp.content << part end end else not_found resp end end |
Instance Method Details
#process_http_request ⇒ Object
Method called for every HTTP request made
29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/slinky/server.rb', line 29 def process_http_request resp = EventMachine::DelegatedHttpResponse.new(self) begin path = Server.path_for_uri(@http_request_uri) rescue resp.status = 500 resp.content = "Invalid request" return end Server.process_path(resp, path).send_response end |