Pregunta

Yo estoy usando la de erlang http:request para publicar algunos datos a un servicio remoto.Tengo el puesto de trabajo, pero los datos en el cuerpo del post viene a través como es, sin ningún tipo de codificación de url que hace que el post de error cuando se analiza el servicio remoto.

Hay una función en Erlang que es similar a la CGI.escape en Ruby para este propósito?

¿Fue útil?

Solución

Usted puede encontrar aquí la El PIAN url_encode y url_decode rutinas

Ellos son bastante sencillos, aunque los comentarios indican que la codificación no es 100% completa para todos los caracteres de puntuación.

Otros consejos

Me encontré con la falta de esta característica en los módulos HTTP así.

Resulta que esta funcionalidad está disponible en la distribución de erlang, sólo tienes que mirar bastante difícil.

> edoc_lib:escape_uri("luca+more@here.com").
"luca%2bmore%40here.com"

Este se comporta como CGI.escape en Ruby, también hay URI.de escape que se comporta de forma ligeramente diferente:

> CGI.escape("luca+more@here.com")
 => "luca%2Bmore%40here.com" 
> URI.escape("luca+more@here.com")
 => "luca+more@here.com" 

edoc_lib

Al menos en R15 hay http_uri:codificar/1 el que hace el trabajo.También me gustaría que no se recomienda el uso de edoc_lib:escape_uri como su traducción de un '=' a %3d en lugar de un %3D que me causó algunos problemas.

He aquí una sencilla función que realiza el trabajo.Está diseñado para trabajar directamente 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)).

Ejemplo de uso:

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

Para responder a mi propia pregunta...he encontrado este lib en 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 cadena basada en el RFC 1738.Devuelve una lista plana.

Supongo que puedo usar esto para hacer la codificación y todavía el uso de http:

Si alguien necesita codificar uri que trabaja con codificación utf-8 en 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: ƹÈ

He aquí un "fork" de la edoc_lib:escape_uri función que mejora el soporte para UTF-8 y también es compatible con archivos binarios.

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

Tenga en cuenta que, debido al uso de unicode:characters_to_binary va a trabajar sólo en R13 o más reciente.

AFAIK no hay URL codificador en las bibliotecas estándar.Creo que 'prestado' el código siguiente desde el PIAN o tal vez uno de los otros Erlang servidores web:

% 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).
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top