0
Fork 0
mirror of https://github.com/ninenines/cowboy.git synced 2025-07-14 12:20:24 +00:00
Small, fast, modern HTTP server for Erlang/OTP.
Find a file
Loïc Hoguin d0d9b0e8b3 Use a more efficient variant of string:to_lower to improve performance.
After much testing and experimentation of all kinds I find lists to be both
faster and using less memory than binaries for request-line and headers
handling. This is more than likely due to the fact that headers are very
short and thus do not benefit from the advantages of refc binaries, meaning
they're copied, just like lists. The memory usage discrepancy is still a
mystery for the most part, although the hoops needed to perform operations
on the binaries are probably responsible for the extra memory use.

I'm thus giving up on trying to use binaries for request-line and headers.
Instead, this commit improves performances even more to the lists code,
making lists 5% faster than binaries. Lists are easier to work with too,
so I guess it's all a big win for everyone.

Of course the request body is still read as a binary, we're using the
binary type where it performs best.
2011-03-27 01:16:11 +01:00
include Fix the type spec for qs_vals, a list of key/values. 2011-03-27 01:07:01 +01:00
src Use a more efficient variant of string:to_lower to improve performance. 2011-03-27 01:16:11 +01:00
.gitignore Initial commit. 2011-03-17 00:29:35 +01:00
LICENSE Initial commit. 2011-03-17 00:29:35 +01:00
Makefile Makefile: Use a REBAR variable 2011-03-23 10:54:09 +01:00
README.md Forward transport and protocol name to Handler:init. 2011-03-22 19:50:02 +01:00
rebar.config Add more dialyzer warnings to rebar.config. 2011-03-22 12:25:43 +01:00

Cowboy

Cowboy is a small, fast and modular HTTP server written in Erlang.

Goals

Cowboy aims to provide the following advantages:

  • Small codebase.
  • Damn fast.
  • Modular: transport, protocol and handlers are replaceable. (see below)
  • Easy to embed inside another application.
  • Selectively dispatch requests to handlers, allowing you to send some requests to your embedded code and others to a FastCGI application in PHP or Ruby.
  • No parameterized module. No process dictionary. Clean Erlang code.

The server is currently in early development stage. Comments, suggestions are more than welcome. To contribute, either open bug reports, or fork the project and send us pull requests with new or improved functionality. Of course you might want to discuss your plans with us before you do any serious work so we can share ideas and save everyone time.

Embedding Cowboy

  • Add Cowboy as a rebar dependency to your application.
  • Start Cowboy and add one or more listeners.
  • Write handlers.

Getting Started

Cowboy can be started and stopped like any other application. However the Cowboy application do not start any listener, those must be started manually.

A listener is a special kind of supervisor that handles a pool of acceptor processes. An acceptor simply accept connections and forward them to a protocol module, for example HTTP. You must thus define the transport and protocol module to use for the listener, their options and the number of acceptors in the pool before you can start a listener supervisor.

For HTTP applications the transport can be either TCP or SSL for HTTP and HTTPS respectively. On the other hand, the protocol is of course HTTP.

Code speaks more than words:

application:start(cowboy),
Dispatch = [
    %% {Host, list({Path, Handler, Opts})}
    {'_', [{'_', my_handler, []}]}
],
%% NbAcceptors, Transport, TransOpts, Protocol, ProtoOpts
cowboy_listener_sup:start_link(100,
    cowboy_tcp_transport, [{port, 8080}],
    cowboy_http_protocol, [{dispatch, Dispatch}]
).

You must also write the my_handler module to process requests. You can use one of the predefined handlers or write your own. An hello world HTTP handler could be written like this:

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

init({tcp, http}, Req, Opts) ->
    {ok, Req, undefined}.

handle(Req, State) ->
    {ok, Req2} = cowboy_http_req:reply(200, [], "Hello World!", Req),
    {ok, Req2, State}.

terminate(Req, State) ->
    ok.