Skip to content

Commit

Permalink
Merge pull request #42 from choptastic/master
Browse files Browse the repository at this point in the history
Add Cowboy support. Fix webmachine compilation
  • Loading branch information
choptastic committed Apr 28, 2012
2 parents fb77001 + d0a3a5b commit eb72c52
Show file tree
Hide file tree
Showing 13 changed files with 290 additions and 9 deletions.
15 changes: 15 additions & 0 deletions Makefile
Expand Up @@ -6,6 +6,7 @@ help:
@echo "Usage: "
@echo " ./make {compile|clean}"
@echo
@echo " ./make {rel_cowboy|package_cowboy}"
@echo " ./make {rel_inets|package_inets}"
@echo " ./make {rel_mochiweb|package_mochiweb}"
@echo " ./make {rel_webmachine|package_webmachine}"
Expand All @@ -24,6 +25,20 @@ compile: get-deps
clean:
./rebar clean

# COWBOY

rel_cowboy: compile
@rm -rf rel/nitrogen
@rm -rf rel/reltool.config
@ln rel/reltool_cowboy.config rel/reltool.config
@(make rel_inner)
@echo Generated a self-contained Nitrogen project
@echo in 'rel/nitrogen', configured to run on Cowboy.

package_cowboy: rel_cowboy
mkdir -p ./builds
tar -C rel -c nitrogen | gzip > ./builds/nitrogen-${NITROGEN_VERSION}-yaws.tar.gz

# INETS

rel_inets: compile
Expand Down
16 changes: 13 additions & 3 deletions THANKS.markdown
Expand Up @@ -2,7 +2,7 @@

Sincere thanks to all the people who have helped make Nitrogen great, including:

* Rusty Klophaus (@rklophaus)
* Rusty Klophaus (@rustyio)
* Chris Williams (@voodootikigod)
* Joel Reymont (@wagerlabs)
* Tom McNulty
Expand All @@ -21,11 +21,21 @@ Sincere thanks to all the people who have helped make Nitrogen great, including:
* Yurii Rashkovskii (@yrashk)
* Ville Koivula
* Manuel Durán Aguete
* Jesse Gumm
* Jesse Gumm (@jessegumm)
* Jan-Felix Wittmann
* Martin Sivak
* Jonas Ådahl
* Boris Faure
* Gregory Haskins
* Dave Peticolas
* Susan Potter
* Ward Bekkar
* Gleb Peregud
* Lorant Kurthy
* Andreas Hasselberg
* Mattias Holmlund
* Justin Kirby
* Tuncer Ayaz
* Loïc Hoguin (@lhoguin)

Roughly sorted by date of contribution. Send your twitter handles to @rklophaus
Roughly sorted by date of contribution. Send your twitter handles to @rustyio or @jessegumm
6 changes: 4 additions & 2 deletions rebar.config
@@ -1,3 +1,5 @@
%% vim: ts=4 sw=4 et ft=erlang

{sub_dirs, ["rel"]}.

{require_otp_vsn, "R13B04|R14|R15"}.
Expand All @@ -7,9 +9,9 @@
{erl_opts, [debug_info, fail_on_warning]}.

