# mochicow

mochicow is a mochiweb adapter for [cowboy](

There are 2 ways to use mochicow:

- as a ranch protocol: It will use the socket acceptor pool of ranch
  instead of the mochiweb one.

- as a protocol upgrade. Like websockets you can upgrade a cowboy
  handler to use a mochiweb loop. It allows you to use both cowboy and 
  mochiweb in your code.

## Use the ranch socket pool with mochiweb

To use mochiweb with the ranch acceptor pool, you just need to use the
`mochicow_protocol` module as the prococol when you start a cowboy
listener. You pass the mochiweb `loop` in the protocol options via the
`loop` property.



-export([start/0, stop/0, loop/1]).
-define(LOOP, {?MODULE, loop}).

start() ->
    {ok, _} = application:ensure_all_started(ranch),
    ranch:start_listener(http, 100,
                          ranch_tcp, [{port, 8000}],
                          mochicow_protocol, [{loop, ?LOOP}]).

stop() ->

loop(Req) ->
    Path = Req:get(path),
    Resource = case string:str(Path, "?") of
        0 -> Path;
        N -> string:substr(Path, 1, length(Path) - (N + 1))
    handle_request(Resource, Req).

handle_request("/hello", Req) ->
    Req:respond({200, [{"Content-Type", "text/html"}], <<"Hello to you as well">>});

handle_request(Path, Req) ->
    Get = Req:parse_qs(),
    Post = Req:parse_post(),
    User_agent = Req:get_header_value("user-agent"),
    erlang:display({get, Get}),
    erlang:display({post, Post}),
    erlang:display({user_agent, User_agent}),
    erlang:display({path, Path}),
    Req:respond({200, [{"Content-Type", "text/html"}], <<"Hello World!">>}).

## Upgrade the protocol

You can use mochicow to quietly migrate your code from mochiweb to
cowboy or use both at the sametime. To do that you will need to use the
upgrade "sub-protocol" using `mochicow_upgrade` as the protocol and compile 
your code and the following option added to the erlang compiler flags:

{parse_transform, mochicow}

Alternately, you can add it to the module you wish to use with mochiweb:

-compile([{parse_transform, mochicow}]).

> the mochicow parse_transform will replace at compilation any call to 
mochiweb_request by calls to mochicow_request. This is needed due to the way 
cowboy handle the first steps of the request keeping a buffer around. 

### Ex to start the cowboy_http_protocol:

-export([start/0, stop/0]).

-define(LOOP, {mochi_handler, loop}).

start() ->
    {ok, _} = application:ensure_all_started(cowboy),
     Dispatch = cowboy_router:compile([

        {'_', [
               {'_', mochi_hello_handler, [{loop, {mochi_hello_handler, loop}}]}

    cowboy:start_http(http, 100,  [{port, 8080}], 
                      [{env, [{dispatch, Dispatch}]} ]).

stop() ->

### The mochiweb handler:

-export([init/3, loop/1]).

init(_, _, _) ->
    {upgrade, protocol, mochicow_upgrade}.

loop(Req) ->
    Req:respond({200, [{"Content-Type", "text/html"}],
                 <<"Hello from mochiweb">>}).

### Usage example

See more usage examples in the `examples` for the usage. For example launch the
`hello_cowboy` application:

[upgrade_demo] rebar3 shell                                                                            2:39:25  ☁  master ☂ ⚡ ✭
===> Verifying dependencies...
===> Compiling mochicow
===> Compiling upgrade_demo
Erlang/OTP 18 [erts-7.3.1] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:0] [kernel-poll:false]

Eshell V7.3.1  (abort with ^G)
1> hello_cowboy:start().

And query the server you just launched:

An echo server running a mochiweb handler (`mochi_echo_handler`)

[~] curl -XPOST http://localhost:8080/echo -d'test echo'               2:39:50
test echo

A simple mochiweb handler `mochi_hello_handler` returning "hello":
[~] curl  http://localhost:8080/hello                                  9:30:22
Hello from mochiweb

The server is mixed with a cowboy habdler `cowboy_hello_handler`:
[~] curl  http://localhost:8080                                        9:32:04
Hello World!