What is Megaphone?

What is Megaphone?
The Megaphone project is about enhancing open source chat software. Specifically, the goal is to allow ejabberd to support 1,000,000 simultaneous users. See The Plan page for more details on how I plan to solve this problem. See the About this Blog page for more details on why I created this blog.

Monday, January 9, 2012

The Case of the Missing Data

Previously...
  • I resolved a problem with erlang processes and TCP sockets.
  • I identified a problem where the megaphone_socket process was not being started.
  • I identified a problem where data was going into ejabberd_http but not coming out.
I put some debugging statements in ejabberd_http:receive_headers and yes, it appears that the data is making it into the system.  The code around that area is interesting for example:

receive_headers(State) ->
    SockMod = State#state.sockmod,
    Socket = State#state.socket,
    Data = SockMod:recv(Socket, 0, 300000),
    case State#state.sockmod of
    gen_tcp ->
        NewState = process_header(State, Data),
        case NewState#state.end_of_request of
            true -> ok;
            _ -> receive_headers(NewState)
        end;
    _ ->
        case Data of
        {ok, Binary} ->
            {Request, Trail} = parse_request(
                     State,
                     State#state.trail ++ binary_to_list(Binary)),
            State1 = State#state{trail = Trail},
            NewState = lists:foldl(
                 fun(D, S) ->
                    case S#state.end_of_request of
                        true -> S;
                        _ -> process_header(S, D)
                    end
                 end, State1, Request),
            case NewState#state.end_of_request of
                true -> ok;
                _ -> receive_headers(NewState)
            end;
        _ ->
            ok
        end
    end.

In particular, if the socket module is not gen_tcp, then the code assumes that the data returned is of the form 

{ok, Binary} 

If it turns out that it is not, then the following case is used:

_ -> ok

This would explain how the data was appearing to disappear when it got to ejabberd.  Taking a look at the process_header function, it expects the data to be in one of the following forms:

{ok, {http_request, Method, Uri, Version}}
{ok, {http_header, _, 'Connection'=Name, _, Conn}}
{ok, {http_header, _, 'Authorization'=Name, _, Auth}}
{ok, {http_header, _, 'Content-Length'=Name, _, SLen}}
{ok, {http_header, _, 'Accept-Language'=Name, _, Langs}}
{ok, {http_header, _, 'Host'=Name, _, Host}}
{ok, {http_header, _, Name, _, Value}}
{ok, http_eoh} when State#state.request_host == undefined
{ok, http_eoh}
{error, _Reason}

I had not known this so it looks like it's back to work for me to get megaphone_socket or some such into the correct form.

Sigh.


No comments:

Post a Comment