venerdì, 04 aprile 2008
To add cookies to HTTP POST/GET requests in ejabberd (1.1.x and 2.x) we have to add some fields in the request headers, setting up the request and state records in ejabberd_http.erl module and its header file ejabberd_http.hrl.

First of all, we will add the field cookie to the record request in ejabberd_http.hrl header file as follows:

-record(request, {method,
                  path,
                  q = [],
                  us,
                  auth,
                  lang = "",
                  data = "",
                  cookie = "", %% lp: cookie request field
                  ip
                 }).


As you can see we are referring to ejabberd 2.0 (in the request record we have the new field ip for new user info).

Now we will edit the ejabberd_http.erl module, adding the field request_cookie to the record state:

-record(state, {sockmod,
                socket,
                request_method,
                request_version,
                request_path,
                request_auth,
                request_cookie, %% lp: cookie request field
                request_keepalive,
                (...)

 
At this point, we have to pass cookies to handlers, modifying the process_headers and process_request functions:

In the process_header, we will add to the case construct

process_header(State, Data) ->
    SockMod = State#state.sockmod,
    Socket = State#state.socket,
    case Data of
        {ok, {http_request, Method, Uri, Version}} ->
   
    (...)
        {ok, {http_header, _, 'Authorization', _, Auth}} ->
            State#state{request_auth = parse_auth(Auth)};
        {ok, {http_header, _, 'Cookie', _, Cookie}} ->
            %% lp: setting up request header cookie
            State#state{request_cookie = Cookie};
        {ok, {http_header, _, 'Content-Length', _, SLen}} ->
    (...)


In the process_request we have to modify the function header as follows:

process_request(#state{request_method = 'GET',
                       request_path = {abs_path, Path},
                       request_auth = Auth,
                       request_lang = Lang,
                       request_cookie = Cookie, %% lp: cookie request field
                       request_handlers = RequestHandlers,
                       sockmod = SockMod,
                       socket = Socket} = State) ->
                       
                        (...)
                        Request = #request{method = 'GET',
                               path = LPath,
                               q = LQuery,
                               auth = Auth,
                               lang = Lang,
                               cookie = Cookie, %% lp: here again :)
                               ip=IP},
                        (...)


and in the next header too:

process_request(#state{request_method = 'POST',
                       request_path = {abs_path, Path},
                       request_auth = Auth,
                       request_content_length = Len,
                       request_lang = Lang,
                       request_cookie = Cookie, %% lp: cookie
                       sockmod = SockMod,
                       socket = Socket,
                       request_handlers = RequestHandlers} = State)
  when is_integer(Len) ->

              (...)
              Request = #request{method = 'POST',
                               path = LPath,
                               q = LQuery,
                               auth = Auth,
                               cookie = Cookie, %% lp: cookie the last one ;)
                               data = Data,
                               lang = Lang},
              case process(RequestHandlers, Request) of
                 (...)


Now, we are ready to add the cookie request's field to our modules processing http requests:

process(#request{us = _US,
                     path = "login",
                     q = _Query,
                     lang = _Lang,
                     cookie = _Cookie} = Request) ->
          
              %% _Cookie will contain the request cookie now
              %% Manage request by cookies
              %% Send response :)



I will eventually post a addon patch for this :)

Enjoy your Jabber,
LP


PS. We used ejabberd 2.0, but you can do this in ejabberd 1.1.x in the same way


Links:
http://www.process-one.net/en/wiki/ejabberd_module_development/
posted() loretoparisi times() 18:05 | Permalink | commenti
Commenti
| commenti (popup)
cookie, request headers