gen tcp - Erlang gen_tcp:recv http_request abs_path -


i'm writing code in erlang accepts http requests. have working code shown below.

the problem have i'm unsure returned result of gen_tcp:recv.

i create listening socket , accept sockets using

{ok, listensock}=gen_tcp:listen(port, [list,{active, false},{packet,http}]) {ok, sock}=gen_tcp:accept(listensock), 

i accept request (or other) using

{ok, {http_request, method, path, version}} = gen_tcp:recv(sock, 0), handle_get(sock, path); 

then, url parameters (cgi parameters, e.g., ?foo=1&bar=2) have match path structure {abs_path, relativepath}.

handle_get(sock, reqpath) ->     {abs_path, relpath} = reqpath,     parameters = string:substr(relpath, string:str(relpath, "?") + 1), 

while reading through docs of erlang gen_tcp , more recv method found the page describing httppacket.

the grammar on page shows path in httppacket, , in case httprequest type, can have multiple types of httpuri.

httprequest = {http_request, httpmethod, httpuri, httpversion} httpuri = '*'         | {absoluteuri,            http | https,            host :: httpstring,            port :: inet:port_number() | undefined,            path :: httpstring}         | {scheme, scheme :: httpstring, httpstring}         | {abs_path, httpstring}         | httpstring 

i understand have support each of these possible cases, not sure. wondering how can test these cases. have tried using curl , restclient in firefox , both of them make gen_tcp:recv return abs_path.

so clear, how determined whether request holds {abs_path, httpstring}, {scheme, scheme :: httpstring, httpstring} or {absoluteuri,...} , need support of them?

full listing

start(port)->     {ok, listensock}=gen_tcp:listen(port, [list,{active, false},{packet,http}]),     loop(listensock).   loop(listensock) ->      {ok, sock}=gen_tcp:accept(listensock),     spawn(?module, handle_request, [sock]),     loop(listensock).  %% takes tcp socket , receives  %% http://erlang.org/doc/man/erlang.html#decode_packet-3 handle_request(sock) ->     {ok, {http_request, method, path, _version}} = gen_tcp:recv(sock, 0),      case (method) of         'get' ->             handle_get(sock, path);         _ ->              send_unsupported_error(sock)     end.  handle_get(sock, reqpath) ->     {abs_path, relpath} = reqpath,     parameters = string:substr(relpath, string:str(relpath, "?") + 1),     %% debugging     parsedparms = httpd:parse_query(parameters),     io:fwrite("full path: ~p~nparameters: ~p~n", [relpath, parsedparms]),     %% end debugging     send_accept(sock). 

you can use simple network-capable client such netcat (/usr/bin/nc on system) send whatever form of request like. example, following connects web server listening on localhost port 8000 , sends get request path url (note $ denotes shell prompt):

$ nc localhost 8000 http://stackoverflow.com http/1.1  $ 

the nc program reads standard input. sure hit enter twice after get line indicate end of http headers. results in gen_tcp:recv call on server returning:

{absoluteuri,http,"stackoverflow.com",undefined,"/"} 

similarly, following return path gen_tcp:recv that's not {abs_path, ...} tuple, rather "../foo":

$ nc localhost 8000 ../foo http/1.1  $ 

you can set test variations these in text files , feed them nc using stdin redirection.


Comments

Popular posts from this blog

apache - PHP Soap issue while content length is larger -

asynchronous - Python asyncio task got bad yield -

javascript - Complete OpenIDConnect auth when requesting via Ajax -