[erlang-questions] problems with cowboy hello world

Garry Hodgson garry@REDACTED
Thu Mar 12 05:18:39 CET 2015


i'm trying to port a webmachine application to cowboy,
with puzzling results so far. i've got all the plumbing set
up, and my handlers get called. i actually need to use
cowboy_rest_handler, but am trying first to get basic http
working. so i copied the example from the User Guide:

-module( hello_api ).

-export( [ init/3, terminate/3 ] ).

init( Transport, Req, Opts ) ->
     Reply = cowboy_req:reply(
                                 200,
                                 [ { <<"content-type">>, 
<<"text/plain">> } ],
                                 <<"Hello world!">>,
                                 Req
                             ),
     log:debug( "hello:init(): Req is ~p", [ Req ] ),
     { ok, Reply, Opts }.

terminate( Reason, Req, State) ->
     log:debug( "terminating for ~p", [ Reason ] ),
     ok.

and when i hit the server with:

--> curl k2v/v0/hello -v
* About to connect() to k2v port 80 (#0)
*   Trying 135.207.243.29... connected
* Connected to k2v (135.207.243.29) port 80 (#0)
 > GET /v0/hello HTTP/1.1
 > User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 
NSS/3.15.3 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
 > Host: k2v
 > Accept: */*
 >
< HTTP/1.1 200 OK
< connection: keep-alive
< server: Cowboy
< date: Thu, 12 Mar 2015 03:52:39 GMT
< content-length: 12
< content-type: text/plain
<
* Connection #0 to host k2v left intact
Hello world!
* Closing connection #0


it works in that i get my response, but terminate() never gets called,
and i see this error report in erlang shell (included debug to show the 
req):

=INFO REPORT==== 11-Mar-2015::23:52:40 ===
{log,debug,
      "hello:init(): Req is 
{http_req,#Port<0.3094>,ranch_tcp,keepalive,<0.297.0>,\n 
<<\"GET\">>,'HTTP/1.1',\n {{135,207,243,29},36394},\n 
<<\"k2v\">>,undefined,80,<<\"/v0/hello\">>,\n 
undefined,<<>>,undefined,[],\n [{<<\"user-agent\">>,\n <<\"curl/7.19.7 
(x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.15.3 zlib/1.2.3 
libidn/1.18 libssh2/1.4.2\">>},\n {<<\"host\">>,<<\"k2v\">>},\n 
{<<\"accept\">>,<<\"*/*\">>}],\n 
[],undefined,[],waiting,<<>>,undefined,false,\n waiting,[],<<>>,undefined}",
      logpost@REDACTED}

=ERROR REPORT==== 11-Mar-2015::23:52:40 ===
Ranch listener cowboy_http_server had connection process started with 
cowboy_protocol:start_link/4 at <0.297.0> exit with reason: 
{function_clause,[{lists,zip,[[transport,connection,pid,method,version,peer,host,host_info,port,path,path_info,qs,qs_vals,bindings,headers,p_headers,cookies,meta,body_state,buffer,multipart,resp_compress,resp_state,resp_headers,resp_body,onresponse],[]],[{file,"lists.erl"},{line,385}]},{lists,zip,2,[{file,"lists.erl"},{line,385}]},{cowboy_handler,handler_terminate,4,[{file,"src/cowboy_handler.erl"},{line,291}]},{cowboy_handler,handler_handle,4,[{file,"src/cowboy_handler.erl"},{line,118}]},{cowboy_protocol,execute,4,[{file,"src/cowboy_protocol.erl"},{line,442}]}]}

the error seems to be because cowboy_handler:handler_terminate() is
calling cowboy_req:to_list(Req) in this catch clause:

handler_terminate(Req, Handler, HandlerState, Reason) ->
     try
         Handler:terminate(Reason, cowboy_req:lock(Req), HandlerState)
     catch Class:Reason2 ->
         erlang:Class([
             {reason, Reason2},
             {mfa, {Handler, terminate, 3}},
             {stacktrace, erlang:get_stacktrace()},
             {req, cowboy_req:to_list(Req)},
             {state, HandlerState},
             {terminate_reason, Reason}
         ])
     end.

where cowboy_req:to_list(Req) is:

to_list(Req) ->
     lists:zip(record_info(fields, http_req), tl(tuple_to_list(Req))).

and that second expression yields [].

So, am i doing something wrong here? Has the api changed?
The documentation and examples don't seem to agree with
the code, let alone whatever questions/tutorials/etc i find
when searching online. I gather the api's are in flux
( init/3 vs. init/2 and rest_init/2, { upgrade, protocol, cowboy_rest }
vs { cowboy_rest, Req, #state{} } ), so i'm not sure what
code i should be running. i grabbed the latest using erlang.mk bootstrap
just a few days ago.

any suggestions would be greatly appreciated.

thanks.


-- 
Garry Hodgson
AT&T Chief Security Office (CSO)

"This e-mail and any files transmitted with it are AT&T property, are confidential, and are intended solely for the use of the individual or entity to whom this e-mail is addressed. If you are not one of the named recipient(s) or otherwise have reason to believe that you have received this message in error, please notify the sender and delete this message immediately from your computer. Any other use, retention, dissemination, forwarding, printing, or copying of this e-mail is strictly prohibited."




More information about the erlang-questions mailing list