{deps, [
{nitrogen_core, "2.1.*", {git, "git://github.com/nitrogen/nitrogen_core.git", "HEAD"}},
{nitrogen_core, "2.1.*", {git, "git://github.com/choptastic/nitrogen_core.git", "HEAD"}},
{nprocreg, "0.2.*", {git, "git://github.com/nitrogen/nprocreg.git", "HEAD"}},
{simple_bridge, "1.2.*", {git, "git://github.com/nitrogen/simple_bridge.git", "HEAD"}},
{simple_bridge, "1.2.*", {git, "git://github.com/choptastic/simple_bridge.git", "HEAD"}},
{sync, "0.1.*", {git, "git://github.com/rustyio/sync.git", "HEAD"}}

%% {nitrogen_core, "2.1.*", {git, "git://github.com/nitrogen/nitrogen_core.git", {tag, "v2.1.0"}}},
Expand Down
10 changes: 10 additions & 0 deletions rel/overlay/cowboy/etc/cowboy.config
@@ -0,0 +1,10 @@
% vim: ts=4 sw=4 et
[
{cowboy,[
{bind_address,"0.0.0.0"},
{bind_port,8000},
{server_name,nitrogen},
{document_root,"./site/static"},
{static_paths, ["js/","images/","css/","nitrogen/"]}
]}
].
26 changes: 26 additions & 0 deletions rel/overlay/cowboy/rebar.config
@@ -0,0 +1,26 @@
{sub_dirs, [
"site",
"deps"
]}.

{require_otp_vsn, "R13B04|R14|R15"}.

{cover_enabled, true}.

{erl_opts, [debug_info, fail_on_warning]}.

{deps_dir, ["lib"]}.

{deps, [
{cowboy, "0.5.*", {git, "git://github.com/extend/cowboy",{tag, "HEAD"}}},
{mimetypes, ".*", {git, "git://github.com/spawngrid/mimetypes", {tag, "HEAD"}}},

{nitrogen_core, "2.1.*", {git, "git://github.com/nitrogen/nitrogen_core", "HEAD"}},
{nprocreg, "0.2.*", {git, "git://github.com/nitrogen/nprocreg", "HEAD"}},
{simple_bridge, "1.2.*", {git, "git://github.com/nitrogen/simple_bridge", "HEAD"}},
{sync, "0.1.*", {git, "git://github.com/rustyio/sync.git", "HEAD"}}
%% {nitrogen_core, "2.1.*", {git, "git://github.com/nitrogen/nitrogen_core", {tag, "v2.1.0"}}},
%% {nprocreg, "0.2.*", {git, "git://github.com/nitrogen/nprocreg", {tag, "v0.2.0"}}},
%% {simple_bridge, "1.2.*", {git, "git://github.com/nitrogen/simple_bridge", {tag, "v1.2.0"}}},
%% {sync, "0.1.*", {git, "git://github.com/rustyio/sync.git", {tag, "v0.1.0"}}}
]}.
13 changes: 13 additions & 0 deletions rel/overlay/cowboy/site/src/nitrogen_app.erl
@@ -0,0 +1,13 @@
-module(nitrogen_app).
-behaviour(application).
-export([start/2, stop/1]).

%% ===================================================================
%% Application callbacks
%% ===================================================================

start(_StartType, _StartArgs) ->
nitrogen_sup:start_link().

stop(_State) ->
ok.
37 changes: 37 additions & 0 deletions rel/overlay/cowboy/site/src/nitrogen_cowboy.erl
@@ -0,0 +1,37 @@
%% vim: ts=4 sw=4 et

-module(nitrogen_cowboy).
-include_lib("nitrogen_core/include/wf.hrl").

-export([init/3, handle/2, terminate/2]).

-record(state, {headers, body}).

init({_Transport, http}, Req, Opts) ->
Headers = proplists:get_value(headers, Opts, []),
Body = proplists:get_value(body, Opts, "http_handler"),
{ok, Req, #state{headers=Headers, body=Body}}.


handle(Req,_Opts) ->
{ok, DocRoot} = application:get_env(cowboy, document_root),
RequestBridge = simple_bridge:make_request(cowboy_request_bridge,
{Req, DocRoot}),

%% Becaue Cowboy usese the same "Req" record, we can pass the
%% previously made RequestBridge to make_response, and it'll
%% parse out the relevant bits to keep both parts (request and
%% response) using the same "Req"
ResponseBridge = simple_bridge:make_response(cowboy_response_bridge,
RequestBridge),

%% Establishes the context with the Request and Response Bridges
nitrogen:init_request(RequestBridge, ResponseBridge),

{ok, NewReq} = nitrogen:run(),

%% This will be returned back to cowboy
{ok, NewReq, _Opts}.

terminate(_Req, _State) ->
ok.
81 changes: 81 additions & 0 deletions rel/overlay/cowboy/site/src/nitrogen_sup.erl
@@ -0,0 +1,81 @@
%% -*- mode: nitrogen -*-
%% vim: ts=4 sw=4 et
-module(nitrogen_sup).
-behaviour(supervisor).
-export([
start_link/0,
init/1
]).

%% Helper macro for declaring children of supervisor
-define(CHILD(I, Type), {I, {I, start_link, []}, permanent, 5000, Type, [I]}).

%% ===================================================================
%% API functions
%% ===================================================================

start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, []).

%% ===================================================================
%% Supervisor callbacks
%% ===================================================================

init([]) ->
%% Start the Process Registry...
application:start(nprocreg),

%% Start Cowboy...
application:start(cowboy),
{ok, BindAddress} = application:get_env(cowboy, bind_address),
{ok, Port} = application:get_env(cowboy, bind_port),
{ok, ServerName} = application:get_env(cowboy, server_name),
{ok, DocRoot} = application:get_env(cowboy, document_root),
{ok, StaticPaths} = application:get_env(cowboy, static_paths),
DocRootBin = wf:to_binary(DocRoot),

io:format("Starting Cowboy Server (~s) on ~s:~p, root: '~s'~n",
[ServerName, BindAddress, Port, DocRoot]),

StaticDispatches = lists:map(fun(Dir) ->
Path = reformat_path(Dir),
Handler = cowboy_http_static,
Opts = [
{directory, filename:join([DocRootBin | Path])},
{mimetypes, {fun mimetypes:path_to_mimes/2, default}}
],
{Path ++ ['...'],Handler,Opts}
end,StaticPaths),

%% HandlerModule will end up calling HandlerModule:handle(Req,HandlerOpts)
HandlerModule = nitrogen_cowboy,
HandlerOpts = [],

%% Start Cowboy...
%% NOTE: According to Loic, there's no way to pass the buck back to cowboy
%% to handle static dispatch files so we want to make sure that any large
%% files get caught in general by cowboy and are never passed to the nitrogen
%% handler at all. In general, your best bet is to include the directory in
%% the static_paths section of cowboy.config
Dispatch = [
%% Nitrogen will handle everything that's not handled in the StaticDispatches
{'_', StaticDispatches ++ [{'_',HandlerModule , HandlerOpts}]}
],
HttpOpts = [{max_keepalive, 50}, {dispatch, Dispatch}],
cowboy:start_listener(http, 100,
cowboy_tcp_transport, [{port, Port}],
cowboy_http_protocol, HttpOpts),

{ok, { {one_for_one, 5, 10}, []} }.

%% If the path is a string, it's going to get split on / and switched to the binary
%% format that cowboy expects
reformat_path(Path) when is_list(Path) andalso is_integer(hd(Path)) ->
TokenizedPath = string:tokens(Path,"/"),
[list_to_binary(Part) || Part <- TokenizedPath];
%% If path is just a binary, let's make it a string and treat it as such
reformat_path(Path) when is_binary(Path) ->
reformat_path(binary_to_list(Path));
%% If path is a list of binaries, then we assumed it's formatted for cowboy format already
reformat_path(Path) when is_list(Path) andalso is_binary(hd(Path)) ->
Path.
49 changes: 49 additions & 0 deletions rel/reltool_cowboy.config
@@ -0,0 +1,49 @@
%% vim: ts=4 sw=4 et ft=erlang

{sys, [
{lib_dirs, ["../deps"]},
{rel, "nitrogen", "2.0.4",
[
kernel,
stdlib,
sasl,
inets,
crypto,
runtime_tools,
xmerl,
compiler,
ssl,
mnesia,
common_test,
parsetools
]},
{rel, "start_clean", "",
[
kernel,
stdlib
]},
{boot_rel, "nitrogen"},
{profile, embedded},
{excl_sys_filters, [
"^bin/.*",
"^erts.*/bin/(dialyzer|typer)"
]},
{app, sasl, [{incl_cond, include}]},
{app, eunit, [{incl_cond, include}]},
{excl_archive_filters, ["^ebin$","^include$","^priv$"]},
{incl_cond, include}
]}.

{overlay, [
%% Copy common files...
{copy, "./overlay/common/*"},
{copy, "./overlay/erts/*", "{{erts_vsn}}/bin"},
{copy, "../deps/nitrogen_core", "lib/nitrogen_core"},
{copy, "../deps/nitrogen_core/www", "site/static/nitrogen"},
{copy, "../deps/simple_bridge", "lib/simple_bridge"},
{copy, "../deps/nprocreg", "lib/nprocreg"},
{copy, "../deps/sync", "lib/sync"},

%% Copy Yaws files...
{copy, "overlay/cowboy/*"}
]}.
11 changes: 10 additions & 1 deletion rel/reltool_inets.config
@@ -1,3 +1,5 @@
%% vim: ts=4 sw=4 et ft=erlang

{sys, [
{lib_dirs, ["../deps"]},
{rel, "nitrogen", "2.0.4",
Expand All @@ -7,7 +9,13 @@
sasl,
inets,
crypto,
runtime_tools
runtime_tools,
xmerl,
compiler,
ssl,
mnesia,
common_test,
parsetools
]},
{rel, "start_clean", "",
[
Expand All @@ -20,6 +28,7 @@
"^bin/.*",
"^erts.*/bin/(dialyzer|typer)"
]},
{excl_archive_filters, ["^ebin$","^include$","^priv$"]},
{app, sasl, [{incl_cond, include}]},
{app, eunit, [{incl_cond, include}]}
]}.
Expand Down
11 changes: 10 additions & 1 deletion rel/reltool_mochiweb.config
@@ -1,3 +1,5 @@
%% vim: ts=4 sw=4 et ft=erlang

{sys, [
{lib_dirs, ["../deps"]},
{rel, "nitrogen", "2.0.4",
Expand All @@ -7,7 +9,13 @@
sasl,
inets,
crypto,
runtime_tools
runtime_tools,
xmerl,
compiler,
ssl,
mnesia,
common_test,
parsetools
]},
{rel, "start_clean", "",
[
Expand All @@ -20,6 +28,7 @@
"^bin/.*",
"^erts.*/bin/(dialyzer|typer)"
]},
{excl_archive_filters, ["^ebin$","^include$","^priv$"]},

{app, sasl, [{incl_cond, include}]},
{app, eunit, [{incl_cond, include}]}
Expand Down
13 changes: 12 additions & 1 deletion rel/reltool_webmachine.config
@@ -1,3 +1,5 @@
%% vim: ts=4 sw=4 et ft=erlang

{sys, [
{lib_dirs, ["../deps"]},
{rel, "nitrogen", "2.0.4",
Expand All @@ -7,7 +9,13 @@
sasl,
inets,
crypto,
runtime_tools
runtime_tools,
xmerl,
compiler,
ssl,
mnesia,
common_test,
parsetools
]},
{rel, "start_clean", "",
[
Expand All @@ -20,6 +28,9 @@
"^bin/.*",
"^erts.*/bin/(dialyzer|typer)"
]},
%% Webmachine needs to compile with file.hrl and it freaks out if the .app file
%% is included in the archive. So we exclude the ebin from the ez files.
{excl_archive_filters, ["^ebin$","^include$","^priv$"]},
{app, sasl, [{incl_cond, include}]},
{app, eunit, [{incl_cond, include}]}
]}.
Expand Down

0 comments on commit eb72c52

Please sign in to comment.