URL kodieren in Erlang
Frage
Ich bin mit erlang http: Anfrage einige Daten an einen entfernten Dienst zu stellen. Ich habe die Post arbeiten, aber die Daten im Körper () die Post kommt durch wie es ist, ohne URL-Codierung, die die Post verursacht scheitern, wenn sie von dem Remote-Service analysiert.
Gibt es eine Funktion in Erlang, die cgi.escape in Ruby für diesen Zweck ähnlich ist?
Lösung
Hier finden Sie hier die Framboesie url_encode und url_decode Routinen
Sie sind ziemlich einfach, obwohl Kommentare die Encodierung ist nicht 100% vollständig für alle Satzzeichen anzuzeigen.
Andere Tipps
Ich traf das Fehlen dieser Funktion in der HTTP-Module als auch.
Es stellt sich heraus, dass diese Funktionalität in der Erlang-Verteilung tatsächlich verfügbar ist, die Sie gerade schauen müssen hart genug.
> edoc_lib:escape_uri("luca+more@here.com").
"luca%2bmore%40here.com"
Dies verhält sich wie cgi.escape in Ruby gibt es auch URI.escape, die etwas anders verhält:
> CGI.escape("luca+more@here.com")
=> "luca%2Bmore%40here.com"
> URI.escape("luca+more@here.com")
=> "luca+more@here.com"
Mindestens in R15 gibt es http_uri: Kodier / 1 das macht die Arbeit. Ich würde auch empfehlen, nicht edoc_lib mit: escape_uri als ein ‚=‘ zu einer% 3d anstelle eines% 3D übersetzen, die mir einige Probleme verursacht.
Hier ist eine einfache Funktion, die die Arbeit erledigt. Es wurde entwickelt, httpc direkt mit inets zu arbeiten.
%% @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)).
Beispiel Nutzung:
httpc:request(post, {"http://localhost:3000/foo", [],
"application/x-www-form-urlencoded",
url_encode([{"username", "bob"}, {"password", "123456"}])}
,[],[]).
Um meine eigene Frage zu beantworten ... ich diese lib in IBrowse gefunden!
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-kodiert für eine Zeichenfolge basiert auf RFC 1738. Gibt eine flache Liste.
Ich glaube, ich kann diese verwenden, um die Codierung zu tun und noch http:
Wenn jemand braucht uri zu kodieren, die mit utf-8 in erlang funktioniert:
https://gist.github.com/3796470
Bsp.
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: ƹÈ
Hier ist eine „Gabel“ der edoc_lib: escape_uri Funktion, die auf der UTF-8-Unterstützung verbessert und unterstützt auch Binärdateien.
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 >= $0, 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 == $_ ->
[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 ->
[$0 + N];
hex_octet(N) when N > 15 ->
hex_octet(N bsr 4) ++ hex_octet(N band 15);
hex_octet(N) ->
[N - 10 + $a].
Beachten Sie, dass aufgrund der Verwendung von Unicode: characters_to_binary es nur in R13 oder höher arbeiten wird
.AFAIK gibt es keinen URL-Encoder in den Standardbibliotheken. Denke ich, ‚ausgeliehen‘ der folgende Code aus gieren oder vielleicht eine der anderen Erlang Webserver:
% 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,$&,[])).
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 -> $0 + C;
hexdigit(C) when C < 16 -> $A + (C - 10).