<html>
  <head>
    <meta content="text/html; charset=windows-1252"
      http-equiv="Content-Type">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    Hi,<br>
    <br>
    I found the solution.<br>
    I had to switch to raw mode after http_eoh and do a gen_tcp:recv/3
    wih 'Content-Length'<br>
    <br>
    <div class="moz-cite-prefix">Am 10.03.2015 um 22:33 schrieb Matthias
      Lersch:<br>
    </div>
    <blockquote cite="mid:54FF633C.1040103@kairion.de" type="cite">
      <meta http-equiv="Content-Type" content="text/html;
        charset=windows-1252">
      <div class="moz-text-flowed" style="font-family: -moz-fixed;
        font-size: 12px;" lang="x-unicode">Hi, <br>
        <br>
        I have a problem with gen_tcp:recv... <br>
        The Body of the first call is missing but shows up at the second
        call causing a http_error. (full code is shown a the end of the
        mail) <br>
        <br>
        I do a gen_tcp:connect/4 with the options <br>
        [list, {mode, list}, {reuseaddr, true}, {active, false},
        {keepalive, true}, {packet, http}, {send_timeout,
        timer:seconds(2)}] <br>
        <br>
        Then i send a HTTP POST request using gen_tcp:send/2 and go into
        a "receve loop" with gen_tcp:recv/3 until i get a {error,_} 
        (thats for debugging at the moment and recv timout is set to 10
        seconds) <br>
        <br>
        my problem is: <br>
        - On the first call (send) i get all the headers but no content.
        <br>
        - On the second call i get the content of the first call at the
        beginning of the response causing the http_error. <br>
        <br>
        <br>
        I'm sending the request to a node.js service, but the result is
        the same if i use a dummy apache service with the same response.
        <br>
        So i don't think its a problem with the Server I'm sending the
        request to. <br>
        The Body of the response (aka content) is always "OK" <br>
        <br>
        The received data from the first call looks like this (there is
        no body with "OK", it ends with http_eoh and then a timeout
        after 10 seconds) : <br>
        <br>
         {ok,{http_response,{1,1},200,"OK"}} <br>
         {ok,{http_header,0,"X-Powered-By",undefined,"Express"}} <br>
         {ok,{http_header,42,'Content-Type',undefined,"text/html;
        charset=utf-8"}} <br>
         {ok,{http_header,38,'Content-Length',undefined,"2"}} <br>
         {ok,{http_header,3,'Date',undefined,"Tue, 10 Mar 2015 20:23:05
        GMT"}} <br>
         {ok,{http_header,2,'Connection',undefined,"keep-alive"}} <br>
         {ok,http_eoh} <br>
            ...after 10 seconds... <br>
         {error,timeout} <br>
        <br>
        The second call then returns this (notice the OKHTTP/1.1... in
        the first row, "OK" is the Body from the call before. It should
        be HTTP/1.1): <br>
        <br>
         {ok,{http_error,"OKHTTP/1.1 200 OK\r\n"}} <br>
         {ok,{http_error,"X-Powered-By: Express\r\n"}} <br>
         {ok,{http_error,"Content-Type: text/html; charset=utf-8\r\n"}}
        <br>
         {ok,{http_error,"Content-Length: 2\r\n"}} <br>
         {ok,{http_error,"Date: Tue, 10 Mar 2015 20:23:16 GMT\r\n"}} <br>
         {ok,{http_error,"Connection: keep-alive\r\n"}} <br>
         {ok,{http_error,"\r\n"}} <br>
            ...after 10 seconds... <br>
         {error,timeout} <br>
        <br>
        <br>
        <br>
        here is the gen_server code im using for my tests. <br>
        i run the test like this from the erl command line <br>
        s:start_link(). <br>
        s:work(1,1). % first call without body <br>
        s:work(1,1). % second call that fails <br>
        <br>
        Thanky for your help! <br>
        <br>
        <br>
        %%%-------------------------------------------------------------------

        <br>
        %%% @author mlersch <br>
        %%% @copyright (C) 2015, <COMPANY> <br>
        %%% @doc <br>
        %%% <br>
        %%% @end <br>
        %%% Created : 20. Feb 2015 11:13 <br>
        %%%-------------------------------------------------------------------

        <br>
        -module(s). <br>
        -author("mlersch"). <br>
        <br>
        %% API <br>
        -compile(export_all). <br>
        <br>
        -behaviour(gen_server). <br>
        <br>
        %% API <br>
        -export([ <br>
          start_link/0, <br>
          send/2, <br>
          reconnect/4]). <br>
        <br>
        %% gen_server callbacks <br>
        -export([init/1, <br>
          handle_call/3, <br>
          handle_cast/2, <br>
          handle_info/2, <br>
          terminate/2, <br>
          code_change/3]). <br>
        <br>
        -define(SERVER, ?MODULE). <br>
        <br>
        -record(state, { <br>
          connection=false, <br>
          host, <br>
          port, <br>
          timeout, <br>
          opts <br>
        }). <br>
        <br>
        <br>
        %%%===================================================================

        <br>
        %%% API <br>
        %%%===================================================================

        <br>
        <br>
        send(Processor, Data)-> <br>
          gen_server:call(?MODULE, {send, Processor, Data}). <br>
        <br>
        info()-> <br>
          gen_server:call(?MODULE,info). <br>
        <br>
        %%--------------------------------------------------------------------

        <br>
        %% @doc <br>
        %% Starts the server <br>
        %% <br>
        %% @end <br>
        %%--------------------------------------------------------------------

        <br>
        -spec(start_link() -> <br>
          {ok, Pid :: pid()} | ignore | {error, Reason :: term()}). <br>
        start_link() -> <br>
          process_flag(trap_exit, true), <br>
          io:format("~p Start~n",[?MODULE]), <br>
          gen_server:start_link({local, ?SERVER}, ?MODULE, [], []). <br>
        <br>
        %%%===================================================================

        <br>
        %%% gen_server callbacks <br>
        %%%===================================================================

        <br>
        <br>
        %%--------------------------------------------------------------------

        <br>
        %% @private <br>
        %% @doc <br>
        %% Initializes the server <br>
        %% <br>
        %% @spec init(Args) -> {ok, State} | <br>
        %%                     {ok, State, Timeout} | <br>
        %%                     ignore | <br>
        %%                     {stop, Reason} <br>
        %% @end <br>
        %%--------------------------------------------------------------------

        <br>
        -spec(init(Args :: term()) -> <br>
          {ok, State :: #state{}} | {ok, State :: #state{}, timeout() |
        hibernate} | <br>
          {stop, Reason :: term()} | ignore). <br>
        init([]) -> <br>
        <br>
          State = #state{ <br>
            host = "localhost", <br>
            port = 9010, <br>
            timeout = timer:seconds(2), <br>
            opts = [list, {mode, list}, {reuseaddr, true}, {active,
        true}, {keepalive, true}, {packet, http}, {send_timeout,
        timer:seconds(2)}] <br>
          }, <br>
        <br>
          reconnect(State), <br>
          {ok, State}. <br>
        <br>
        %%--------------------------------------------------------------------

        <br>
        %% @private <br>
        %% @doc <br>
        %% Handling call messages <br>
        %% <br>
        %% @end <br>
        %%--------------------------------------------------------------------

        <br>
        -spec(handle_call(Request :: term(), From :: {pid(), Tag ::
        term()}, <br>
            State :: #state{}) -> <br>
          {reply, Reply :: term(), NewState :: #state{}} | <br>
          {reply, Reply :: term(), NewState :: #state{}, timeout() |
        hibernate} | <br>
          {noreply, NewState :: #state{}} | <br>
          {noreply, NewState :: #state{}, timeout() | hibernate} | <br>
          {stop, Reason :: term(), Reply :: term(), NewState ::
        #state{}} | <br>
          {stop, Reason :: term(), NewState :: #state{}}). <br>
        <br>
        handle_call({send, Processor, Data}, From, State) -> <br>
        <br>
          % If we are offline, notify the caller <br>
          case State#state.connection of <br>
        <br>
            {ok,Con}-> <br>
        <br>
              Request = <br>
                ["POST /" ++ Processor ++ " HTTP/1.1\r\n" <br>
                  ++ "Content-Length: " ++
        integer_to_list(lists:flatlength(Data)) ++ "\r\n" <br>
                  ++ "User-Agent: Erlang Client\r\n" <br>
                  ++ "Content-Type: application/json\r\n" <br>
                  ++ "Host: " ++ State#state.host ++ "\r\n" <br>
                  ++ "Accept: */*\r\n" <br>
                  ++ "\r\n", [Data]], <br>
        <br>
                % Try sending the data <br>
                case send_and_receive(Con, Request) of <br>
                  ok -> {reply, ok, State}; <br>
        <br>
                  % If sending fails... <br>
                  Error -> <br>
                    % ...Answer the Client with a error <br>
                    gen_server:reply(From, error), <br>
                    io:format("~p Error: ~p~n", [?MODULE, Error]), <br>
        <br>
                    % ...Close the connection <br>
                    gen_tcp:close(Con), <br>
                    timer:sleep(500), <br>
        <br>
                    % ...Spawn a Process that trys to reconnect. <br>
                    reconnect(State), <br>
        <br>
                    % ...Update the connection state <br>
                    {reply, error, State#state{connection = false}} <br>
        <br>
                end; <br>
        <br>
              _ -> {reply, offline, State} <br>
          end; <br>
        <br>
        handle_call(info, _From, State) -> <br>
          {reply, State, State}; <br>
        <br>
        handle_call(Request, _From, State) -> <br>
          io:format("~p CALL: ~p~n", [?MODULE, Request]), <br>
          {reply, ok, State}. <br>
        <br>
        %%--------------------------------------------------------------------

        <br>
        %% @private <br>
        %% @doc <br>
        %% Handling cast messages <br>
        %% <br>
        %% @end <br>
        %%--------------------------------------------------------------------

        <br>
        -spec(handle_cast(Request :: term(), State :: #state{}) -> <br>
          {noreply, NewState :: #state{}} | <br>
          {noreply, NewState :: #state{}, timeout() | hibernate} | <br>
          {stop, Reason :: term(), NewState :: #state{}}). <br>
        handle_cast({connected, Connection}, State) -> <br>
          io:format("~p Connected: ~p~n", [?MODULE, Connection]), <br>
          {noreply, State#state{connection = Connection}}; <br>
        <br>
        handle_cast(Request, State) -> <br>
          io:format("~p CAST: ~p~n", [?MODULE, Request]), <br>
          {noreply, State}. <br>
        <br>
        %%--------------------------------------------------------------------

        <br>
        %% @private <br>
        %% @doc <br>
        %% Handling all non call/cast messages <br>
        %% <br>
        %% @spec handle_info(Info, State) -> {noreply, State} | <br>
        %%                                   {noreply, State, Timeout} |
        <br>
        %%                                   {stop, Reason, State} <br>
        %% @end <br>
        %%--------------------------------------------------------------------

        <br>
        -spec(handle_info(Info :: timeout() | term(), State :: #state{})
        -> <br>
          {noreply, NewState :: #state{}} | <br>
          {noreply, NewState :: #state{}, timeout() | hibernate} | <br>
          {stop, Reason :: term(), NewState :: #state{}}). <br>
        <br>
        handle_info({tcp_closed, _}, State) -> <br>
          io:format("~p Connection closed!~n", [?MODULE]), <br>
          reconnect(State), <br>
          {noreply, State#state{connection = false}}; <br>
        <br>
        handle_info(Info, State) -> <br>
          io:format("~p INFO: ~p~n", [?MODULE, Info]), <br>
          {noreply, State}. <br>
        <br>
        %%--------------------------------------------------------------------

        <br>
        %% @private <br>
        %% @doc <br>
        %% This function is called by a gen_server when it is about to <br>
        %% terminate. It should be the opposite of Module:init/1 and do
        any <br>
        %% necessary cleaning up. When it returns, the gen_server
        terminates <br>
        %% with Reason. The return value is ignored. <br>
        %% <br>
        %% @spec terminate(Reason, State) -> void() <br>
        %% @end <br>
        %%--------------------------------------------------------------------

        <br>
        -spec(terminate(Reason :: (normal | shutdown | {shutdown,
        term()} | term()), <br>
            State :: #state{}) -> term()). <br>
        terminate(Reason, _State) -> <br>
          io:format("~p TERMINATE: ~p~n", [?MODULE, Reason]), <br>
          ok. <br>
        <br>
        %%--------------------------------------------------------------------

        <br>
        %% @private <br>
        %% @doc <br>
        %% Convert process state when code is changed <br>
        %% <br>
        %% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}
        <br>
        %% @end <br>
        %%--------------------------------------------------------------------

        <br>
        -spec(code_change(OldVsn :: term() | {down, term()}, State ::
        #state{}, <br>
            Extra :: term()) -> <br>
          {ok, NewState :: #state{}} | {error, Reason :: term()}). <br>
        code_change(_OldVsn, State, _Extra) -> <br>
          {ok, State}. <br>
        <br>
        %%%===================================================================

        <br>
        %%% Internal functions <br>
        %%%===================================================================

        <br>
        <br>
        <br>
        <br>
        %% This helper function sends the request to the server and
        parses the response <br>
        %% to look in it for a status 200 code. If it finds a 200 we
        return ok otherwise error. <br>
        %% by default we use active connections, when we are in idle to
        get info messages about <br>
        %% deconnections into handle_info/2 <br>
        %% but here we must change to passive mode, so we are able to
        parse the response of this <br>
        %% send operations. disconnect messages wont show up in passive
        mode but will pop up when <br>
        %% we switch bach to active mode again (even if the ocured
        during passive mode). <br>
        send_and_receive(Con, Request)-> <br>
          inet:setopts(Con, [{active, false}]), <br>
          Response = <br>
          case gen_tcp:send(Con, Request) of <br>
            ok -> parse_response(Con); <br>
            E -> E <br>
          end, <br>
          inet:setopts(Con, [{active, true}]), <br>
          Response. <br>
        <br>
        <br>
        parse_response(Con)->parse_response(Con, error). <br>
        parse_response(Con, State)-> <br>
          R = gen_tcp:recv(Con, 0, timer:seconds(10)), <br>
          io:format("PR: ~p~n",[R]), <br>
          case R of <br>
            {ok,{http_response,_,200,_}} -> parse_response(Con, ok);
        <br>
            {ok,http_eoh} -> <br>
              io:format("PRX: ~p~n",[gen_tcp:recv(Con, 0,
        timer:seconds(10))]), <br>
              State; <br>
            {error, E} -> {error, E}; <br>
            _ -> parse_response(Con, State) <br>
          end. <br>
        <br>
        reconnect(State)-> <br>
          spawn_link(?MODULE, reconnect, [self(), State,
        calendar:local_time(), 1]). <br>
        <br>
        reconnect(Pid, State, Started, Tries)-> <br>
          io:format("~p Connecting to host ~p on port ~p~n",[?MODULE,
        State#state.host, State#state.port]), <br>
          case gen_tcp:connect(State#state.host, State#state.port,
        State#state.opts, State#state.timeout) of <br>
            {ok, Connection} -> <br>
              io:format("~p Reconnect changing controlling process:
        ~p~n",[?MODULE, gen_tcp:controlling_process(Connection, Pid)]),
        <br>
              gen_server:cast(?MODULE, {connected, {ok, Connection}}); <br>
            E -> io:format("~p Reconnection failed ~p (Tried it ~p
        times since ~p). Waiting 2sec. till retry!~n", [?MODULE, E,
        Tries, Started]), <br>
                 timer:sleep(timer:seconds(2)), <br>
                 reconnect(Pid, State, Started, Tries+1) <br>
          end. <br>
        <br>
        <br>
        <br>
        %%%===================================================================

        <br>
        %%% Debug stuff <br>
        %%%===================================================================

        <br>
        loop(Max)-> <br>
          lists:foreach(fun(_)-> <br>
            timer:sleep(100), <br>
              spawn(fun()-> <br>
                send("processgaac",
        "{\"_id\":{\"$oid\":\"53B382F4BE53EE3946137430\"},\"sid\":\"07101a57ce294750bb36fa72e2ffab5d\",\"eid\":1566,\"cd\":{\"$date\":1404273396000},\"t\":\"gaac\",\"p\":{\"ua\":\"Mozilla/5.0


        (Windows NT 6.3; WOW64; rv:30.0) Gecko/20100101
Firefox/30.0\",\"pt\":\"search_result\",\"rt\":\"internal\",\"gs\":[{\"g\":\"08006309\",\"p\":1650},{\"g\":\"04431464\",\"p\":1429},{\"g\":\"03932773\",\"p\":696},{\"g\":\"07563999\",\"p\":825},{\"g\":\"09100275\",\"p\":5089},{\"g\":\"06426800\",\"p\":2240},{\"g\":\"10417853\",\"p\":1180},{\"g\":\"02096458\",\"p\":1365},{\"g\":\"08798173\",\"p\":3897},{\"g\":\"03531850\",\"p\":1243},{\"g\":\"00188357\",\"p\":412},{\"g\":\"09296203\",\"p\":2495},{\"g\":\"05566143\",\"p\":1498},{\"g\":\"08006456\",\"p\":1467},{\"g\":\"04347717\",\"p\":2199},{\"g\":\"08006410\",\"p\":4499},{\"g\":\"09374110\",\"p\":3897},{\"g\":\"04187656\",\"p\":691},{\"g\":\"05010397\",\"p\":1075},{\"g\":\"07727923\",\"p\":493}],\"cats\":[\"1100068\",\"1100068\",\"1100068\",\"1100071\",\"1100043\",\"1100015\",\"1100015\",\"1100029\",\"1100355\",\"1100355\",\"1100196\",\"1100114\",\"1100013\",\"1100021\",\"1100021\",\"1100021\",\"1100021\",\"1100021\",\"1100170\",\"1571\",\"1100014\",\"1100117\",\"1100233\",\"1100107\",

\"1100096\",\"1100467\",\"1100094\",\"1100094\",\"1100013\",\"1100014\",\"1100014\",\"1100029\",\"1100015\",\"1100015\",\"1100017\",\"1100463\",\"1100034\",\"1100109\",\"1440\",\"1100114\",\"1100109\",\"1440\",\"1100177\",\"1100013\",\"1100191\",\"1100094\",\"1100191\",\"1100029\",\"1100029\",\"1100048\",\"1100043\",\"1100016\",\"1100210\",\"1100016\",\"1100463\",\"1226\"],\"catsc\":[\"AR02AA16\",\"79680\",\"22172\",\"30365\",\"AR01AC03\",\"24009\",\"79658\",\"66403\",\"30365\",\"22294\",\"BX01\",\"71445\",\"81085\",\"24510\",\"30365\",\"22294\",\"AD11AX01\",\"82323\",\"30365\",\"22294\",\"30365\",\"22294\",\"BB03Z\",\"81644\",\"81629\",\"25123\",\"22183\",\"22182\",\"30365\",\"30365\",\"BB01A\",\"24577\",\"66407\",\"30365\",\"AD01AE16\",\"30365\",\"AD08AC\",\"24512\",\"22206\",\"30365\",\"AN05CX\",\"81736\",\"22192\",\"30365\",\"BB03Z\",\"77677\",\"66409\",\"66407\",\"30365\",\"BX01\",\"71446\",\"79609\",\"22171\",\"30365\",\"BC01D\",\"30365\",\"BB03D\",\"82323\",\"25125\",\"22204\",

\"30365\",\"22294\",\"AD11AX01\",\"82997\",\"82323\",\"25125\",\"22204\",\"32455\",\"30365\",\"22294\",\"BB03Z\",\"24783\",\"81736\",\"81083\",\"81082\",\"81087\",\"39604\",\"30365\",\"AS01GX07\",\"24009\",\"22220\",\"22196\",\"79610\",\"30365\",\"22294\",\"BC01D\",\"24728\",\"30365\",\"23432\",\"30365\"],\"catsx\":[\"30365\",\"30365\",\"22294\",\"30365\",\"22294\",\"82323\",\"30365\",\"22294\",\"30365\",\"22294\",\"30365\",\"30365\",\"30365\",\"30365\",\"30365\",\"30365\",\"77677\",\"30365\",\"30365\",\"30365\",\"82323\",\"30365\",\"22294\",\"82997\",\"82323\",\"30365\",\"22294\",\"39604\",\"30365\",\"30365\",\"22294\",\"30365\",\"23432\",\"30365\"],\"fpid\":\"/aktionsartikel\",\"lt\":\"list\",\"lp\":1},\"r\":{\"s\":[{\"slid\":\"high\",\"cid\":2498,\"scr\":100000000,\"f\":1}]},\"ti\":200000000,\"to\":false,\"at\":53596,\"dv\":8,\"agg\":[],\"pad\":\"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"}")<br>
              end) <br>
            end, <br>
            lists:seq(1,Max)). <br>
        <br>
        work(Loops, Max)-> <br>
          lists:foreach(fun(_)-> spawn(s,loop,[Max])
        end,lists:seq(1,Loops)). <br>
        <br>
        <div class="moz-txt-sig"><span class="moz-txt-tag">-- <br>
          </span>________________________________________ <br>
          Matthias Lersch, Senior Software Architect <br>
          Tel.: +49 69 972 69 197; Fax: +49 69 972 69 204; Email: <a
            moz-do-not-send="true" class="moz-txt-link-abbreviated"
            href="mailto:matthias.lersch@kairion.de">matthias.lersch@kairion.de</a>
          <br>
          Kairion GmbH, Gutleutstraße 30, D-60329 Frankfurt <br>
          Internet: <a moz-do-not-send="true"
            class="moz-txt-link-freetext" href="http://www.kairion.de">http://www.kairion.de</a>
          <br>
          <br>
          <br>
        </div>
      </div>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <br>
      <pre wrap="">_______________________________________________
erlang-questions mailing list
<a class="moz-txt-link-abbreviated" href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a>
<a class="moz-txt-link-freetext" href="http://erlang.org/mailman/listinfo/erlang-questions">http://erlang.org/mailman/listinfo/erlang-questions</a>
</pre>
    </blockquote>
    <br>
    <pre class="moz-signature" cols="72">-- 
________________________________________
Matthias Lersch, Senior Software Architect
Tel.: +49 69 972 69 197; Fax: +49 69 972 69 204; Email: <a class="moz-txt-link-abbreviated" href="mailto:matthias.lersch@kairion.de">matthias.lersch@kairion.de</a>
Kairion GmbH, Gutleutstraße 30, D-60329 Frankfurt
Internet: <a class="moz-txt-link-freetext" href="http://www.kairion.de">http://www.kairion.de</a>
</pre>
  </body>
</html>