1
0
Fork 0
mirror of https://github.com/edgurgel/httparrot synced 2025-04-05 08:12:31 -04:00

Use Base module for conversions and handle bad requests gracefully

This commit is contained in:
Aleksei Magusev 2014-05-06 02:18:56 +04:00
parent 506b430948
commit 9ee0aa4ce1
4 changed files with 36 additions and 20 deletions

View file

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

View file

@ -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}

View file

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

View file

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