Produits Support Open Source Company
 
 
 
Home > Wiki > ejabberd HTTP request handlers

Article - Talk ejabberd HTTP request handlers

The web server embedded in ejabberd can be extended by writing your own
modules.

Tutorial

Assume that you want to write a simple “mod_http_hello” module to handle
all requests whose URL path begins with ”/hello”, such as:

  • http://localhost:5280/hello/world
  • http://localhost:5280/hello/hedgehog

Start by writing a “mod_http_hello.erl” file that contains request
handlers, which are clauses of the process/2 function. For
example, to handle a request with the ”/hello/world” path:

process(_LocalPath = ["world"], _Request) ->
    
{xmlelement, "html", [{"xmlns", "http://www.w3.org/1999/xhtml"}],
     
[{xmlelement, "head", [],
       
[{xmlelement, "title", [], []}]},
      
{xmlelement, "body", [],
       
[{xmlelement, "p", [], [{xmlcdata, "Hello, world!"}]}]}]};

(Note that the “hello” part is not taken care of here, since it’s common to all handlers.)

The entire mod_http_hello.erl file would look like:

%%%----------------------------------------------------------------------
%%%
File    : mod_http_hello.erl
%%% Author  : Your Name <your [at] email [dot] org>
%%%
Purpose : Sample module that extends embedded ejabberd HTTP server
%%% Created :
%%%
Id      :
%%%----------------------------------------------------------------------

-
module(mod_http_hello).
-
author('your@email.org').
-
vsn('').
-
define(ejabberd_debug, true).

-
behaviour(gen_mod).

-
export([
    start
/2,
    
stop/1,
    
process/2
    ]
).

-include(
"ejabberd.hrl").
-include(
"jlib.hrl").
-include(
"ejabberd_http.hrl").

%%%----------------------------------------------------------------------
%%%
REQUEST HANDLERS
%%%----------------------------------------------------------------------

process(["world"], _Request) ->
    
{xmlelement, "html", [{"xmlns", "http://www.w3.org/1999/xhtml"}],
     
[{xmlelement, "head", [],
       
[{xmlelement, "title", [], []}]},
      
{xmlelement, "body", [],
       
[{xmlelement, "p", [], [{xmlcdata, "Hello, world!"}]}]}]};

process(["produce_error"], _Request) ->
    
{400, [], {xmlelement, "h1", [],
               
[{xmlcdata, "400 Bad Request"}]}};

process(LocalPath, _Request) ->
    
{xmlelement, "html", [{"xmlns", "http://www.w3.org/1999/xhtml"}],
     
[{xmlelement, "head", [],
       
[{xmlelement, "title", [], []}]},
      
{xmlelement, "body", [],
       
[{xmlelement, "p", [], [{xmlcdata, io_lib:format("Called with path: ~p", [LocalPath])}]}]}]}.

%%%----------------------------------------------------------------------
%%%
BEHAVIOUR CALLBACKS
%%%----------------------------------------------------------------------

start(_Host, _Opts) ->
    
ok.

stop(_Host) ->
    
ok.

Modify ejabberd.cfg so that mod_http_hello is loaded when ejabberd starts:

{modules,
[
  
%% ...
  
{mod_http_hello, []},
  %% ...
]}.

Also in ejabberd.cfg, configure ejabberd_http so that it dispatches requests beginning with ”/hello/” to mod_http_hello:

{5280, ejabberd_http,    [http_poll, web_admin,
                          
{request_handlers, [{["hello"], mod_http_hello}]}]}

API

Apart from callbacks required by gen_mod, your module only has to implement (one or more clauses of) process/2:

  • your_http_module:process(LocalPath, Request)

The process/2 function handles an HTTP request. It returns the data to be sent back to the client, optionally with a status code and additional headers.

process/2 will be called with two arguments: LocalPath and Request.

The LocalPath argument is a list containing the part of the requested URL path that is “local to the module”.

Example: mod_foo was configured in ejabberd.cfg to handle requests whose path begins with ”/a/b”:

{5280, ejabberd_http,    [http_poll, web_admin,
                  
{request_handlers, [{["a", "b"], mod_foo}]}]}

User requests the URL:

http://server:5280/a/b/c/d

Path “local to the module” will be:

["c", "d"]

Usually you will want to select a handler based on the local path instead of the full path (Request#request.path), so that server administrators can make the module available under the path prefix of their choice.

The Request argument is a record containing information about the HTTP request as defined in ejabberd_http.hrl. It consists of the following fields:

{
  
"request",
  
method,    %% HTTP method ("GET" or "POST")
  
path,      %% Full path to requested resource
             
%% e.g. for "http://server:5280/a/b/c/d": ["a", "b", "c", "d"]
  q
,         %% Query part of the URL
             
%% e.g. for "http://server:5280/a/b/c/d?foo=bar": [{"foo", "bar"}]
  us
,        %% Authenticated user and server.  Used in ejabberd_web_admin for now.
             %%
e.g. for "foo@jabber.server.org": {"foo", "jabber.server.org"}
  auth
,      %% Information provided for HTTP-auth (if any)
             %%
e.g. for a user "john" who entered the password "secret": {"john", "secret"}
  lang
= "", %% Language code
  data
= "", %% POST data
}

 
 
 
Valid HTML 4.01!   Valid CSS!