providing static content in webmachine
Recently I was migrating my web app from plain vanilla mochiweb into webmachine. One caveat I met was how to serve static content. Mochiweb as a default serves static content from its ./priv/www directory but I haven’t found similar convention in webmachine. Indeed, there is no one. Instead one have to create static content resource. I created the webmachine static resource just for that purpose feel free to use it in your projects.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | %% @author author <daniel.kwiecinski@lambder.com> %% @copyright Daniel Kwiecinski. %% @doc Static webmachine resource. -module(static_resource). -export([init/1, allowed_methods/2, content_types_provided/2, resource_exists/2, last_modified/2, provide_content/2]). -include_lib("webmachine/include/webmachine.hrl"). -include_lib("kernel/include/file.hrl"). -record(context, {docroot,fullpath,fileinfo}). init(DocRoot) -> {ok, #context{docroot=DocRoot}}. resource_exists(ReqData, Context) -> case get_full_path(Context#context.docroot, wrq:disp_path(ReqData)) of undefined -> {false, ReqData, Context}; Path -> case filelib:is_regular(Path) of true -> case file:read_file_info(Path) of {ok, FileInfo} -> {true, ReqData, Context#context{fileinfo=FileInfo}}; {error, _} -> {false, ReqData, Context} end; _ -> {false, ReqData, Context} end end. content_types_provided(ReqData, Context) -> Path = get_full_path(Context#context.docroot, wrq:disp_path(ReqData)), {[{webmachine_util:guess_mime(Path), provide_content}], ReqData, Context#context{fullpath=Path}}. allowed_methods(ReqData, Context) -> {['HEAD', 'GET'], ReqData, Context}. last_modified(ReqData, Context) -> {(Context#context.fileinfo)#file_info.mtime, ReqData, Context}. provide_content(ReqData, Context) -> util:puts(Context), {ok, Value} = file:read_file(Context#context.fullpath), {Value, ReqData, Context}. % ------------------ PRIVATE ------------------------ get_full_path(DocRoot, Path) -> case mochiweb_util:safe_relative_path(Path) of undefined -> undefined; RelPath -> FullPath = filename:join([DocRoot, RelPath]), case filelib:is_dir(FullPath) of true -> filename:join([FullPath, "index.html"]); false -> FullPath end end. |
Bon Appétit
Nice fileserver! Very easy to follow, and right to the point. If you ever find yourself wanting to extend its abilities (adding etags or file uploads, for example), I recommend having a look at the “demo_fs_resource” that ships with Webmachine. It’s buried in webmachine/demo/src, but it has a few simple implementations of common resource functions, so it’s worth a glance.
Hello, can you please post some more information on this topic? I would like to read more.
I’m really happy to answer your questions and help. Feel free to contact me.