ublog

n2o - GET та POST параметри, розбір URI

programming [35]erlang [33]n2o [18]

дістанемо GET-параметр
X = wf:qp(<<"x">>),
Y = wf:qp(<<"y">>),
% domain.com/test/?x=7
io:format("~p~n", [X]), % <<"7">>
io:format("~p~n", [Y]), % undefined

щоб дістати POST-параметр напишемо допоміжну функцію в модуль hm
post_value(Req, Key) ->
  {ok, PostStr, _} = wf:request_body(Req),
  PostList = cow_qs:parse_qs(PostStr),
  ?MODULE:post_value2( [ Value || {_Key1, Value} <- PostList, _Key1 =:= Key ] ).

% helper
post_value2([]) -> undefined;
post_value2([Val|_]) -> Val;
post_value2(_) -> undefined.

після чого дістанемо POST-параметр
Z = hm:post_value(?REQ, <<"z">>),
% domain.com/test/?x=7
% post data -- z=9
io:format("~p~n", [Z]), % undefined | <<"9">>


далі розглянемо як розібрати URI
допустимо, ми хочемо отримати id з адреси типу /page/777

запишемо в routes.erl
route(<<"page/",_/binary>>) -> page;

далі отримаємо path ( /page/777 ) та проведемо валідацію
Path = wf:path(?REQ),

case hm:is_valid_uri_page(Path) of
  true ->
    % valid page
    
    PageNum = hm:get_page_number(Path),
    % work with page number -- show page
    ;
  _ ->
    % invalid page
    wf:redirect("/404/")
end.

де функції валідації та отримання номеру сторінки виглядають наступним чином
is_valid_uri_page(A) ->
  case re:run(A, <<"^/page/[1-9]{1}([0-9])*$">>) of
    nomatch ->
      false;
    _ ->
      true
  end.


get_page_number(A) ->
  % <<"/page/777">> or <<"/ws/page/777">>
  [_,N|_] = string:split(A, <<"/">>, trailing),
  erlang:binary_to_integer(N).

зверніть увагу на коментар в функції get_page_number --
у випадку з вебсокет-з'єднанням до uri спереді додається /ws
таким чином для валідації uri при вебсокет-з'єднанні
вам потрібна трішки інша функція, ніж наведена вище для GET-запиту

і ще одне -- щоб ваша регулярка-валідатор "переварювала" utf8 без падінь
(для прикладу, очікуєте кирилицю в запиті, чи хочете щоб при utf8 сторінка не "падала")
користуйтесь наступним варіантом --
re:run(A, <<"^/page/([A-Za-zА-Яа-я])*$"/utf8>>, [unicode])


ось так :)