Search code examples
apachehttperlanggen-serverinets

Erlang inets httpc connect to local inets httpd


I'm trying to implement a module with httpd, which handles HTTP get request for a process. Basically it handles the incoming get request, parses the get parameters and calls a synchronous gen_server method on the node, which started the http server. Then, it returns some HTML with the return values from the synchronous call. All works fine, until I test it with a browser (Chrome, Firefox latest versions working). But I need to implement a HTTP forwarding feature, where the http server can call an other URL with the given parameters. I tried it with httpc:

httpc:request(get, {"http://localhost:55556/httpfront:get?key=1", []}, [], []).

but the following error was thrown:

{error,{failed_connect,[{to_address,{"localhost",55556}},
                        {inet,[inet],econnrefused}]}}

Can you help me out please? What am I missing?

Ps. other sites, such as stackoverflow.com work with the above httpc:request(...).

Config: I start the node.erl, the node starts the httpfront.erl httpd daemon in an other module, the get request is handled at httpfront. I do this several times (start more nodes), now I want to connect from one httpfront instance with httpc:request(...) to an other. All of the HTTP handlers are started at localhost, but different non-proprietary port.

node.erl:

http_listener() ->
    httpfront:start().

start() ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
...

httpfront.erl:

start() ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []),
%this is the port number, it increments on each new node
    P = 55556,
    % the corresponding url is: http://localhost:port/
    % command are accesible this way:
    % port is from 55556 until end of valid port range, increments on new node join
    % http://localhost:55556/httpfront:get?key=thisisashortkey
    inets:start(),
    inets:start(httpd, [
        {modules, [
            mod_alias, 
            mod_auth, 
            mod_esi, 
            mod_actions, 
            mod_cgi, 
            mod_dir, 
            mod_get, 
            mod_head, 
            mod_log, 
            mod_disk_log
        ]},
        {port,P},
        {server_name,"httpfront"},
        {server_root,"log"},
        {document_root,"www"},
        {erl_script_alias, {"", [httpfront]}},
        {error_log, "error.log"},
        {security_log, "security.log"},
        {transfer_log, "transfer.log"},
        {mime_types,[
            {"html","text/html"}
            ]}
        ]),
        io:format("OK. Good to go.~n").

    get(SessionID, _Env, Input) ->
    % this get() is a gen_server synchronous call on the inside
    Result = node:get(Input),

    mod_esi:deliver(SessionID, [
        "Content-Type: text/html\r\n\r\n", 
        "<html><body>",
        "Get<br>",
        "Key=" ++ Value,
        "<br>Result=" ++ Result,
        "</body></html>"


    ]).
    ...

Now finally I try to call this, as I stated, from an other node, but I get the error:

httpc:request(get, {"http://localhost:55556/httpfront:get?key=1", []}, [], []).
{error,{failed_connect,[{to_address,{"localhost",55556}},
                        {inet,[inet],econnrefused}]}}

Any help and advice is appreciated. Thank you.


Solution

  • Try passing {ipfamily, inet} as a member of the option list for your httpd start call to get it to listen on IPv4 instead of IPv6. Also, since you likely want only localhost connectivity, you might consider passing the {bind_address, {127,0,0,1}} option as well.