1
0
Fork 0
mirror of https://github.com/edgurgel/httparrot synced 2025-04-06 00:32:34 -04:00

Compare commits

..

No commits in common. "master" and "v1.3.0" have entirely different histories.

41 changed files with 246 additions and 407 deletions

View file

@ -1,4 +0,0 @@
# Used by "mix format"
[
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
]

View file

@ -1,54 +0,0 @@
name: CI
on: [push, pull_request]
jobs:
format:
name: Format & credo
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.3.1
- name: Install OTP and Elixir
uses: erlef/setup-beam@v1
with:
otp-version: 26.x
elixir-version: 1.16.x
- name: Install dependencies
run: mix deps.get
- name: Compile with --warnings-as-errors
run: mix compile --warnings-as-errors
- name: Run "mix format"
run: mix format --check-formatted
test:
name: Test (Elixir ${{matrix.elixir}} | Erlang/OTP ${{matrix.otp}})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- otp: 26.x
elixir: 1.16.x
coverage: true
- otp: 27.x
elixir: 1.17.x
env:
MIX_ENV: test
steps:
- uses: actions/checkout@v2.3.1
- name: Install OTP and Elixir
uses: erlef/setup-beam@v1
with:
otp-version: ${{matrix.otp}}
elixir-version: ${{matrix.elixir}}
- name: Install dependencies
run: mix deps.get --only test
- name: Run tests
run: mix test --trace

28
.gitignore vendored
View file

@ -1,26 +1,6 @@
# The directory Mix will write compiled artifacts to. /_build
/_build/ /deps
# If you run "mix test --cover", coverage assets end up here.
/cover/
# The directory Mix downloads your dependencies sources to.
/deps/
# Where third-party dependencies like ExDoc output generated docs.
/doc/
# Ignore .fetch files in case you like to edit your project deps locally.
/.fetch
# If the VM crashes, it generates a dump, let's ignore it too.
erl_crash.dump erl_crash.dump
# Also ignore archive artifacts (built via "mix archive.build").
*.ez *.ez
/doc
# Ignore package tarball (built via "mix hex.build"). .elixir_ls
httparrot-*.tar
# Temporary files, for example, from tests.
/tmp/

25
.travis.yml Normal file
View file

@ -0,0 +1,25 @@
language: elixir
notifications:
recipients:
- eduardo@gurgel.me
cache:
directories:
- _build
- deps
sudo: false
script: mix test
matrix:
include:
otp_release: 21.0
- elixir: 1.7
otp_release: 19.3
- elixir: 1.7
otp_release: 20.3
- elixir: 1.7
otp_release: 21.0
- elixir: 1.8
otp_release: 20.3
- elixir: 1.8
otp_release: 21.0
- elixir: 1.8
otp_release: 22.0.1

View file

@ -1,6 +1,4 @@
# The MIT License Copyright (c) 2013-2014 Eduardo Gurgel Pinho
Copyright (c) 2013 Eduardo Gurgel <eduardo@gurgel.me>
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the

View file

