I’m looking for a way to host a local directory as a small, static, website.
The local web server in Node.js offers exactly what I need (running ws in the terminal starts a local web server in the current directory which I can access at localhost:8000), but it’d be great to do it in Julia.
I imagine this is possible with HttpServer.jl but I don’t know how and I was a bit confused by the doc (apologies, I’m a newbie in the world of web apps). Pointers would be very welcome.
req.target == "/" && return HTTP.Response(200, read("index.html")) is a default handler where you navigate to 127.0.0.1:8081, typically in that case, servers return the “default” webpage, usually named “index.html”. file = HTTP.unescapeuri(req.target[2:end])), takes any path and converts it into a file, so if you visited 127.0.0.1:8081/path/to/file it would return path/to/file; the call to unescapeuri just ensures that any % encoded characters are converted back from the url encoding.
The last line just checks if the path refers to an actual file: if so, it reads and returns it, otherwise, a 404 response is returned.
It might be worth noting that the default http.server in Python only serves files from within the current directory, whereas this one will happily serve up http://localhost:8081//etc/passwd.
using Bukdu
plug(plug.Static, at="/", from=normpath("."))
Bukdu.start(8000)
and got
ERROR GET /
MethodError(convert, (Bukdu.Octo.Assoc, Dict("Connection"=>"keep-alive","DNT"=>"1","Upgrade-Insecure-Requests"=>"1","http_minor"=>"1","Keep-Alive"=>"1","User-Agent"=>"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:61.0) Gecko/20100101 Firefox/61.0","Accept-Encoding"=>"gzip, deflate","Host"=>"localhost:8000","http_major"=>"1","Accept"=>"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8","Accept-Language"=>"en-GB,en;q=0.5")), 0x000000000000555c)
handler(::Type{Bukdu.Endpoint}, ::Int64, ::HttpCommon.Request, ::HttpCommon.Response) at handler.jl:46
(::Bukdu.##64#68{Bukdu.Endpoint,Int64})(::HttpCommon.Request, ::HttpCommon.Response) at server.jl:88
(::HttpServer.#on_message_complete#14{HttpServer.Server,HttpServer.Client{TCPSocket},Bool})(::HttpCommon.Request) at HttpServer.jl:427
on_message_complete(::Ptr{HttpParser.Parser}) at RequestParser.jl:113
http_parser_execute(::HttpParser.Parser, ::HttpParser.ParserSettings, ::Array{UInt8,1}) at HttpParser.jl:115
process_client(::HttpServer.Server, ::HttpServer.Client{TCPSocket}, ::Bool) at HttpServer.jl:389
(::HttpServer.##7#8{HttpServer.Server,Bool})() at task.jl:335
Hello @wookyoung,
I’m starting to write a small web app with Bukdu. Unfortunately I couldn’t figure out how to use this static plug, it seems like this changed. I couldn’t find any documentation or a working example.
My new lightweight web framework Dance.jl supports this easily:
using Dance.Router
static_dir("/static", "files")
where first param is route prefix of how to serve (can be / too) and second param is name of the static files folder in web project dir to serve content from.
You would have to copy the static files dir to root of newly created web project dir, as for security dance.jl does not allow going higher than the project root.
Nice! given I was the OP I should probably also mention here that we ended up building LiveServer.jl (a bit similar to python’s http.server and node’s browser-sync) for the purpose mentioned in the question. LiveServer works with Documenter, Literate and also is the backend of Franklin.jl so it’s pretty robust though quite simple.
Glad to see that there are more things coming in this space, I haven’t tried Dance yet but will have a look!