diff --git a/lib/httparrot/base64_handler.ex b/lib/httparrot/base64_handler.ex
index 2ed85a3..ad7a1dc 100644
--- a/lib/httparrot/base64_handler.ex
+++ b/lib/httparrot/base64_handler.ex
@@ -8,31 +8,37 @@ defmodule HTTParrot.Base64Handler do
   end
 
   def allowed_methods(req, state) do
-    {["GET", "HEAD", "OPTIONS"], req, state}
+    {~W(GET HEAD OPTIONS), req, state}
   end
 
   def content_types_provided(req, state) do
     {[{{"application", "octet-stream", []}, :get_binary}], req, state}
   end
 
-  def get_binary(req, state) do
+  def malformed_request(req, state) do
     {value, req} = :cowboy_req.binding(:value, req)
-    value = decode(value)
-    {value, req, state}
-  end
 
-  defp decode(bin) when is_binary(bin) do
-    bin = case rem(byte_size(bin), 4) do
-      2 -> << bin :: binary, "==" >>
-      3 -> << bin :: binary, "=" >>
-      _ -> bin
+    case decode(value) do
+      { :ok, result } -> {false, req, result}
+        :error -> {true, req, state}
     end
-    bc <<x>> inbits :base64.decode(bin), x != ?=, do: <<urldecode_digit(x)>>
   end
 
-  defp urldecode_digit(?_), do: ?/
-  defp urldecode_digit(?-), do: ?+
-  defp urldecode_digit(d), do: d
+  defp decode(value) do
+    pad(value) |> Base.url_decode64
+  end
+
+  defp pad(value) do
+    case byte_size(value) |> rem(4) do
+      2 -> value <> "=="
+      3 -> value <> "="
+      _ -> value
+    end
+  end
+
+  def get_binary(req, result) do
+    {result, req, result}
+  end
 
   def terminate(_, _, _), do: :ok
 end
diff --git a/lib/httparrot/image_handler.ex b/lib/httparrot/image_handler.ex
index 3360b67..a6fb00a 100644
--- a/lib/httparrot/image_handler.ex
+++ b/lib/httparrot/image_handler.ex
@@ -16,8 +16,8 @@ defmodule HTTParrot.ImageHandler do
       {{"image", "jpeg", []}, :get_jpeg}], req, state}
   end
 
-  @png :base64.decode("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg==")
-  @jpeg :base64.decode("/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=")
+  @png Base.decode64!("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg==")
+  @jpeg Base.decode64!("/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=")
 
   def get_png(req, state), do: {@png, req, state}
   def get_jpeg(req, state), do: {@jpeg, req, state}
diff --git a/lib/httparrot/p_handler.ex b/lib/httparrot/p_handler.ex
index cc66aca..63319c3 100644
--- a/lib/httparrot/p_handler.ex
+++ b/lib/httparrot/p_handler.ex
@@ -43,7 +43,7 @@ defmodule HTTParrot.PHandler do
       end
     else
       # Octet-stream
-      body = :base64.encode(body)
+      body = Base.encode64(body)
       post(req, [form: [{}], data: "data:application/octet-stream;base64," <> body, json: nil])
     end
   end
diff --git a/test/base64_handler_test.exs b/test/base64_handler_test.exs
index d15f06f..d5f8f47 100644
--- a/test/base64_handler_test.exs
+++ b/test/base64_handler_test.exs
@@ -11,11 +11,21 @@ defmodule HTTParrot.Base64HandlerTest do
     unload :cowboy_req
   end
 
-  test "returns decoded base64 urlsafe" do
+  test "halts with error" do
+    expect(:cowboy_req, :binding, [{[:value, :req1], {"I=", :req2}}])
+
+    assert malformed_request(:req1, :state) == {true, :req2, :state}
+    assert validate(:cowboy_req)
+  end
+
+  test "proceeds with decoded base64 urlsafe" do
     expect(:cowboy_req, :binding, [{[:value, :req1], {"LytiYXNlNjQrLw", :req2}}])
 
-    assert get_binary(:req1, :state) == { "/+base64+/", :req2, :state}
+    assert malformed_request(:req1, :state) == {false, :req2, "/+base64+/"}
+    assert validate(:cowboy_req)
+  end
 
-    assert validate :cowboy_req
+  test "returns value from state" do
+    assert get_binary(:req, :decoded) == {:decoded, :req, :decoded}
   end
 end