@ -1,56 +1,49 @@
# HTTParrot # HTTParrot [![Build Status](https://travis-ci.org/edgurgel/httparrot.png?branch=master)](https://travis-ci.org/edgurgel/httparrot)
[![Build Status](https://travis-ci.org/edgurgel/httparrot.png?branch=master)](https://travis-ci.org/edgurgel/httparrot) HTTP server built on top of Cowboy using (mostly) `cowboy_rest` handlers to serve useful endpoints for testing purposes. Its goal is to be as close as possible to [HTTPBin](http://httpbin.org).
[![Module Version](https://img.shields.io/hexpm/v/httparrot.svg)](https://hex.pm/packages/httparrot)
[![Hex Docs](https://img.shields.io/badge/hex-docs-lightgreen.svg)](https://hexdocs.pm/httparrot/)
[![Total Download](https://img.shields.io/hexpm/dt/httparrot.svg)](https://hex.pm/packages/httparrot)
[![License](https://img.shields.io/hexpm/l/httparrot.svg)](https://github.com/edgurgel/httparrot/blob/master/LICENSE.md)
[![Last Updated](https://img.shields.io/github/last-commit/edgurgel/httparrot.svg)](https://github.com/edgurgel/httparrot/commits/master)
HTTP server built on top of [Cowboy](https://hex.pm/packages/cowboy) using (mostly) `cowboy_rest` handlers to serve useful endpoints for testing purposes. Its goal is to be as close as possible to [HTTPBin](http://httpbin.org).
## Endpoints ## Endpoints
* `/` This page. * / This page.
* `/ip` Returns Origin IP. * /ip Returns Origin IP.
* `/user-agent` Returns user-agent. * /user-agent Returns user-agent.
* `/headers` Returns header dict. * /headers Returns header dict.
* `/get` Returns GET data. * /get Returns GET data.
* `/post` Returns POST data. * /post Returns POST data.
* `/put` Returns PUT data. * /put Returns PUT data.
* `/patch` Returns PATCH data. * /patch Returns PATCH data.
* `/delete` Returns DELETE data * /delete Returns DELETE data
* `/gzip` Returns gzip-encoded data. * /gzip Returns gzip-encoded data.
* `/status/:code` Returns given HTTP Status code. * /status/:code Returns given HTTP Status code.
* `/response-headers?key=val` Returns given response headers. * /response-headers?key=val Returns given response headers.
* `/redirect/:n` 301 Redirects n times. * /redirect/:n 301 Redirects n times.
* `/redirect-to?url=foo` 301 Redirects to the foo URL. * /redirect-to?url=foo 301 Redirects to the foo URL.
* `/relative-redirect/:n` 301 Relative redirects n times. * /relative-redirect/:n 301 Relative redirects n times.
* `/cookies` Returns cookie data. * /cookies Returns cookie data.
* `/cookies/set?name=value` Sets one or more simple cookies. * /cookies/set?name=value Sets one or more simple cookies.
* `/cookies/set/name/value` Sets one cookie . * /cookies/set/name/value Sets one cookie .
* `/cookies/delete?name` Deletes one or more simple cookies. * /cookies/delete?name Deletes one or more simple cookies.
* `/basic-auth/:user/:passwd` Challenges HTTPBasic Auth. * /basic-auth/:user/:passwd Challenges HTTPBasic Auth.
* `/hidden-basic-auth/:user/:passwd` 404'd BasicAuth. * /hidden-basic-auth/:user/:passwd 404'd BasicAuth.
* `/digest-auth/:qop/:user/:passwd` Challenges HTTP Digest Auth. * /digest-auth/:qop/:user/:passwd Challenges HTTP Digest Auth.
* `/stream/:n` Streams n100 lines. * /stream/:n Streams n100 lines.
* `/delay/:n` Delays responding for n10 seconds. * /delay/:n Delays responding for n10 seconds.
* `/html` Renders an HTML Page. * /html Renders an HTML Page.
* `/robots.txt` Returns some robots.txt rules. * /robots.txt Returns some robots.txt rules.
* `/deny` Denied by robots.txt file. * /deny Denied by robots.txt file.
* `/cache` Returns 200 unless an If-Modified-Since header is provided, when it returns a 304 Not Modified. * /cache Returns 200 unless an If-Modified-Since header is provided, when it returns a 304 Not Modified.
* `/base64/:value` Decodes base64url-encoded string. * /base64/:value Decodes base64url-encoded string.
* `/image` Return an image based on Accept header. * /image Return an image based on Accept header.
* `/websocket` Echo message received through websocket * /websocket Echo message received through websocket
## TODO ## TODO
* [ ] `/deflate` Returns deflate-encoded data. * [ ] /deflate Returns deflate-encoded data.
* [ ] `/digest-auth/:qop/:user/:passwd` Challenges HTTP Digest Auth. * [ ] /digest-auth/:qop/:user/:passwd Challenges HTTP Digest Auth.
## Copyright and License ## License
Copyright (c) 2013 Eduardo Gurgel <eduardo@gurgel.me> Copyright 2013-2016 Eduardo Gurgel <eduardo@gurgel.me>
This work is free. You can redistribute it and/or modify it under the This work is free. You can redistribute it and/or modify it under the
terms of the MIT License. See the [LICENSE.md](./LICENSE.md) file for more details. terms of the MIT License. See the LICENSE file for more details.

View file

@ -1,10 +0,0 @@
#!/usr/bin/env bash
# exit on error
set -o errexit
# Initial setup
mix deps.get --only prod
MIX_ENV=prod mix compile
# Build the release and overwrite the existing release directory
MIX_ENV=prod mix release --overwrite

View file

@ -1,4 +1,4 @@
import Config import Mix.Config
port = System.get_env("PORT", "8080") port = System.get_env("PORT", "8080")
port = String.to_integer(port) port = String.to_integer(port)
@ -14,3 +14,4 @@ config :httparrot,
https_port: ssl_port, https_port: ssl_port,
unix_socket: unix_socket, unix_socket: unix_socket,
socket_path: System.get_env("SOCKET_PATH", "httparrot.sock") socket_path: System.get_env("SOCKET_PATH", "httparrot.sock")

View file

@ -14,3 +14,4 @@ config :httparrot,
https_port: ssl_port, https_port: ssl_port,
unix_socket: unix_socket, unix_socket: unix_socket,
socket_path: System.get_env("SOCKET_PATH", "httparrot.sock") socket_path: System.get_env("SOCKET_PATH", "httparrot.sock")

View file

@ -7,7 +7,7 @@ defmodule HTTParrot do
end end
def init(_) do def init(_) do
Supervisor.start_link([], strategy: :one_for_one) supervise([], strategy: :simple_one_for_one)
end end
def start(_type, _args) do def start(_type, _args) do
@ -71,9 +71,9 @@ defmodule HTTParrot do
:https, :https,
[ [
port: https_port, port: https_port,
cacertfile: priv_dir ++ ~c"/ssl/server-ca.crt", cacertfile: priv_dir ++ '/ssl/server-ca.crt',
certfile: priv_dir ++ ~c"/ssl/server.crt", certfile: priv_dir ++ '/ssl/server.crt',
keyfile: priv_dir ++ ~c"/ssl/server.key" keyfile: priv_dir ++ '/ssl/server.key'
], ],
%{env: %{dispatch: dispatch}} %{env: %{dispatch: dispatch}}
) )

View file

@ -18,7 +18,7 @@ defmodule HTTParrot.DenyHandler do
\ .-"` `"-. / \ .-"` `"-. /
'. .' '. .'
'-......-' '-......-'
YOU SHOULDN'T BE HERE YOU SHOUDN'T BE HERE
""" """
def get_plain(req, state) do def get_plain(req, state) do
{@body, req, state} {@body, req, state}

View file

@ -13,7 +13,7 @@ defmodule HTTParrot.PHandler do
""" """
def allowed_methods(req, state) do def allowed_methods(req, state) do
path = :cowboy_req.path(req) path = :cowboy_req.path(req)
path = String.slice(path, 1..-1//1) path = String.slice(path, 1..-1)
{[String.upcase(path)], req, state} {[String.upcase(path)], req, state}
end end

View file

@ -19,11 +19,7 @@ defmodule HTTParrot.RedirectHandler do
def previously_existed(req, state), do: {true, req, state} def previously_existed(req, state), do: {true, req, state}
def moved_permanently(req, n) do def moved_permanently(req, n) do
host_url = host_url = IO.iodata_to_binary(:cowboy_req.uri(req, %{path: :undefined, qs: :undefined, fragment: :undefined}))
IO.iodata_to_binary(
:cowboy_req.uri(req, %{path: :undefined, qs: :undefined, fragment: :undefined})
)
url = if n > 1, do: "/redirect/#{n - 1}", else: "/get" url = if n > 1, do: "/redirect/#{n - 1}", else: "/get"
{{true, host_url <> url}, req, nil} {{true, host_url <> url}, req, nil}
end end

View file

@ -1,6 +1,6 @@
defmodule HTTParrot.RequestStore do defmodule HTTParrot.RequestStore do
@moduledoc """ @moduledoc """
Used to store and retrieved requests Used to store and retrived requests
""" """
@doc """ @doc """
Store the requests to the key Store the requests to the key
@ -26,7 +26,7 @@ defmodule HTTParrot.RequestStore do
end end
@doc """ @doc """
Clear the saved data on the corresponding key Clear the saved data on the coresponding key
""" """
def clear(key) do def clear(key) do
ConCache.delete(:requests_registry, key) ConCache.delete(:requests_registry, key)

View file

@ -1,6 +1,6 @@
defmodule HTTParrot.RetrieveRequestHandler do defmodule HTTParrot.RetrieveRequestHandler do
@moduledoc """ @moduledoc """
Retrieve saved request and clear the conresponding :id Retreive saved request and clear the conresponding :id
""" """
use HTTParrot.Cowboy, methods: ~w(GET POST PUT HEAD OPTIONS) use HTTParrot.Cowboy, methods: ~w(GET POST PUT HEAD OPTIONS)

View file

@ -23,7 +23,7 @@ defmodule HTTParrot.StoreRequestHandler do
{info, req} = GeneralRequestInfo.retrieve(req) {info, req} = GeneralRequestInfo.retrieve(req)
key = :cowboy_req.binding(:key, req) key = :cowboy_req.binding(:key, req)
HTTParrot.RequestStore.store(key, info) HTTParrot.RequestStore.store(key, info)
{~c'{"saved": "true"}', req, state} {'{"saved": "true"}', req, state}
end end
def post_binary(req, _state) do def post_binary(req, _state) do

View file

@ -31,15 +31,13 @@ defmodule HTTParrot.StreamBytesHandler do
end end
defp stream_response!(n, chunk_size, req) do defp stream_response!(n, chunk_size, req) do
req = :cowboy_req.stream_reply(200, %{"content-type" => "application/octet-stream"}, req) req = :cowboy_req.stream_reply(200, %{ "content-type" => "application/octet-stream" }, req)
Stream.repeatedly(fn -> :rand.uniform(255) end) Stream.repeatedly(fn -> :rand.uniform(255) end)
|> Stream.take(n) |> Stream.take(n)
|> Enum.chunk_every(chunk_size, chunk_size, []) |> Enum.chunk_every(chunk_size, chunk_size, [])
|> Enum.each(fn chunk -> |> Enum.each(fn chunk ->
:cowboy_req.stream_body(List.to_string(chunk), :nofin, req) :cowboy_req.stream_body(List.to_string(chunk), :nofin, req)
end) end)
:cowboy_req.stream_body("", :fin, req) :cowboy_req.stream_body("", :fin, req)
req req
end end

View file

@ -25,13 +25,11 @@ defmodule HTTParrot.StreamHandler do
def get_json(req, n) do def get_json(req, n) do
{info, req} = GeneralRequestInfo.retrieve(req) {info, req} = GeneralRequestInfo.retrieve(req)
req = :cowboy_req.stream_reply(200, %{"content-type" => "application/json"}, req) req = :cowboy_req.stream_reply(200, %{ "content-type" => "application/json" }, req)
Enum.each(0..(n - 1), fn i -> Enum.each(0..(n - 1), fn i ->
body = JSX.encode!([id: i] ++ info) body = JSX.encode!([id: i] ++ info)
:cowboy_req.stream_body(body, :nofin, req) :cowboy_req.stream_body(body, :nofin, req)
end) end)
:cowboy_req.stream_body("", :fin, req) :cowboy_req.stream_body("", :fin, req)
{:stop, req, nil} {:stop, req, nil}
end end

37
mix.exs
View file

@ -1,18 +1,19 @@
defmodule Httparrot.Mixfile do defmodule Httparrot.Mixfile do
use Mix.Project use Mix.Project
@source_url "https://github.com/edgurgel/httparrot" @description """
@version "1.4.0" HTTP Request & Response Server. An incomplete clone of http://httpbin.org
"""
def project do def project do
[ [
app: :httparrot, app: :httparrot,
version: @version, version: "1.3.0",
elixir: "~> 1.16", elixir: "~> 1.7",
name: "HTTParrot", name: "HTTParrot",
description: @description,
package: package(), package: package(),
deps: deps(), deps: deps()
docs: docs()
] ]
end end
@ -25,38 +26,24 @@ defmodule Httparrot.Mixfile do
defp deps do defp deps do
[ [
{:cowboy, "~> 2.12"}, {:cowboy, "~> 2.8.0"},
{:exjsx, "~> 3.0 or ~> 4.0"}, {:exjsx, "~> 3.0 or ~> 4.0"},
{:con_cache, "~> 1.1"}, {:con_cache, "~> 0.14.0"},
{:earmark, "~> 1.0", only: :dev}, {:earmark, "~> 1.0", only: :dev},
{:ex_doc, "~> 0.18", only: :dev}, {:ex_doc, "~> 0.18", only: :dev},
{:meck, "~> 0.9", only: :test} {:meck, "~> 0.8.13", only: :test}
] ]
end end
defp package do defp package do
[ [
description: "https://github.com/edgurgel/httparrot",
maintainers: ["Eduardo Gurgel Pinho"], maintainers: ["Eduardo Gurgel Pinho"],
licenses: ["MIT"], licenses: ["MIT"],
links: %{ links: %{
"Github" => @source_url, "Github" => "https://github.com/edgurgel/httparrot",
"HTTParrot" => "https://httparrot.onrender.com/", "HTTParrot" => "http://httparrot.herokuapp.com",
"httpbin" => "http://httpbin.org" "httpbin" => "http://httpbin.org"
} }
] ]
end end
defp docs do
[
extras: [
"LICENSE.md": [title: "License"],
"README.md": [title: "Overview"]
],
main: "readme",
source_url: @source_url,
source_ref: "v#{@version}",
formatters: ["html"]
]
end
end end

View file

@ -1,17 +1,15 @@
%{ %{
"con_cache": {:hex, :con_cache, "1.1.0", "45c7c6cd6dc216e47636232e8c683734b7fe293221fccd9454fa1757bc685044", [:mix], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "8655f2ae13a1e56c8aef304d250814c7ed929c12810f126fc423ecc8e871593b"}, "con_cache": {:hex, :con_cache, "0.14.0", "863acb90fa08017be3129074993af944cf7a4b6c3ee7c06c5cd0ed6b94fbc223", [:mix], [], "hexpm", "50887a8949377d0b707a3c6653b7610de06074751b52d0f267f52135f391aece"},
"cowboy": {:hex, :cowboy, "2.12.0", "f276d521a1ff88b2b9b4c54d0e753da6c66dd7be6c9fca3d9418b561828a3731", [:make, :rebar3], [{:cowlib, "2.13.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "8a7abe6d183372ceb21caa2709bec928ab2b72e18a3911aa1771639bef82651e"}, "cowboy": {:hex, :cowboy, "2.8.0", "f3dc62e35797ecd9ac1b50db74611193c29815401e53bac9a5c0577bd7bc667d", [:rebar3], [{:cowlib, "~> 2.9.1", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "4643e4fba74ac96d4d152c75803de6fad0b3fa5df354c71afdd6cbeeb15fac8a"},
"cowlib": {:hex, :cowlib, "2.13.0", "db8f7505d8332d98ef50a3ef34b34c1afddec7506e4ee4dd4a3a266285d282ca", [:make, :rebar3], [], "hexpm", "e1e1284dc3fc030a64b1ad0d8382ae7e99da46c3246b815318a4b848873800a4"}, "cowlib": {:hex, :cowlib, "2.9.1", "61a6c7c50cf07fdd24b2f45b89500bb93b6686579b069a89f88cb211e1125c78", [:rebar3], [], "hexpm", "e4175dc240a70d996156160891e1c62238ede1729e45740bdd38064dad476170"},
"earmark": {:hex, :earmark, "1.4.46", "8c7287bd3137e99d26ae4643e5b7ef2129a260e3dcf41f251750cb4563c8fb81", [:mix], [], "hexpm", "798d86db3d79964e759ddc0c077d5eb254968ed426399fbf5a62de2b5ff8910a"}, "earmark": {:hex, :earmark, "1.4.6", "f14260802d8998f30e1654189a0d1699c4aa7d099eb4dad904eb5f41283a70b2", [:mix], [], "hexpm", "c1653a90f63400d029b783a098f4d70a40418ddff14da4cc156a0fee9e72e8d6"},
"earmark_parser": {:hex, :earmark_parser, "1.4.39", "424642f8335b05bb9eb611aa1564c148a8ee35c9c8a8bba6e129d51a3e3c6769", [:mix], [], "hexpm", "06553a88d1f1846da9ef066b87b57c6f605552cfbe40d20bd8d59cc6bde41944"}, "ex_doc": {:hex, :ex_doc, "0.22.1", "9bb6d51508778193a4ea90fa16eac47f8b67934f33f8271d5e1edec2dc0eee4c", [:mix], [{:earmark, "~> 1.4.0", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "d957de1b75cb9f78d3ee17820733dc4460114d8b1e11f7ee4fd6546e69b1db60"},
"ex_doc": {:hex, :ex_doc, "0.34.1", "9751a0419bc15bc7580c73fde506b17b07f6402a1e5243be9e0f05a68c723368", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "d441f1a86a235f59088978eff870de2e815e290e44a8bd976fe5d64470a4c9d2"}, "exactor": {:hex, :exactor, "2.2.3", "a6972f43bb6160afeb73e1d8ab45ba604cd0ac8b5244c557093f6e92ce582786", [:mix], [], "hexpm"},
"exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm", "32e95820a97cffea67830e91514a2ad53b888850442d6d395f53a1ac60c82e07"}, "exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm", "32e95820a97cffea67830e91514a2ad53b888850442d6d395f53a1ac60c82e07"},
"jsx": {:hex, :jsx, "2.8.3", "a05252d381885240744d955fbe3cf810504eb2567164824e19303ea59eef62cf", [:mix, :rebar3], [], "hexpm", "fc3499fed7a726995aa659143a248534adc754ebd16ccd437cd93b649a95091f"}, "jsx": {:hex, :jsx, "2.8.3", "a05252d381885240744d955fbe3cf810504eb2567164824e19303ea59eef62cf", [:mix, :rebar3], [], "hexpm", "fc3499fed7a726995aa659143a248534adc754ebd16ccd437cd93b649a95091f"},
"makeup": {:hex, :makeup, "1.1.2", "9ba8837913bdf757787e71c1581c21f9d2455f4dd04cfca785c70bbfff1a76a3", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cce1566b81fbcbd21eca8ffe808f33b221f9eee2cbc7a1706fc3da9ff18e6cac"}, "makeup": {:hex, :makeup, "1.0.3", "e339e2f766d12e7260e6672dd4047405963c5ec99661abdc432e6ec67d29ef95", [:mix], [{:nimble_parsec, "~> 0.5", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "2e9b4996d11832947731f7608fed7ad2f9443011b3b479ae288011265cdd3dad"},
"makeup_elixir": {:hex, :makeup_elixir, "0.16.2", "627e84b8e8bf22e60a2579dad15067c755531fea049ae26ef1020cad58fe9578", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "41193978704763f6bbe6cc2758b84909e62984c7752b3784bd3c218bb341706b"}, "makeup_elixir": {:hex, :makeup_elixir, "0.14.1", "4f0e96847c63c17841d42c08107405a005a2680eb9c7ccadfd757bd31dabccfb", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "f2438b1a80eaec9ede832b5c41cd4f373b38fd7aa33e3b22d9db79e640cbde11"},
"makeup_erlang": {:hex, :makeup_erlang, "1.0.0", "6f0eff9c9c489f26b69b61440bf1b238d95badae49adac77973cbacae87e3c2e", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "ea7a9307de9d1548d2a72d299058d1fd2339e3d398560a0e46c27dab4891e4d2"}, "meck": {:hex, :meck, "0.8.13", "ffedb39f99b0b99703b8601c6f17c7f76313ee12de6b646e671e3188401f7866", [:rebar3], [], "hexpm", "d34f013c156db51ad57cc556891b9720e6a1c1df5fe2e15af999c84d6cebeb1a"},
"meck": {:hex, :meck, "0.9.2", "85ccbab053f1db86c7ca240e9fc718170ee5bda03810a6292b5306bf31bae5f5", [:rebar3], [], "hexpm", "81344f561357dc40a8344afa53767c32669153355b626ea9fcbc8da6b3045826"}, "nimble_parsec": {:hex, :nimble_parsec, "0.6.0", "32111b3bf39137144abd7ba1cce0914533b2d16ef35e8abc5ec8be6122944263", [:mix], [], "hexpm", "27eac315a94909d4dc68bc07a4a83e06c8379237c5ea528a9acff4ca1c873c52"},
"nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"}, "ranch": {:hex, :ranch, "1.7.1", "6b1fab51b49196860b733a49c07604465a47bdb78aa10c1c16a3d199f7f8c881", [:rebar3], [], "hexpm", "451d8527787df716d99dc36162fca05934915db0b6141bbdac2ea8d3c7afc7d7"},
"ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"},
"telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"},
} }

View file

@ -56,7 +56,7 @@
<div class='mp'> <div class='mp'>
<h1>httparrot(1): HTTP Request &amp; Response Service</h1> <h1>httparrot(1): HTTP Request &amp; Response Service</h1>
<p>Freely hosted in <a href="https://httparrot.onrender.com/">HTTPS</a> <p>Freely hosted in <a href="http://httparrot.herokuapp.com">HTTP</a> &amp; <a href="https://httparrot.herokuapp.com">HTTPS</a>
<h2 id="ENDPOINTS">ENDPOINTS</h2> <h2 id="ENDPOINTS">ENDPOINTS</h2>
@ -104,46 +104,34 @@ scenarios. Additional endpoints are being considered (e.g. <code>/deflate</code>
<h2 id="EXAMPLES">EXAMPLES</h2> <h2 id="EXAMPLES">EXAMPLES</h2>
<h3 id="-curl-http-httparrot-org-ip">$ curl https://httparrot.onrender.com/</h3> <h3 id="-curl-http-httparrot-org-ip">$ curl http://httparrot.herokuapp.com/ip</h3>
<pre><code>{"origin": "24.127.96.129"} <pre><code>{"origin": "24.127.96.129"}
</code></pre> </code></pre>
<h3 id="-curl-http-httparrot-org-user-agent">$ curl https://httparrot.onrender.com/user-agent</h3> <h3 id="-curl-http-httparrot-org-user-agent">$ curl http://httparrot.herokuapp.com/user-agent</h3>
<pre><code>{"user-agent": "curl/7.19.7 (universal-apple-darwin10.0) libcurl/7.19.7 OpenSSL/0.9.8l zlib/1.2.3"} <pre><code>{"user-agent": "curl/7.19.7 (universal-apple-darwin10.0) libcurl/7.19.7 OpenSSL/0.9.8l zlib/1.2.3"}
</code></pre> </code></pre>
<h3 id="-curl-http-httparrot-org-get">$ curl https://httparrot.onrender.com/get</h3> <h3 id="-curl-http-httparrot-org-get">$ curl http://httparrot.herokuapp.com/get</h3>
<pre><code> <pre><code>{
{ "args": {},
"args": {}, "headers": {
"headers": { "Accept": "*/*",
"accept": "*/*", "Connection": "close",
"accept-encoding": "gzip", "Content-Length": "",
"cdn-loop": "cloudflare; subreqs=1", "Content-Type": "",
"cf-connecting-ip": "118.148.71.18", "Host": "httparrot.herokuapp.com",
"cf-ew-via": "15", "User-Agent": "curl/7.19.7 (universal-apple-darwin10.0) libcurl/7.19.7 OpenSSL/0.9.8l zlib/1.2.3"
"cf-ipcountry": "NZ", },
"cf-ray": "899c4ca20494508c-AKL", "origin": "24.127.96.129",
"cf-visitor": "{\"scheme\":\"https\"}", "url": "http://httparrot.herokuapp.com/get"
"cf-worker": "onrender.com", }
"host": "httparrot.onrender.com",
"render-proxy-ttl": "4",
"rndr-id": "1cf65e46-55f1-429d",
"true-client-ip": "118.148.71.18",
"user-agent": "curl/7.81.0",
"x-forwarded-for": "118.148.71.18, 10.213.36.192, 10.214.43.80",
"x-forwarded-proto": "https",
"x-request-start": "1719395492280333"
},
"url": "http://httparrot.onrender.com/get",
"origin": ""
}
</code></pre> </code></pre>
<h3 id="-curl-I-http-httparrot-org-status-418">$ curl -I https://httparrot.onrender.com/status/201</h3> <h3 id="-curl-I-http-httparrot-org-status-418">$ curl -I http://httparrot.herokuapp.com/status/201</h3>
<pre><code>HTTP/1.1 201 <pre><code>HTTP/1.1 201
Server: Cowboy Server: Cowboy

View file

@ -1,27 +1,16 @@
-----BEGIN CERTIFICATE----- -----BEGIN CERTIFICATE-----
MIIEqjCCAxKgAwIBAgIRANXKM01Lqak+6N93VnHgkl4wDQYJKoZIhvcNAQELBQAw MIICeDCCAeGgAwIBAgIJAOvpU0y2e5J4MA0GCSqGSIb3DQEBBQUAMFUxCzAJBgNV
bTEeMBwGA1UEChMVbWtjZXJ0IGRldmVsb3BtZW50IENBMSEwHwYDVQQLDBhlZHVh BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczETMBEGA1UECgwKTmluZSBOaW5lczEPMA0G
cmRvQHBvcC1vcyAoRWR1YXJkbykxKDAmBgNVBAMMH21rY2VydCBlZHVhcmRvQHBv A1UECwwGQ293Ym95MRAwDgYDVQQDDAdST09UIENBMB4XDTEzMDIyODA1MTAwMVoX
cC1vcyAoRWR1YXJkbykwHhcNMjQwNjIzMDU1MzA0WhcNMzQwNjIzMDU1MzA0WjBt DTMzMDIyMzA1MTAwMVowVTELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVRleGFzMRMw
MR4wHAYDVQQKExVta2NlcnQgZGV2ZWxvcG1lbnQgQ0ExITAfBgNVBAsMGGVkdWFy EQYDVQQKDApOaW5lIE5pbmVzMQ8wDQYDVQQLDAZDb3dib3kxEDAOBgNVBAMMB1JP
ZG9AcG9wLW9zIChFZHVhcmRvKTEoMCYGA1UEAwwfbWtjZXJ0IGVkdWFyZG9AcG9w T1QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMzmY7Us06yjyUbpqwPx
LW9zIChFZHVhcmRvKTCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAK6p Iv+xh/g3V7we07ClC9GEYnvr3OQvdA1jFEHccMBUUjRoQ8DPd6uSyK5UkixABs08
DThGWoUHwCVf8DqHDFthUTvNIKRJzyxArh4GF71dHehiLVBZQ9i/jA1nRASzsVcu Tt5B3VsnGKr0DIN+IO4SN2PkmBqIU/BN3KdcwN65YNr3iM0KsKWeFtAZdYx4CakX
UGyZT18N+XvCCeoPevHXOPjUJZtMkhPqlt55N9gzrniEsmRRQOPzIt8+BiFjJ5Jn 7REbO0wjK20AH3xSBn3uFGiBAgMBAAGjUDBOMB0GA1UdDgQWBBRKfZ8KF2jlLBDm
RzRD9S+9AwNIaZKUjiQ1Oexxgvd7pbWy3S/IzXCyFsKIZqYcvvpBY6FroDSEZbrk NL6IuEuGY0pdbzAfBgNVHSMEGDAWgBRKfZ8KF2jlLBDmNL6IuEuGY0pdbzAMBgNV
xMA4Fhvy2370nTrlKzuoVTGZ8WdHOsh7Ef+mCZp1QwTtCkIPHdCa3OMs5F7u4q8P HRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAG1I0kBxXiLkM1b7rl2zPLizREYg
tB4QgaWnvEmRtDwsst/CCQr4nIrQzjDwCMS41x0DZwMrQ8lzSjnAHxayWoll9aJK 1m+ajb6rWzPOBg6TXjv58Be+H4tqoHIL/M/crixew5emftBkuAGjiKMhbIokjvan
38jaDviT9qvnIjjdMHN9jJ7fDBZeonrGqdGSs/754oxpSFAiErpBY6dPGYgzkjQM aPTCV8U6HHvNvz9c68HpESWbd+56cHqfsS5XCKp1OpW5tbL2UQYpFKMP4qmbv3Ea
IxKi4zqYW9ZWPSYacAmRwZsYWp50tvtwxtdY63GslFrnVjtG7e+H1rJJWsQ2Eq5w pBfPPmSFMBb1i2AI
sQekS/EqOpufBuoildwGMiyW1CEhXezW5lCiA++kyA6DkVA2zQRi0huJ4LPvDQID
AQABo0UwQzAOBgNVHQ8BAf8EBAMCAgQwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNV
HQ4EFgQUSGXO0OyaSJ4ztTJkQt8atnaqe7MwDQYJKoZIhvcNAQELBQADggGBAA6c
pCJO1U2S79McbKZylJ13Nv+qMSWvTF5ax+/tSahAgvauaQiDInLa9wOUHfiTqNwH
q42UUexfm04Yre+R9NR9jOVHCFwT9uq3MOPKDuRS3UUUCCUjy0b0CSDc1uCi9BGu
jykYViGNCDvTeOI8AZfIEtD77TGJt/8kn7Z6Qe9EFe1N+k8PtbFJgt1/rjIOtFz0
638iHBSky+U4ozznxQmwwseR3KSSNS0JWQDxm/gWqy4MP1m0pW5Pd543ms2BPUzO
2P1PkEV4jz8J4j2C3EctdoiCudqa8BCFMXIE+t/hKQ+LgbW6phoIN6DLp65Yhs7Z
DHPq64f8005EXB8GDHLoP/HL/wnO60e+hjjvsumvCWc7EZeZiHl2QwFMQ6csExeZ
9bky+h1WiQeV2poEyJSPOVAXThaxf3GOV+V/zrnY+DHNio/IRa4Z+/1Fwxs26+o7
Qnkf9UqSZrKr/B7ilQ/Cb1sv3dLzIPAmfNuDjqPWb4eYT+B26n264znHlhvmWw==
-----END CERTIFICATE----- -----END CERTIFICATE-----

View file

@ -1,26 +1,17 @@
-----BEGIN CERTIFICATE----- -----BEGIN CERTIFICATE-----
MIIEZTCCAs2gAwIBAgIQIJarIG+LC7mjP0IRrFcI0zANBgkqhkiG9w0BAQsFADBt MIICpTCCAg6gAwIBAgIJAOvpU0y2e5J5MA0GCSqGSIb3DQEBBQUAMFUxCzAJBgNV
MR4wHAYDVQQKExVta2NlcnQgZGV2ZWxvcG1lbnQgQ0ExITAfBgNVBAsMGGVkdWFy BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczETMBEGA1UECgwKTmluZSBOaW5lczEPMA0G
ZG9AcG9wLW9zIChFZHVhcmRvKTEoMCYGA1UEAwwfbWtjZXJ0IGVkdWFyZG9AcG9w A1UECwwGQ293Ym95MRAwDgYDVQQDDAdST09UIENBMB4XDTEzMDIyODA1MjMzNFoX
LW9zIChFZHVhcmRvKTAeFw0yNDA2MjMwNTU0MTBaFw0yNjA5MjMwNTU0MTBaMEwx DTMzMDIyMzA1MjMzNFowVzELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVRleGFzMRMw
JzAlBgNVBAoTHm1rY2VydCBkZXZlbG9wbWVudCBjZXJ0aWZpY2F0ZTEhMB8GA1UE EQYDVQQKDApOaW5lIE5pbmVzMQ8wDQYDVQQLDAZDb3dib3kxEjAQBgNVBAMMCWxv
CwwYZWR1YXJkb0Bwb3Atb3MgKEVkdWFyZG8pMIIBIjANBgkqhkiG9w0BAQEFAAOC Y2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAzbW1GjECzHUc/WST
AQ8AMIIBCgKCAQEAx8lf20sm9KkWh/u6ehJ4YpDlx7DGaebBok3JR6rdV42c9flu qLiAGqjCNccR5saVS+yoz2SPRhpoyf0/qBrX5BY0tzmgozoTiRfE4wCiVD99Cc+D
pXdi0Uu7tq4utk4rGu6gotIlPFDeRxokqNIaCUmpIW2msG6KzPBp2Lf+AR0EbdQS rp/FM49r4EpZdocIovprmOmv/gwkoj95zaA6PKNn1OdmDp2hwJsX2Zm3kpbGUZTx
EvqiMLx5dU3yEafGKeH1z4qMobhEWIWU9F0V8zuuJvCeHRCdBkse1XQ64X6gyN1m jDkkccmgUb4EjL7qNHq7saQtivUCAwEAAaN7MHkwCQYDVR0TBAIwADAsBglghkgB
5lYEEIlGfOj7rrAFdCkv63W5dUeph9yoIF//T9yhTx0yNGUeCOuqQEL5HsSdD6HL hvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYE
hqIsjmlI33uHWJd9fr72ZTjmxawRca3tS4ljR6QeZw8zE51lh5P4f1pTGa2vUPxX FB6jTEIWI8T1ckORA4GezbyYxtbvMB8GA1UdIwQYMBaAFEp9nwoXaOUsEOY0voi4
A11O8jmuXkflgLyDNlm1Pob0tuoNOpa2Zi+mAQIDAQABo4GhMIGeMA4GA1UdDwEB S4ZjSl1vMA0GCSqGSIb3DQEBBQUAA4GBACMboVQjrx8u/fk3gl/sR0tbA0Wf/NcS
/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAfBgNVHSMEGDAWgBRIZc7Q7JpI 2Dzsy2czndgVUAG4Sqb+hfgn0dqAyUKghRrj3JDcYxYksGPIklDfPzZb7yJ39l16
njO1MmRC3xq2dqp7szBWBgNVHREETzBNggtleGFtcGxlLmNvbYINKi5leGFtcGxl 6x5ZiIzhp8CAVdPvRxRznw5rZwaXesryXu1jVSZxTr3MYZdkG6KaAM0t90+YlGLZ
LmNvbYIMZXhhbXBsZS50ZXN0gglsb2NhbGhvc3SHBH8AAAGHEAAAAAAAAAAAAAAA UG8fAicx0Bf+
AAAAAAEwDQYJKoZIhvcNAQELBQADggGBAKuzr0Vb6NZV5XlByLgMb1sddIhl3DWq
RGcAf556am51zvZQFz9W/SBm0Ww7+W1fLx7lasyawsxNhfgNHgP05WKZqghodqIw
1tQJAu8PRuXClrvADUnvMz4a3ELCkygSZNn1Oo84YXssEBe1vy70ZTGZS8hhq5qJ
uKTwN0/UtJXXF0dapd4T+N0kuWuoB1xsf7U9Hdn0Bmw5idWe+U2xvb4/Eo0rPUKa
+GJafosfJ17zV5D4oUbuf1uPg8MqQJzEcQDEOcVDgds7tyy3A3igQ+v1WYDkUcUZ
IfOoQxMfHF7mGDbAETGnn0pSRztgKdobpg7MItbdiI04XSIwgGZL4puLJZfSkRDC
ZLqZk9JJc8DpLRjGmH7lRcKkq8TkbrKGsYOQ3bWV6rLP1xH++rE7Sld7P8bLhapQ
hIwcy1rg38v6u2OmApfEbp+VBa62h7RqBDsW0JSNo8Ut1d0VS2HxHMNZ+pr0WVqO
nGcNj0IS+dchbyqN7WF4X9h1iqD09qWeaw==
-----END CERTIFICATE----- -----END CERTIFICATE-----

View file

@ -1,28 +1,15 @@
-----BEGIN PRIVATE KEY----- -----BEGIN RSA PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDHyV/bSyb0qRaH MIICXQIBAAKBgQDNtbUaMQLMdRz9ZJOouIAaqMI1xxHmxpVL7KjPZI9GGmjJ/T+o
+7p6EnhikOXHsMZp5sGiTclHqt1XjZz1+W6ld2LRS7u2ri62Tisa7qCi0iU8UN5H GtfkFjS3OaCjOhOJF8TjAKJUP30Jz4Oun8Uzj2vgSll2hwii+muY6a/+DCSiP3nN
GiSo0hoJSakhbaawborM8GnYt/4BHQRt1BIS+qIwvHl1TfIRp8Yp4fXPioyhuERY oDo8o2fU52YOnaHAmxfZmbeSlsZRlPGMOSRxyaBRvgSMvuo0eruxpC2K9QIDAQAB
hZT0XRXzO64m8J4dEJ0GSx7VdDrhfqDI3WbmVgQQiUZ86PuusAV0KS/rdbl1R6mH AoGAaD85c/h6bpq7Aj7CBbLaWKhFI3OqwsTITB22vsM7SE+B4zsP02UnG1OVi3UM
3KggX/9P3KFPHTI0ZR4I66pAQvkexJ0PocuGoiyOaUjfe4dYl31+vvZlOObFrBFx zytTUxpUkKV1njQ+bYZYOVqGWF4Up8tTqUglHn0FTPok1AIemELWtz3sXvdSHC1T
re1LiWNHpB5nDzMTnWWHk/h/WlMZra9Q/FcDXU7yOa5eR+WAvIM2WbU+hvS26g06 lqvFBAZ9kibn13qGyVOiyCFaMwfOM/05RvV7p3jfUMTWnNECQQDs7yCJZ8Ol8MyH
lrZmL6YBAgMBAAECggEAY2zlJnZdGa84hk4RfITKoornv5xK8hMj1EkP3Xm8E8Fn TGZzvkjoN2zg1KwmTbSD1hkP6QAJtPdRuqFbjlEru0/PefgOXsWLRIa3/3v0qw2G
FsaeePxUEkK1VXGTz6hRLWMKUF1yqHS6Wfo5ukZtLKga4ob2SKGKs/kFRBQ09Yri xGkV6AXTAkEA3kNbFisqUydjPnZIYv/P6SvPdUimHJEjXbAbfNfzS9dzszrOVJd2
VGIQ6J8Qrl5tt6Il0QGEzf0k3rddy3GvmbpI6d+Vd+oAfmKK3X4SFzq1SpdAYk1H XqGH7z5yzjoH3IyaIMW8GnubVzGDSjrHFwJAKSU5vELlygpwKkrNO+pelN0TLlQg
RcC+VLfu60v7yFMtk0IMKMvtXBNY4TPmvJFKv439mLDyIRA5Dsk8P6TZrf473PVJ dSJnZ8GlZorq88SWcn37iX/EftivenNO7YftvEqxLoDSkOGnnrC7Iw/A+wJBAIEe
JpofVVIKtug8z++CFojhiQYX2bcyIxHWdbUer/snJq4UV+0pOjVYqtB+cVjToBSV L/QY72WPJCBNJpAce/PA96vyoE1II3txqwZDjZspdpVQPDz4IFOpEwbxCFC1dYuy
BGNcR+qe8Sg0HXVjpSpKUl3d3GOmCTjKeFzHbu4yTQKBgQD498zP1pW4jH1RVxo8 Qnd3Z2cbF4r3wIWGz9ECQQCJGNhUNtY+Om1ELdqPcquxE2VRV/pucnvJSTKwyo2C
RVsZWKmZip7iD9MhrUakMW9G9pUrWzl6DG7Na8pnYi5TsZXXak/f5sWhhCPxkae0 Rvm6H7kFDwPDuN23YnTOlTiho0zzCkclcIukhIVJ+dKz
0x4Pp7qnSqPvGuTMZQsuG8bvFBWg5XwwrLbx8AzKQ6WggnRumamV5KEwQ8pHMa20 -----END RSA PRIVATE KEY-----
b2fZWPEn3KNR5LASzp9QW3cS2wKBgQDNbfYZOmrEAZw9c53VJG9S1JiqClYHg99T
oTlklsfdNfot78odTto29LO9Tr997ZX0w93jDrxSdLyyiIdZEDVSSkbS3HSdSjfm
nqwlogNXf5TnH88j+EkVvQWs63Q7lyrFNcEftT44ebYXH5ehzPkVbKlocztY0AWw
iVgD8AlrUwKBgQCHE8L+fJks0KRpTk3Ap4x+mvkhgfEkC5vsaJusF9oc8UoLhOoR
Ss+PCk19e+pQpEf84QRHIWjWceAif3kzBVwI+GKvwzJgVwIN10CSmqV7LzVw3zFb
I0n6x9fYoY0qIb1UCHDXD31Yt17284AgJlV8ueHVU8MUenQBMDOFoKphAwKBgGGc
/5SLSpIqhbg5iOTvtCoytPwPf0OA6QyPDnt6nivB60gKqgp1HoGAkyvAEIPg8iFl
NLkglmHD8KoQ7+dlKUEZ5D9r28mlq5xdB0W2j0nzaKjOV5oq72dx8xFwrEFomj0t
RsAvWgpx4xFnxKBwimcgw/rKzodsCVgSWw078O3bAoGBAOyz3sgE9c6mv5jwg2bt
59rqGfHZizMRH0gxiC8P1Ui9dlZfnvdeBLUR/FD6XBSb450vRdcgG4AQ+HPECKkb
kECHkBb542ymb/GqgutNLPzQ8n0Q1zO92CSX5KKmY2B+lEfer5NSc2c9gY261YMH
AApeuDGbws/XXVLWnR1fGbH0
-----END PRIVATE KEY-----

View file

@ -1,8 +1,6 @@
@echo off @echo off
rem Set the release to load code on demand (interactive) instead of preloading (embedded). rem Set the release to work across nodes. If using the long name format like
rem set RELEASE_MODE=interactive rem the one below (my_app@127.0.0.1), you need to also uncomment the
rem RELEASE_DISTRIBUTION variable below.
rem Set the release to work across nodes.
rem RELEASE_DISTRIBUTION must be "sname" (local), "name" (distributed) or "none".
rem set RELEASE_DISTRIBUTION=name rem set RELEASE_DISTRIBUTION=name
rem set RELEASE_NODE=<%= @release.name %> rem set RELEASE_NODE=<%= @release.name %>@127.0.0.1

View file

@ -1,20 +1,14 @@
#!/bin/sh #!/bin/sh
# # Sets and enables heart (recommended only in daemon mode) # Sets and enables heart (recommended only in daemon mode)
# case $RELEASE_COMMAND in # if [ "$RELEASE_COMMAND" = "daemon" ] || [ "$RELEASE_COMMAND" = "daemon_iex" ]; then
# daemon*) # HEART_COMMAND="$RELEASE_ROOT/bin/$RELEASE_NAME $RELEASE_COMMAND"
# HEART_COMMAND="$RELEASE_ROOT/bin/$RELEASE_NAME $RELEASE_COMMAND" # export HEART_COMMAND
# export HEART_COMMAND # export ELIXIR_ERL_OPTIONS="-heart"
# export ELIXIR_ERL_OPTIONS="-heart" # fi
# ;;
# *)
# ;;
# esac
# # Set the release to load code on demand (interactive) instead of preloading (embedded). # Set the release to work across nodes. If using the long name format like
# export RELEASE_MODE=interactive # the one below (my_app@127.0.0.1), you need to also uncomment the
# RELEASE_DISTRIBUTION variable below.
# # Set the release to work across nodes.
# # RELEASE_DISTRIBUTION must be "sname" (local), "name" (distributed) or "none".
# export RELEASE_DISTRIBUTION=name # export RELEASE_DISTRIBUTION=name
# export RELEASE_NODE=<%= @release.name %> # export RELEASE_NODE=<%= @release.name %>@127.0.0.1

View file

@ -1,12 +0,0 @@
## Customize flags given to the VM: https://www.erlang.org/doc/man/erl.html
## -mode/-name/-sname/-setcookie are configured via env vars, do not set them here
## Increase number of concurrent ports/sockets
##+Q 65536
## Tweak GC to run more often
##-env ERL_FULLSWEEP_AFTER 10
## Enable deployment without epmd
## (requires changing both vm.args and remote.vm.args)
##-start_epmd false -erl_epmd_port 6789 -dist_listen false

View file

@ -1,12 +1,11 @@
## Customize flags given to the VM: https://www.erlang.org/doc/man/erl.html ## Customize flags given to the VM: http://erlang.org/doc/man/erl.html
## -mode/-name/-sname/-setcookie are configured via env vars, do not set them here ## -mode/-name/-sname/-setcookie are configured via env vars, do not set them here
## Number of dirty schedulers doing IO work (file, sockets, etc)
##+SDio 5
## Increase number of concurrent ports/sockets ## Increase number of concurrent ports/sockets
##+Q 65536 ##+Q 65536
## Tweak GC to run more often ## Tweak GC to run more often
##-env ERL_FULLSWEEP_AFTER 10 ##-env ERL_FULLSWEEP_AFTER 10
## Enable deployment without epmd
## (requires changing both vm.args and remote.vm.args)
##-start_epmd false -erl_epmd_port 6789false

View file

@ -4,8 +4,8 @@ defmodule HTTParrot.Base64HandlerTest do
import HTTParrot.Base64Handler import HTTParrot.Base64Handler
setup do setup do
new(:cowboy_req) new :cowboy_req
on_exit(fn -> unload() end) on_exit fn -> unload() end
:ok :ok
end end

View file

@ -4,33 +4,32 @@ defmodule HTTParrot.BasicAuthHandlerTest do
import HTTParrot.BasicAuthHandler import HTTParrot.BasicAuthHandler
setup do setup do
new(:cowboy_req) new :cowboy_req
new(JSX) new JSX
on_exit(fn -> unload() end) on_exit fn -> unload() end
:ok :ok
end end
test "is_authorized returns true if user and passwd match" do test "is_authorized returns true if user and passwd match" do
expect(:cowboy_req, :binding, [{[:user, :req1], :user}, {[:passwd, :req1], :passwd}]) expect(:cowboy_req, :binding, [{[:user, :req1], :user},
{[:passwd, :req1], :passwd}])
expect(:cowboy_req, :parse_header, [{["authorization", :req1], {:basic, :user, :passwd}}]) expect(:cowboy_req, :parse_header, [{["authorization", :req1], {:basic, :user, :passwd}}])
assert is_authorized(:req1, :state) == {true, :req1, :user} assert is_authorized(:req1, :state) == {true, :req1, :user}
assert validate(:cowboy_req) assert validate :cowboy_req
assert validate(JSX) assert validate JSX
end end
test "is_authorized returns false if user and passwd doesnt match" do test "is_authorized returns false if user and passwd doesnt match" do
expect(:cowboy_req, :binding, [{[:user, :req1], :user}, {[:passwd, :req1], :passwd}]) expect(:cowboy_req, :binding, [{[:user, :req1], :user},
{[:passwd, :req1], :passwd}])
expect(:cowboy_req, :parse_header, [ expect(:cowboy_req, :parse_header, [{["authorization", :req1], {:basic, :not_the_user, :passwd}}])
{["authorization", :req1], {:basic, :not_the_user, :passwd}}
])
assert is_authorized(:req1, :state) == {{false, "Basic realm=\"Fake Realm\""}, :req1, :state} assert is_authorized(:req1, :state) == {{false, "Basic realm=\"Fake Realm\""}, :req1, :state}
assert validate(:cowboy_req) assert validate :cowboy_req
assert validate(JSX) assert validate JSX
end end
test "returns user and if it's authenticated" do test "returns user and if it's authenticated" do
@ -38,6 +37,6 @@ defmodule HTTParrot.BasicAuthHandlerTest do
assert get_json(:req1, :user) == {:json, :req1, nil} assert get_json(:req1, :user) == {:json, :req1, nil}
assert validate(JSX) assert validate JSX
end end
end end

View file

@ -4,9 +4,9 @@ defmodule HTTParrot.CacheHandlerTest do
import HTTParrot.CacheHandler import HTTParrot.CacheHandler
setup do setup do
new(HTTParrot.GeneralRequestInfo) new HTTParrot.GeneralRequestInfo
new(JSX) new JSX
on_exit(fn -> unload() end) on_exit fn -> unload() end
:ok :ok
end end
@ -16,7 +16,7 @@ defmodule HTTParrot.CacheHandlerTest do
assert get_json(:req1, :state) == {:json, :req2, :state} assert get_json(:req1, :state) == {:json, :req2, :state}
assert validate(HTTParrot.GeneralRequestInfo) assert validate HTTParrot.GeneralRequestInfo
assert validate(JSX) assert validate JSX
end end
end end

View file

@ -4,9 +4,9 @@ defmodule HTTParrot.DeflateHandlerTest do
import HTTParrot.DeflateHandler import HTTParrot.DeflateHandler
setup do setup do
new(HTTParrot.GeneralRequestInfo) new HTTParrot.GeneralRequestInfo
new(JSX) new JSX
on_exit(fn -> unload() end) on_exit fn -> unload() end
:ok :ok
end end
@ -16,15 +16,15 @@ defmodule HTTParrot.DeflateHandlerTest do
expect(JSX, :prettify!, [{[:json], "json"}]) expect(JSX, :prettify!, [{[:json], "json"}])
expect(:cowboy_req, :set_resp_header, 3, :req3) expect(:cowboy_req, :set_resp_header, 3, :req3)
opened_zlib = :zlib.open() opened_zlib = :zlib.open
:zlib.deflateInit(opened_zlib) :zlib.deflateInit(opened_zlib)
body = :zlib.deflate(opened_zlib, "json", :finish) body = :zlib.deflate(opened_zlib, "json", :finish)
:zlib.deflateEnd(opened_zlib) :zlib.deflateEnd(opened_zlib)
assert get_json(:req1, :state) == {body, :req3, :state} assert get_json(:req1, :state) == {body, :req3, :state}
assert validate(HTTParrot.GeneralRequestInfo) assert validate HTTParrot.GeneralRequestInfo
assert validate(JSX) assert validate JSX
assert validate(:cowboy_req) assert validate :cowboy_req
end end
end end

View file

@ -4,10 +4,10 @@ defmodule HTTParrot.DeleteHandlerTest do
import HTTParrot.DeleteHandler import HTTParrot.DeleteHandler
setup do setup do
new(:cowboy_req) new :cowboy_req
new(HTTParrot.GeneralRequestInfo) new HTTParrot.GeneralRequestInfo
new(JSX) new JSX
on_exit(fn -> unload() end) on_exit fn -> unload() end
:ok :ok
end end
@ -18,8 +18,8 @@ defmodule HTTParrot.DeleteHandlerTest do
assert delete_resource(:req1, :state) == {true, :req3, :state} assert delete_resource(:req1, :state) == {true, :req3, :state}
assert validate(:cowboy_req) assert validate :cowboy_req
assert validate(HTTParrot.GeneralRequestInfo) assert validate HTTParrot.GeneralRequestInfo
assert validate(JSX) assert validate JSX
end end
end end

View file

@ -4,9 +4,9 @@ defmodule HTTParrot.GetHandlerTest do
import HTTParrot.GetHandler import HTTParrot.GetHandler
setup do setup do
new(HTTParrot.GeneralRequestInfo) new HTTParrot.GeneralRequestInfo
new(JSX) new JSX
on_exit(fn -> unload() end) on_exit fn -> unload() end
:ok :ok
end end
@ -16,7 +16,7 @@ defmodule HTTParrot.GetHandlerTest do
assert get_json(:req1, :state) == {:json, :req2, :state} assert get_json(:req1, :state) == {:json, :req2, :state}
assert validate(HTTParrot.GeneralRequestInfo) assert validate HTTParrot.GeneralRequestInfo
assert validate(JSX) assert validate JSX
end end
end end

View file

@ -4,9 +4,9 @@ defmodule HTTParrot.GzipHandlerTest do
import HTTParrot.GzipHandler import HTTParrot.GzipHandler
setup do setup do
new(HTTParrot.GeneralRequestInfo) new HTTParrot.GeneralRequestInfo
new(JSX) new JSX
on_exit(fn -> unload() end) on_exit fn -> unload() end
:ok :ok
end end
@ -20,8 +20,8 @@ defmodule HTTParrot.GzipHandlerTest do
assert get_json(:req1, :state) == {body, :req3, :state} assert get_json(:req1, :state) == {body, :req3, :state}
assert validate(HTTParrot.GeneralRequestInfo) assert validate HTTParrot.GeneralRequestInfo
assert validate(JSX) assert validate JSX
assert validate(:cowboy_req) assert validate :cowboy_req
end end
end end

View file

@ -26,7 +26,7 @@ defmodule HTTParrot.HiddenBasicAuthHandlerTest do
assert validate(JSX) assert validate(JSX)
end end
test "resource_exists returns false if user and passwd doesn't match" do test "resource_exists returns false if user and passwd doesnt match" do
expect(:cowboy_req, :binding, [{[:user, :req1], :user}, {[:passwd, :req1], :passwd}]) expect(:cowboy_req, :binding, [{[:user, :req1], :user}, {[:passwd, :req1], :passwd}])
expect(:cowboy_req, :parse_header, [ expect(:cowboy_req, :parse_header, [

View file

@ -11,10 +11,10 @@ defmodule HTTParrotTest do
test "'prettify_json' prettifies body response if it's a JSON" do test "'prettify_json' prettifies body response if it's a JSON" do
expect(:cowboy_req, :reply, [ expect(:cowboy_req, :reply, [
{[:status, %{"content-length" => ~c"14"}, "{\n \"a\": \"b\"\n}", :req1], :req2} {[:status, %{"content-length" => '14'}, "{\n \"a\": \"b\"\n}", :req1], :req2}
]) ])
assert prettify_json(:status, %{"content-length" => ~c"12"}, "{\"a\":\"b\"}", :req1) == :req2 assert prettify_json(:status, %{"content-length" => '12'}, "{\"a\":\"b\"}", :req1) == :req2
assert validate(:cowboy_req) assert validate(:cowboy_req)
end end

View file

@ -1,13 +1,12 @@
defmodule HTTParrot.RequestStoreTest do defmodule HTTParrot.RequestStoreTest do
alias HTTParrot.RequestStore alias HTTParrot.RequestStore
use ExUnit.Case use ExUnit.Case
test "save, retrieve, clear" do test "save, retrieve, clear" do
request = %{req: 1} request = %{req: 1}
RequestStore.clear(:test) RequestStore.clear(:test)
RequestStore.store(:test, request) RequestStore.store(:test, request)
assert RequestStore.retrieve(:test) == [request] assert RequestStore.retrieve(:test) == [request]
RequestStore.clear(:test) RequestStore.clear(:test)
assert RequestStore.retrieve(:test) == [] assert RequestStore.retrieve(:test) == []
end end
end end

View file

@ -5,7 +5,7 @@ defmodule HTTParrot.RetrieveRequestHandlerTests do
setup do setup do
HTTParrot.RequestStore.clear(:test) HTTParrot.RequestStore.clear(:test)
on_exit(fn -> unload() end) on_exit fn -> unload() end
:ok :ok
end end

View file

@ -12,15 +12,15 @@ defmodule HTTParrot.StoreRequestHandlerTests do
test "store a request" do test "store a request" do
expect(:cowboy_req, :binding, [:key, :req1], :test) expect(:cowboy_req, :binding, [:key, :req1], :test)
expect(HTTParrot.GeneralRequestInfo, :retrieve, 1, {:info, :req1}) expect(HTTParrot.GeneralRequestInfo, :retrieve, 1, {:info, :req1})
assert get(:req1, :state) == {~c'{"saved": "true"}', :req1, :state} assert get(:req1, :state) == {'{"saved": "true"}', :req1, :state}
assert HTTParrot.RequestStore.retrieve(:test) == [:info] assert HTTParrot.RequestStore.retrieve(:test) == [:info]
end end
test "store multiple requests" do test "store multiple requests" do
expect(:cowboy_req, :binding, [:key, :req1], :test) expect(:cowboy_req, :binding, [:key, :req1], :test)
expect(HTTParrot.GeneralRequestInfo, :retrieve, 1, {:info, :req1}) expect(HTTParrot.GeneralRequestInfo, :retrieve, 1, {:info, :req1})
assert get(:req1, :state) == {~c'{"saved": "true"}', :req1, :state} assert get(:req1, :state) == {'{"saved": "true"}', :req1, :state}
assert get(:req2, :state) == {~c'{"saved": "true"}', :req1, :state} assert get(:req2, :state) == {'{"saved": "true"}', :req1, :state}
assert HTTParrot.RequestStore.retrieve(:test) == [:info, :info] assert HTTParrot.RequestStore.retrieve(:test) == [:info, :info]
end end
end end

View file

@ -4,9 +4,9 @@ defmodule HTTParrot.UserAgentHandlerTest do
import HTTParrot.UserAgentHandler import HTTParrot.UserAgentHandler
setup do setup do
new(:cowboy_req) new :cowboy_req
new(JSX) new JSX
on_exit(fn -> unload() end) on_exit fn -> unload() end
:ok :ok
end end
@ -16,7 +16,7 @@ defmodule HTTParrot.UserAgentHandlerTest do
assert get_json(:req1, :state) == {:json, :req1, :state} assert get_json(:req1, :state) == {:json, :req1, :state}
assert validate(:cowboy_req) assert validate :cowboy_req
assert validate(JSX) assert validate JSX
end end
end end