Skip to content

Instantly share code, notes, and snippets.

@pda
Created August 9, 2012 02:23
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save pda/3300372 to your computer and use it in GitHub Desktop.
Save pda/3300372 to your computer and use it in GitHub Desktop.
www: Serve the current directory via HTTP.
#!/usr/bin/env ruby
# Serve the current directory via HTTP.
# Like Python's SimpleHTTPServer, but with no-cache headers.
# Default port 8000, specify alternate port as first parameter:
# www 3000
# sudo www 80 # (probably a bad idea)
# Inspired by http://chrismdp.github.com/2011/12/cache-busting-ruby-http-server/
require "webrick"
class NonCachingFileHandler < WEBrick::HTTPServlet::FileHandler
DAY = 86400
def do_GET(request, response)
super
set_no_cache(response)
set_content_type(response)
end
private
def set_no_cache(response)
response["Content-Type"]
response["ETag"] = nil
response["Last-Modified"] = Time.now + DAY
response["Cache-Control"] = "no-store, no-cache, must-revalidate, post-check=0, pre-check=0"
response["Pragma"] = "no-cache"
response["Expires"] = Time.now - DAY
end
def set_content_type(response)
response["Content-Type"] = content_type(response.filename)
end
def content_type(path)
case path.match(%r{\.(\w+)\z})[1]
when "html" then "text/html"
when "js" then "text/javascript"
when "css" then "text/css"
else `/usr/bin/file --brief --mime-type #{Shellwords.escape(path)}`.chomp
end
end
end
WEBrick::HTTPServer.new(Port: ARGV.first || 8000).tap do |server|
server.mount "/", NonCachingFileHandler , Dir.pwd
trap("INT") { server.stop }
server.start
end
@wolfeidau
Copy link

Only change I have made to this script is adding less as a suffix for text/css mime type.

when "css","less" then "text/css"

Working a treat for HTML mockup serving!

@pda
Copy link
Author

pda commented Sep 4, 2012

The calls to IO.popen for Content-Type detection were leaving behind dead processes.

Instead of adding the verbosity of pid collection, Process.wait calls etc, I've used backticks instead of IO.popen, with Shellwords.escape protecting against shell injection via path names.

@curran
Copy link

curran commented Jul 22, 2013

Here's an even simpler solution for always serving fresh files (if you're willing to use Node) https://github.com/curran/dashboardScaffold/blob/4ce4da6d9b79431570ff152620198f4a6612e70d/server.js

@dskecse
Copy link

dskecse commented Nov 28, 2014

You could simply run ruby -run -e httpd . -p 8000.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment