Skip to content

Instantly share code, notes, and snippets.

@c-spencer
Created December 14, 2014 21:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save c-spencer/885f33c493bf3ae7d131 to your computer and use it in GitHub Desktop.
Save c-spencer/885f33c493bf3ae7d131 to your computer and use it in GitHub Desktop.
defp(do_decide(:accept_charset_exists?, var!(conn))) do
if(has_header(var!(conn), "accept-charset")) do
case(handle_decision(var!(conn), (
charset = ConNeg.find_best(:charset, var!(conn).assigns().headers()["accept-charset"], @available_charsets)
{!is_nil(charset), assign(var!(conn), :charset, charset)}
))) do
{true, var!(conn)} ->
do_decide(:if_match_exists?, var!(conn))
{false, var!(conn)} ->
do_decide(:handle_not_acceptable, var!(conn))
end
else
do_decide(:if_match_exists?, var!(conn))
end
end
defp(do_decide(:handle_created, var!(conn))) do
Plug.Conn.resp(var!(conn), 201, "")
end
defp(do_decide(:handle_not_acceptable, var!(conn))) do
Plug.Conn.resp(var!(conn), 406, "No acceptable resource available.")
end
defp(do_decide(:handle_not_modified, var!(conn))) do
Plug.Conn.resp(var!(conn), 304, "")
end
defp(do_decide(:handle_precondition_failed, var!(conn))) do
Plug.Conn.resp(var!(conn), 412, "Precondition failed.")
end
defp(do_decide(:if_match_exists?, var!(conn))) do
if(has_header(var!(conn), "if-match")) do
if(var!(conn).assigns().headers()["if-match"] == "*") do
do_decide(:if_unmodified_since_exists?, var!(conn))
else
case(handle_decision(var!(conn), (
etag = format_etag(etag(var!(conn)))
{etag == var!(conn).assigns().headers()["if-match"], assign(var!(conn), :etag, etag)}
))) do
{true, var!(conn)} ->
do_decide(:if_unmodified_since_exists?, var!(conn))
{false, var!(conn)} ->
do_decide(:handle_precondition_failed, var!(conn))
end
end
else
do_decide(:if_unmodified_since_exists?, var!(conn))
end
end
defp(do_decide(:if_modified_since_exists?, var!(conn))) do
if(has_header(var!(conn), "if-modified-since")) do
case(handle_decision(var!(conn), (
datestring = to_char_list(var!(conn).assigns().headers()["if-modified-since"])
case(:httpd_util.convert_request_date(datestring)) do
:bad_date ->
false
date ->
{true, assign(var!(conn), :if_modified_since_date, date)}
end
))) do
{true, var!(conn)} ->
case(handle_decision(var!(conn), case(last_modified(var!(conn))) do
nil ->
true
last_modified ->
modsincedate = var!(conn).assigns()[:if_modified_since_date]
case(last_modified == modsincedate) do
true ->
false
false ->
{true, assign(var!(conn), :last_modified, last_modified)}
end
end)) do
{true, var!(conn)} ->
do_decide(:post_to_existing?, var!(conn))
{false, var!(conn)} ->
do_decide(:handle_not_modified, var!(conn))
end
{false, var!(conn)} ->
do_decide(:post_to_existing?, var!(conn))
end
else
do_decide(:post_to_existing?, var!(conn))
end
end
defp(do_decide(:if_none_match?, var!(conn))) do
if(var!(conn).method() in ["GET", "HEAD"]) do
do_decide(:handle_not_modified, var!(conn))
else
do_decide(:handle_precondition_failed, var!(conn))
end
end
defp(do_decide(:if_none_match_exists?, var!(conn))) do
if(has_header(var!(conn), "if-none-match")) do
if(var!(conn).assigns().headers()["if-none-match"] == "*") do
do_decide(:if_none_match?, var!(conn))
else
case(handle_decision(var!(conn), (
etag = format_etag(etag(var!(conn)))
{etag == var!(conn).assigns().headers()["if-none-match"], assign(var!(conn), :etag, etag)}
))) do
{true, var!(conn)} ->
do_decide(:if_none_match?, var!(conn))
{false, var!(conn)} ->
do_decide(:if_modified_since_exists?, var!(conn))
end
end
else
do_decide(:if_modified_since_exists?, var!(conn))
end
end
defp(do_decide(:conflict?, var!(conn))) do
case(handle_decision(var!(conn), check_setting(conn, :conflict?, false))) do
{true, var!(conn)} ->
Plug.Conn.resp(var!(conn), 409, "Conflict.")
{false, var!(conn)} ->
do_decide(:new?, put!(var!(conn)))
end
end
defp(do_decide(:delete_enacted?, var!(conn))) do
case(handle_decision(var!(conn), check_setting(conn, :delete_enacted?, true))) do
{true, var!(conn)} ->
do_decide(:respond_with_entity?, var!(conn))
{false, var!(conn)} ->
Plug.Conn.resp(var!(conn), 202, "Accepted.")
end
end
defp(do_decide(:handle_moved_permanently, var!(conn))) do
Plug.Conn.resp(var!(conn), 301, "")
end
defp(do_decide(:handle_not_found, var!(conn))) do
Plug.Conn.resp(var!(conn), 404, "Resource not found.")
end
defp(do_decide(:handle_not_implemented, var!(conn))) do
Plug.Conn.resp(var!(conn), 501, "Not implemented.")
end
defp(do_decide(:handle_precondition_failed, var!(conn))) do
Plug.Conn.resp(var!(conn), 412, "Precondition failed.")
end
defp(do_decide(:if_none_match_exists?, var!(conn))) do
if(has_header(var!(conn), "if-none-match")) do
if(var!(conn).assigns().headers()["if-none-match"] == "*") do
if(var!(conn).method() in ["GET", "HEAD"]) do
Plug.Conn.resp(var!(conn), 304, "")
else
do_decide(:handle_precondition_failed, var!(conn))
end
else
do_decide(:method_delete?, var!(conn))
end
else
do_decide(:method_delete?, var!(conn))
end
end
defp(do_decide(:if_unmodified_since_exists?, var!(conn))) do
if(has_header(var!(conn), "if-unmodified-since")) do
case(handle_decision(var!(conn), (
datestring = to_char_list(var!(conn).assigns().headers()["if-unmodified-since"])
case(:httpd_util.convert_request_date(datestring)) do
:bad_date ->
false
date ->
{true, assign(var!(conn), :if_unmodified_since_date, date)}
end
))) do
{true, var!(conn)} ->
case(handle_decision(var!(conn), case(last_modified(var!(conn))) do
nil ->
true
last_modified ->
unmodsincedate = var!(conn).assigns()[:if_unmodified_since_date]
case(last_modified == unmodsincedate) do
true ->
{false, assign(var!(conn), :last_modified, last_modified)}
false ->
true
end
end)) do
{true, var!(conn)} ->
do_decide(:handle_precondition_failed, var!(conn))
{false, var!(conn)} ->
do_decide(:if_none_match_exists?, var!(conn))
end
{false, var!(conn)} ->
do_decide(:if_none_match_exists?, var!(conn))
end
else
do_decide(:if_none_match_exists?, var!(conn))
end
end
defp(do_decide(:if_unmodified_since_exists?, var!(conn))) do
if(has_header(var!(conn), "if-unmodified-since")) do
case(handle_decision(var!(conn), (
datestring = to_char_list(var!(conn).assigns().headers()["if-unmodified-since"])
case(:httpd_util.convert_request_date(datestring)) do
:bad_date ->
false
date ->
{true, assign(var!(conn), :if_unmodified_since_date, date)}
end
))) do
{true, var!(conn)} ->
do_decide(:handle_precondition_failed, var!(conn))
{false, var!(conn)} ->
do_decide(:if_none_match_exists?, var!(conn))
end
else
do_decide(:if_none_match_exists?, var!(conn))
end
end
defp(do_decide(:method_delete?, var!(conn))) do
if(var!(conn).method() == "DELETE") do
do_decide(:delete_enacted?, delete!(var!(conn)))
else
if(var!(conn).method() == "PATCH") do
do_decide(:respond_with_entity?, patch!(var!(conn)))
else
if(var!(conn).method() == "POST") do
do_decide(:post!, var!(conn))
else
if(var!(conn).method() == "PUT") do
do_decide(:conflict?, var!(conn))
else
do_decide(:multiple_representations?, var!(conn))
end
end
end
end
end
defp(do_decide(:multiple_representations?, var!(conn))) do
case(handle_decision(var!(conn), check_setting(conn, :multiple_representations?, false))) do
{true, var!(conn)} ->
Plug.Conn.resp(var!(conn), 300, "")
{false, var!(conn)} ->
Plug.Conn.resp(var!(conn), 200, "OK")
end
end
defp(do_decide(:known_method?, var!(conn))) do
if(var!(conn).method() in @known_methods) do
if(var!(conn).method() in @allowed_methods) do
if(var!(conn).method() == "OPTIONS") do
Plug.Conn.resp(var!(conn), 200, "")
else
case(handle_decision(var!(conn), if(var!(conn).assigns().headers()["accept"]) do
true
else
{false, assign(var!(conn), :media_type, ConNeg.find_best(:accept, "*/*", @available_media_types))}
end)) do
{true, var!(conn)} ->
case(handle_decision(var!(conn), (
type = ConNeg.find_best(:accept, var!(conn).assigns().headers()["accept"], @available_media_types)
{!is_nil(type), assign(var!(conn), :media_type, type)}
))) do
{true, var!(conn)} ->
do_decide(:accept_charset_exists?, var!(conn))
{false, var!(conn)} ->
do_decide(:handle_not_acceptable, var!(conn))
end
{false, var!(conn)} ->
do_decide(:accept_charset_exists?, var!(conn))
end
end
else
Plug.Conn.resp(var!(conn), 405, "Method not allowed.")
end
else
Plug.Conn.resp(var!(conn), 501, "Unknown method.")
end
end
defp(do_decide(:new?, var!(conn))) do
case(handle_decision(var!(conn), check_setting(conn, :new?, true))) do
{true, var!(conn)} ->
Plug.Conn.resp(var!(conn), 201, "")
{false, var!(conn)} ->
do_decide(:respond_with_entity?, var!(conn))
end
end
defp(do_decide(:post!, var!(conn))) do
do_decide(:post_redirect?, post!(var!(conn)))
end
defp(do_decide(:post_redirect?, var!(conn))) do
case(handle_decision(var!(conn), check_setting(conn, :post_redirect?, false))) do
{true, var!(conn)} ->
Plug.Conn.resp(var!(conn), 303, "")
{false, var!(conn)} ->
do_decide(:new?, var!(conn))
end
end
defp(do_decide(:post_to_existing?, var!(conn))) do
if(var!(conn).method() == "POST") do
do_decide(:handle_created, post!(var!(conn)))
else
content = case(var!(conn)) do
%Plug.Conn{assigns: %{media_type: "text/html"}} ->
"HELLO"
%Plug.Conn{assigns: %{media_type: "application/json"}} ->
~s"{\"message\": \"HELLO\"}"
end
Plug.Conn.resp(var!(conn), 200, content)
end
end
defp(do_decide(:processable?, var!(conn))) do
case(handle_decision(var!(conn), check_setting(conn, :processable?, true))) do
{true, var!(conn)} ->
case(handle_decision(var!(conn), check_setting(conn, :exists?, true))) do
{true, var!(conn)} ->
if(has_header(var!(conn), "if-match")) do
if(var!(conn).assigns().headers()["if-match"] == "*") do
do_decide(:if_unmodified_since_exists?, var!(conn))
else
do_decide(:handle_precondition_failed, var!(conn))
end
else
do_decide(:if_unmodified_since_exists?, var!(conn))
end
{false, var!(conn)} ->
if(var!(conn).assigns().headers()["if-match"] == "*") do
do_decide(:handle_precondition_failed, var!(conn))
else
if(var!(conn).method() == "PUT") do
case(handle_decision(var!(conn), check_setting(conn, :put_to_different_url?, false))) do
{true, var!(conn)} ->
do_decide(:handle_moved_permanently, var!(conn))
{false, var!(conn)} ->
case(handle_decision(var!(conn), check_setting(conn, :can_put_to_missing?, true))) do
{true, var!(conn)} ->
do_decide(:conflict?, var!(conn))
{false, var!(conn)} ->
do_decide(:handle_not_implemented, var!(conn))
end
end
else
case(handle_decision(var!(conn), check_setting(conn, :existed?, false))) do
{true, var!(conn)} ->
case(handle_decision(var!(conn), check_setting(conn, :moved_permanently?, false))) do
{true, var!(conn)} ->
do_decide(:handle_moved_permanently, var!(conn))
{false, var!(conn)} ->
case(handle_decision(var!(conn), check_setting(conn, :moved_temporarily?, false))) do
{true, var!(conn)} ->
Plug.Conn.resp(var!(conn), 307, "")
{false, var!(conn)} ->
if(var!(conn).method() == "POST") do
case(handle_decision(var!(conn), check_setting(conn, :can_post_to_gone?, true))) do
{true, var!(conn)} ->
do_decide(:post!, var!(conn))
{false, var!(conn)} ->
Plug.Conn.resp(var!(conn), 410, "Resource is gone.")
end
else
do_decide(:handle_not_found, var!(conn))
end
end
end
{false, var!(conn)} ->
if(var!(conn).method() == "POST") do
case(handle_decision(var!(conn), check_setting(conn, :can_post_to_missing?, true))) do
{true, var!(conn)} ->
do_decide(:post!, var!(conn))
{false, var!(conn)} ->
do_decide(:handle_not_found, var!(conn))
end
else
do_decide(:handle_not_found, var!(conn))
end
end
end
end
end
{false, var!(conn)} ->
Plug.Conn.resp(var!(conn), 422, "Unprocessable entity.")
end
end
defp(do_decide(:respond_with_entity?, var!(conn))) do
case(handle_decision(var!(conn), check_setting(conn, :respond_with_entity?, false))) do
{true, var!(conn)} ->
do_decide(:multiple_representations?, var!(conn))
{false, var!(conn)} ->
Plug.Conn.resp(var!(conn), 204, "")
end
end
defp(do_decide(:service_available?, var!(conn))) do
case(handle_decision(var!(conn), check_setting(conn, :service_available?, true))) do
{true, var!(conn)} ->
if(var!(conn).method() in @known_methods) do
case(handle_decision(var!(conn), check_setting(conn, :uri_too_long?, false))) do
{true, var!(conn)} ->
Plug.Conn.resp(var!(conn), 414, "Request URI too long.")
{false, var!(conn)} ->
if(var!(conn).method() in @allowed_methods) do
case(handle_decision(var!(conn), check_setting(conn, :malformed?, false))) do
{true, var!(conn)} ->
Plug.Conn.resp(var!(conn), 400, "Bad request.")
{false, var!(conn)} ->
case(handle_decision(var!(conn), check_setting(conn, :authorized?, true))) do
{true, var!(conn)} ->
case(handle_decision(var!(conn), check_setting(conn, :allowed?, true))) do
{true, var!(conn)} ->
case(handle_decision(var!(conn), check_setting(conn, :valid_content_header?, true))) do
{true, var!(conn)} ->
case(handle_decision(var!(conn), check_setting(conn, :known_content_type?, true))) do
{true, var!(conn)} ->
case(handle_decision(var!(conn), check_setting(conn, :valid_entity_length?, true))) do
{true, var!(conn)} ->
if(var!(conn).method() == "OPTIONS") do
Plug.Conn.resp(var!(conn), 200, "")
else
case(handle_decision(var!(conn), if(var!(conn).assigns().headers()["accept"]) do
true
else
{false, assign(var!(conn), :media_type, ConNeg.find_best(:accept, "*/*", @available_media_types))}
end)) do
{true, var!(conn)} ->
case(handle_decision(var!(conn), (
type = ConNeg.find_best(:accept, var!(conn).assigns().headers()["accept"], @available_media_types)
{!is_nil(type), assign(var!(conn), :media_type, type)}
))) do
{true, var!(conn)} ->
do_decide(:processable?, var!(conn))
{false, var!(conn)} ->
Plug.Conn.resp(var!(conn), 406, "No acceptable resource available.")
end
{false, var!(conn)} ->
do_decide(:processable?, var!(conn))
end
end
{false, var!(conn)} ->
Plug.Conn.resp(var!(conn), 413, "Request entity too large.")
end
{false, var!(conn)} ->
Plug.Conn.resp(var!(conn), 415, "Unsupported media type.")
end
{false, var!(conn)} ->
do_decide(:handle_not_implemented, var!(conn))
end
{false, var!(conn)} ->
Plug.Conn.resp(var!(conn), 403, "Forbidden.")
end
{false, var!(conn)} ->
Plug.Conn.resp(var!(conn), 401, "Not authorized.")
end
end
else
Plug.Conn.resp(var!(conn), 405, "Method not allowed.")
end
end
else
Plug.Conn.resp(var!(conn), 501, "Unknown method.")
end
{false, var!(conn)} ->
Plug.Conn.resp(var!(conn), 503, "Service not available.")
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment