Question

J'utilise erlang http: demande d'envoi de données à un service distant. La publication fonctionne, mais les données figurant dans le corps () de la publication sont transmises telles quelles, sans aucun codage d’URL, ce qui entraîne l’échec de la publication lorsqu’il est analysé par le service distant.

Existe-t-il une fonction dans Erlang similaire à CGI.escape dans Ruby?

Autres conseils

Au moins dans la R15, il existe http_uri: encode / 1 qui fait le travail. De plus, je ne recommanderais pas d'utiliser edoc_lib: escape_uri pour traduire un '=' en% 3d au lieu de% 3D, ce qui m'a causé quelques problèmes.

Voici une fonction simple qui fait le travail. Il est conçu pour fonctionner directement avec 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)).

Exemple d'utilisation:

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

Pour répondre à ma propre question ... j'ai trouvé cette bibliothèque dans 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: code une chaîne basée sur RFC 1738. Renvoie une liste simple.

Je suppose que je peux utiliser ceci pour encoder tout en utilisant http:

Si quelqu'un a besoin d'un code uri qui fonctionne avec utf-8 dans 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: ƹÈ

Voici une "fourchette". de la fonction edoc_lib: escape_uri qui améliore le support UTF-8 et supporte également les fichiers binaires.

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 == 

Voici une "fourchette". de la fonction edoc_lib: escape_uri qui améliore le support UTF-8 et supporte également les fichiers binaires.

<*>

Notez que, en raison de l'utilisation de l'unicode: characters_to_binary, il ne fonctionnera que dans les versions R13 ou plus récentes.

-> [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].

Notez que, en raison de l'utilisation de l'unicode: characters_to_binary, il ne fonctionnera que dans les versions R13 ou plus récentes.

Autant que je sache, il n'y a pas de codeur d'URL dans les bibliothèques standard. Pensez que j'ai "emprunté" le code suivant à YAWS ou peut-être à l'un des autres serveurs 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).
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top