In Camping, how's it best to serve static files, such as css?
Right now I have
class Style < R '/cards.css'
def get
@headers["Content-Type"] = "text/css"
File.read('cards.css')
end
end
Is there a smarter way involving Rack?
Serving Files With koa-static To serve files just pass the koa-static middleware to the koa's middleware stack with app. use() .
In your node application, you can use node-static module to serve static resources. The node-static module is an HTTP static-file server module with built-in caching. First of all, install node-static module using NPM as below. After installing node-static module, you can create static file server in Node.
Camping's current (remember to install the latest version from RubyGems!) stance on static files is that the server should be responsible for serving static files.
If you use the camping
-command then the public/
-directory should automatically be served for you. Simply move cards.css
into public/cards.css
and localhost:3301/cards.css should return the file.
In production you should configure Apache/Nginx/whatever to serve files directly from the public/
-directory.
If you can't configure Apache/Nginx (e.g. in Heroku) you can write a custom config.ru like this:
# Your Camping app:
app = MyApp
# Static files:
files = Rack::File.new('public')
# First try the static files, then "fallback" to the app
run Rack::Cascade.new([files, app], [405, 404, 403])
(This is what Camping::Server does internally: https://github.com/camping/camping/blob/5201b49b753fe29dc3d2e96405d724bcaa7ad7d4/lib/camping/server.rb#L151)
For small files, you can store them in the DATA-block of your app.rb: https://github.com/camping/camping/blob/5201b49b753fe29dc3d2e96405d724bcaa7ad7d4/test/app_file.rb#L37
This is also useful if you want to keep everything inside one file.
Camping.goes :Foo
__END__
@@ /cards.css
...
Camping will use the file extension to set the correct Content-Type.
Also, the latest version of Camping has a serve
-method which handles the Content-Type for you. You could simplify your controller to this:
class Style < R '/style.css'
def get
serve "cards.css", File.read("cards.css")
end
end
I'll have to apologize for the bad documentation. For now you
Here's a suggestion originally by whytheluckystiff:
class Static < R '/static/(.+)'
MIME_TYPES = {
'.html' => 'text/html',
'.css' => 'text/css',
'.js' => 'text/javascript',
'.jpg' => 'image/jpeg',
'.gif' => 'image/gif'
}
PATH = File.expand_path(File.dirname(@__FILE__@))
def get(path)
@headers['Content-Type'] = MIME_TYPES[path[/\.\w+$/, 0]] || "text/plain"
unless path.include? ".." # prevent directory traversal attacks
@headers['X-Sendfile'] = "#{PATH}/static/#{path}"
else
@status = "403"
"403 - Invalid path"
end
end
end
PS- Actually, you can find some other great ideas here, like file uploads, sessions, etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With