Skip to content

Instantly share code, notes, and snippets.

@JLarky
Last active April 8, 2018 14:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JLarky/6534b7db3fe3df024bdeb96b246d990b to your computer and use it in GitHub Desktop.
Save JLarky/6534b7db3fe3df024bdeb96b246d990b to your computer and use it in GitHub Desktop.
Erlang url encode with unicode/utf8 support working on binary instead of lists/strings
-module(encode_uri_rfc3986_binary).
-author('Renato Albano <renatoalbano@gmail.com>').
-author('JLarky <jlarky@gmail.com>').
-export([encode/1]).
%% Taken from <http://erlangexamples.com/>,
%% from <http://github.com/CapnKernul/httparadise>
%% and <http://www.erlang.org/doc/man/edoc_lib.html>
encode(Binary) when is_binary(Binary) ->
escape(Binary).
escape(<<C, Cs/binary>>) when C >= $a, C =< $z ->
<<C, (escape(Cs))/binary>>;
escape(<<C, Cs/binary>>) when C >= $A, C =< $Z ->
<<C, (escape(Cs))/binary>>;
escape(<<C, Cs/binary>>) when C >= $0, C =< $9 ->
<<C, (escape(Cs))/binary>>;
escape(<<C, Cs/binary>>) when C == 16#20 -> % space to +
<<"+", (escape(Cs))/binary>>;
% unreserved
escape(<<C, Cs/binary>>) when C =:= $- ->
<<C, (escape(Cs))/binary>>;
escape(<<C, Cs/binary>>) when C =:= $_ ->
<<C, (escape(Cs))/binary>>;
escape(<<C, Cs/binary>>) when C =:= 46 -> % .
<<C, (escape(Cs))/binary>>;
escape(<<C, Cs/binary>>) when C =:= $! ->
<<C, (escape(Cs))/binary>>;
escape(<<C, Cs/binary>>) when C =:= $~ ->
<<C, (escape(Cs))/binary>>;
escape(<<C, Cs/binary>>) when C =:= $* ->
<<C, (escape(Cs))/binary>>;
escape(<<C, Cs/binary>>) when C =:= 39 -> % '
<<C, (escape(Cs))/binary>>;
escape(<<C, Cs/binary>>) when C =:= $( ->
<<C, (escape(Cs))/binary>>;
escape(<<C, Cs/binary>>) when C =:= $) ->
<<C, (escape(Cs))/binary>>;
escape(<<C, Cs/binary>>) ->
<<(escape_byte(C))/binary, (escape(Cs))/binary>>;
escape(<<>>) -> <<>>.
% from edoc_lib source
hex_octet(N) when N =< 9 ->
$0 + N;
hex_octet(N) when N =< 15 ->
$a + N - 10.
escape_byte(C) ->
<<"%", (hex_octet(C bsr 4)), (hex_octet(C band 15))>>.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment