Domanda

Sto usando erlang http: richiesta per pubblicare alcuni dati su un servizio remoto. Ho il post funzionante ma i dati nel corpo () del post passano così come sono, senza alcuna codifica URL che causa il fallimento del post quando analizzato dal servizio remoto.

Esiste una funzione in Erlang simile a CGI.escape in Ruby per questo scopo?

È stato utile?

Soluzione

Altri suggerimenti

Almeno in R15 c'è http_uri: encode / 1 che fa il lavoro. Inoltre, non consiglierei di usare edoc_lib: escape_uri perché sta traducendo un '=' in% 3d invece di un% 3D che mi ha causato qualche problema.

Ecco una semplice funzione che fa il lavoro. È progettato per funzionare direttamente con inets httpc.

%% @doc A function to URL encode form data.
%% @spec url_encode(formdata()).

-spec(url_encode(formdata()) -> string()).
url_encode(Data) ->
    url_encode(Data,"").

url_encode([],Acc) ->
    Acc;

url_encode([{Key,Value}|R],"") ->
    url_encode(R, edoc_lib:escape_uri(Key) ++ "=" ++ edoc_lib:escape_uri(Value));
url_encode([{Key,Value}|R],Acc) ->
    url_encode(R, Acc ++ "&" ++ edoc_lib:escape_uri(Key) ++ "=" ++ edoc_lib:escape_uri(Value)).

Esempio di utilizzo:

httpc:request(post, {"http://localhost:3000/foo", [], 
                    "application/x-www-form-urlencoded",
                    url_encode([{"username", "bob"}, {"password", "123456"}])}
             ,[],[]).

Per rispondere alla mia domanda ... Ho trovato questa lib in ibrowse!

http: //www.erlware .org / lib / 5.6.3 / iBrowse-1.4 / ibrowse_lib.html # url_encode-1

url_encode/1

url_encode(Str) -> UrlEncodedStr

Str = string()
UrlEncodedStr = string()

URL codifica una stringa basata su RFC 1738. Restituisce un elenco semplice.

Immagino di poterlo utilizzare per eseguire la codifica e continuare a utilizzare http:

Se qualcuno ha bisogno di codificare uri che funziona con utf-8 in erlang:

https://gist.github.com/3796470

Ex.

Eshell V5.9.1  (abort with ^G)

1> c(encode_uri_rfc3986).
{ok,encode_uri_rfc3986}

2> encode_uri_rfc3986:encode("テスト").
"%e3%83%86%e3%82%b9%e3%83%88"

3> edoc_lib:escape_uri("テスト").
"%c3%86%c2%b9%c3%88" # output wrong: ƹÈ

Ecco un " fork " della funzione edoc_lib: escape_uri che migliora il supporto UTF-8 e supporta anche i binari.

escape_uri(S) when is_list(S) ->
    escape_uri(unicode:characters_to_binary(S));
escape_uri(<<C:8, Cs/binary>>) when C >= $a, C =< $z ->
    [C] ++ escape_uri(Cs);
escape_uri(<<C:8, Cs/binary>>) when C >= $A, C =< $Z ->
    [C] ++ escape_uri(Cs);
escape_uri(<<C:8, Cs/binary>>) when C >= <*>, C =< $9 ->
    [C] ++ escape_uri(Cs);
escape_uri(<<C:8, Cs/binary>>) when C == $. ->
    [C] ++ escape_uri(Cs);
escape_uri(<<C:8, Cs/binary>>) when C == $- ->
    [C] ++ escape_uri(Cs);
escape_uri(<<C:8, Cs/binary>>) when C == 

Ecco un " fork " della funzione edoc_lib: escape_uri che migliora il supporto UTF-8 e supporta anche i binari.

<*>

Nota che, a causa dell'uso di unicode: characters_to_binary, funzionerà solo in R13 o più recente.

-> [C] ++ escape_uri(Cs); escape_uri(<<C:8, Cs/binary>>) -> escape_byte(C) ++ escape_uri(Cs); escape_uri(<<>>) -> "". escape_byte(C) -> "%" ++ hex_octet(C). hex_octet(N) when N =< 9 -> [<*> + N]; hex_octet(N) when N > 15 -> hex_octet(N bsr 4) ++ hex_octet(N band 15); hex_octet(N) -> [N - 10 + $a].

Nota che, a causa dell'uso di unicode: characters_to_binary, funzionerà solo in R13 o più recente.

AFAIK non esiste un codificatore URL nelle librerie standard. Credo di aver "preso in prestito" il seguente codice da YAWS o forse uno degli altri server Web Erlang:

% Utility function to convert a 'form' of name-value pairs into a URL encoded
% content string.

urlencode(Form) ->
    RevPairs = lists:foldl(fun({K,V},Acc) -> [[quote_plus(K),$=,quote_plus(V)] | Acc] end, [],Form),
    lists:flatten(revjoin(RevPairs,<*>amp;,[])).

quote_plus(Atom) when is_atom(Atom) ->
    quote_plus(atom_to_list(Atom));

quote_plus(Int) when is_integer(Int) ->
    quote_plus(integer_to_list(Int));

quote_plus(String) ->
    quote_plus(String, []).

quote_plus([], Acc) ->
    lists:reverse(Acc);

quote_plus([C | Rest], Acc) when ?QS_SAFE(C) ->
    quote_plus(Rest, [C | Acc]);

quote_plus([$\s | Rest], Acc) ->
    quote_plus(Rest, [<*> | Acc]);

quote_plus([C | Rest], Acc) ->
    <<Hi:4, Lo:4>> = <<C>>,
    quote_plus(Rest, [hexdigit(Lo), hexdigit(Hi), ?PERCENT | Acc]).

revjoin([], _Separator, Acc) ->
    Acc;

revjoin([S | Rest],Separator,[]) ->
    revjoin(Rest,Separator,[S]);

revjoin([S | Rest],Separator,Acc) ->
    revjoin(Rest,Separator,[S,Separator | Acc]).

hexdigit(C) when C < 10 -> <*> + C;
hexdigit(C) when C < 16 -> $A + (C - 10).
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top