mirror of
https://github.com/edgurgel/httparrot
synced 2025-04-06 00:32:34 -04:00
Use Base
module for conversions and handle bad requests gracefully
This commit is contained in:
parent
506b430948
commit
9ee0aa4ce1
4 changed files with 36 additions and 20 deletions
|
@ -8,31 +8,37 @@ defmodule HTTParrot.Base64Handler do
|
||||||
end
|
end
|
||||||
|
|
||||||
def allowed_methods(req, state) do
|
def allowed_methods(req, state) do
|
||||||
{["GET", "HEAD", "OPTIONS"], req, state}
|
{~W(GET HEAD OPTIONS), req, state}
|
||||||
end
|
end
|
||||||
|
|
||||||
def content_types_provided(req, state) do
|
def content_types_provided(req, state) do
|
||||||
{[{{"application", "octet-stream", []}, :get_binary}], req, state}
|
{[{{"application", "octet-stream", []}, :get_binary}], req, state}
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_binary(req, state) do
|
def malformed_request(req, state) do
|
||||||
{value, req} = :cowboy_req.binding(:value, req)
|
{value, req} = :cowboy_req.binding(:value, req)
|
||||||
value = decode(value)
|
|
||||||
{value, req, state}
|
|
||||||
end
|
|
||||||
|
|
||||||
defp decode(bin) when is_binary(bin) do
|
case decode(value) do
|
||||||
bin = case rem(byte_size(bin), 4) do
|
{ :ok, result } -> {false, req, result}
|
||||||
2 -> << bin :: binary, "==" >>
|
:error -> {true, req, state}
|
||||||
3 -> << bin :: binary, "=" >>
|
|
||||||
_ -> bin
|
|
||||||
end
|
end
|
||||||
bc <<x>> inbits :base64.decode(bin), x != ?=, do: <<urldecode_digit(x)>>
|
|
||||||
end
|
end
|
||||||
|
|
||||||
defp urldecode_digit(?_), do: ?/
|
defp decode(value) do
|
||||||
defp urldecode_digit(?-), do: ?+
|
pad(value) |> Base.url_decode64
|
||||||
defp urldecode_digit(d), do: d
|
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
|
def terminate(_, _, _), do: :ok
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,8 +16,8 @@ defmodule HTTParrot.ImageHandler do
|
||||||
{{"image", "jpeg", []}, :get_jpeg}], req, state}
|
{{"image", "jpeg", []}, :get_jpeg}], req, state}
|
||||||
end
|
end
|
||||||
|
|
||||||
@png :base64.decode("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg==")
|
@png Base.decode64!("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg==")
|
||||||
@jpeg :base64.decode("/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=")
|
@jpeg Base.decode64!("/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=")
|
||||||
|
|
||||||
def get_png(req, state), do: {@png, req, state}
|
def get_png(req, state), do: {@png, req, state}
|
||||||
def get_jpeg(req, state), do: {@jpeg, req, state}
|
def get_jpeg(req, state), do: {@jpeg, req, state}
|
||||||
|
|
|
@ -43,7 +43,7 @@ defmodule HTTParrot.PHandler do
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
# Octet-stream
|
# Octet-stream
|
||||||
body = :base64.encode(body)
|
body = Base.encode64(body)
|
||||||
post(req, [form: [{}], data: "data:application/octet-stream;base64," <> body, json: nil])
|
post(req, [form: [{}], data: "data:application/octet-stream;base64," <> body, json: nil])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,11 +11,21 @@ defmodule HTTParrot.Base64HandlerTest do
|
||||||
unload :cowboy_req
|
unload :cowboy_req
|
||||||
end
|
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}}])
|
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
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Reference in a new issue